diff --git a/deps/v8/.gitignore b/deps/v8/.gitignore index 72196753bc8..db57d1bb323 100644 --- a/deps/v8/.gitignore +++ b/deps/v8/.gitignore @@ -19,17 +19,13 @@ d8 d8_g shell shell_g -/build/gyp /obj/ /test/es5conform/data/ /test/mozilla/data/ /test/sputnik/sputniktests/ -/test/test262/data/ /tools/oom_dump/oom_dump /tools/oom_dump/oom_dump.o /tools/visual_studio/Debug /tools/visual_studio/Release /xcodebuild/ TAGS -Makefile -*.Makefile diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index d4e35fe8002..92b69cb686b 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -7,9 +7,7 @@ Google Inc. Sigma Designs Inc. ARM Ltd. Hewlett-Packard Development Company, LP -Igalia, S.L. -Akinori MUSHA Alexander Botero-Lowry Alexander Karpinsky Alexandre Vassalotti @@ -26,21 +24,17 @@ Jay Freeman Joel Stanley John Jozwiak Kun Zhang -Martyn Capewell Matt Hanselman -Maxim Mossienko +Martyn Capewell Michael Smith Mike Gilbert Paolo Giarrusso Patrick Gansterer -Peter Varga Rafal Krypa Rene Rebe -Robert Mustacchi Rodolph Perfetta Ryan Dahl Sanjoy Das Subrato K De Vlad Burlik -Yuqiang Xian Zaheer Ahmad diff --git a/deps/v8/ChangeLog b/deps/v8/ChangeLog index f936c7a0d56..7936058e264 100644 --- a/deps/v8/ChangeLog +++ b/deps/v8/ChangeLog @@ -1,443 +1,3 @@ -2011-07-04: Version 3.4.9 - - Added support for debugger inspection of locals in optimized frames - (issue 1140). - - Fixed SConstruct to pass correct defines to samples/preparser when - building with library=shared. - - Made date parser handle ES5 Date Time Strings correctly (issue 1498). - - Fixed a bug in Object.defineProperty on the arguments object. - - Performance improvements on all platforms. - - -2011-06-29: Version 3.4.8 - - Ensure 16-byte stack alignment on Solaris (issue 1505). - - Fix "illegal access" when calling parseInt with a radix - that is not a smi. (issue 1246). - - -2011-06-27: Version 3.4.7 - - Fixed 64-bit build on FreeBSD. - - Added API to set the property attributes for the prototype - property on functions created from FunctionTemplates. - - Bugfixes and performance work. - - -2011-06-22: Version 3.4.6 - - Lowered limit on code space for systems with low memory supply. - - Allowed compiling v8_shell with the 'host' toolset (issue 82437). - - Extended setBreakpoint API to accept partial script name (issue 1418). - - Made multi-line comments not count when deciding whether the '-->' - comment starter is first on a line. This matches Safari. - - Made handling of non-array recievers in Array length setter correct - (issue 1491). - - Added ability to heap profiler to iterate over snapshot's node - (issue 1481). - - -2011-06-20: Version 3.4.5 - - Fixed issues 794, 1097, 1215(partial), 1417, 1435, 1472, 1473, - 1476, and 1477. - - Improved code generation for !0 and !1. - - Reduced memory usage for regular expressions with nested qualifiers. - (issue 1472) - - Fixed V8 to count line terminators in multi-line comments. - (Chromium issue 86431) - - Fixed disassembler=on option for release-mode builds. (issue 1473) - - Performance improvements on all platforms. - - -2011-06-15: Version 3.4.4 - - Added snapshot compression support and --stress-opt flag to d8. - - Improved performance of try/catch. - - Several GYP-related changes: Added support for building Xcode project - files. Make the ARM simulator build with GYP again. Generate Makefiles - for all architectures on Linux. - - Fixed Array.prototype.{reduce,reduceRight} to pass undefined as the - receiver for strict mode callbacks. (issue 1436) - - Fixed a bug where an array load was incorrectly hoisted by GVN. - - Handle 'undefined' correctly when === has been specialized for doubles. - (issue 1434) - - Corrected the limit of local variables in an optimized function from 64 - to 63. - - Correctly set ReadOnly flag on indexed properties when using the API Set - method. (issue 1470) - - Give the correct error message when Object.isExtensible is called on a - non-object. (issue 1452) - - Added GetOwnPropertyNames method for Object in the API. Patch by Peter - Varga. - - Do not redefine properties unneccesarily in seal and freeze. (issue - 1447) - - IsExecutionTerminating has an Isolate parameter now. - - Distinguish keyed loads with a symbol key from fast elements loads, - avoiding some useless deoptimizations. (issue 1471) - - -2011-06-08: Version 3.4.3 - - Clear the global thread table when an isolate is disposed - (issue 1433). - - Converted time zone name to UTF8 on Windows (issue 1290). - - Limited the number of arguments in a function call to 32766 - (issue 1413). - - Compress sources of JS libraries in addition to the snapshot. - - Fixed a bug in Lithium environment iteration. - - Performance improvements on all platforms. - - -2011-06-06: Version 3.4.2 - - More work on ES-Harmony proxies. Still hidden behind a flag. - - Fixed some crash bugs and improved performance. - - Fixed building with gdb debugging support. - - Do not install SIGPROF handler until it is needed. - - Added DateTimeFormat to i18n API. - - Fixed compilation on OpenBSD. - - Take the ulimit into account when sizing the heap. OpenBSD users - may still have to increase the default ulimit to run heavy pages in - the browser. - - -2011-06-01: Version 3.4.1 - - Fixed JSON stringify issue with arrays. - - Changed calls to JS builtins to be passed undefined when called with - implicit receiver. - - Implemented the set trap for Harmony proxies. Proxies still need to - be enabled with the --harmony-proxies flag. - - -2011-05-30: Version 3.4.0 - - Changed calls to undefined property setters to not throw (issue 1355). - - Made RegExp objects not callable. - - Fixed issues on special case large JSON strings in new json parser - (issues http://crbug.com/83877 and http://crbug.com/84186). - - Performance improvements on all platforms. - - -2011-05-25: Version 3.3.10 - - Fixed calls of strict mode function with an implicit receiver. - - Fixed fast handling of arrays to properly deal with changes to the - Object prototype (issue 1403). - - Changed strict mode poison pill to be the same type error function - (issue 1387). - - Fixed a debug crash in arguments object handling (issue 1227). - - Fixed a bug in deoptimization on x64 (issue 1404). - - Performance improvements and bug fixes on all platforms. - - -2011-05-23: Version 3.3.9 - - Added DateTimeFormat class to experimental i18n API. - - Extended preparser to give early errors for some strict mode - restrictions. - - Removed legacy execScript function from V8. - - Extended isolate API with the ability to add embedder-specific - data to an isolate. - - Added basic support for polymorphic loads from JS and external - arrays. - - Fixed bug in handling of switch statements in the optimizing - compiler. - - -2011-05-18: Version 3.3.8 - - Added MarkIndependent to the persistent handle API. Independent - handles are independent of all other persistent handles and can be - garbage collected more frequently. - - Implemented the get trap for Harmony proxies. Proxies are enabled - with the --harmony-proxies flag. - - Performance improvements and bug fixes on all platforms. - - -2011-05-16: Version 3.3.7 - - Updated MIPS infrastructure files. - - Performance improvements and bug fixes on all platforms. - - -2011-05-11: Version 3.3.6 - - Updated MIPS infrastructure files. - - Added method IsCallable for Object to the API. - Patch by Peter Varga. - - -2011-05-09: Version 3.3.5 - - Fixed build on FreeBSD. Patch by Akinori MUSHA. - - Added check that receiver is JSObject on API calls. - - Implemented CallAsConstructor method for Object in the API (Issue 1348). - Patch by Peter Varga. - - Added CallAsFunction method to the Object class in the API (Issue 1336). - Patch by Peter Varga. - - Added per-isolate locking and unlocking. - - Fixed bug in x64 >>> operator (Issue 1359). - - -2011-05-04: Version 3.3.4 - - Implemented API to disallow code generation from strings for a context - (issue 1258). - - Fixed bug with whitespaces in parseInt (issue 955). - - Fixed bug with == comparison of Date objects (issue 1356). - - Added GYP variables for ARM code generation: - v8_can_use_vfp_instructions, v8_can_use_unaligned_accesses - and v8_use_arm_eabi_hardfloat. - - -2011-05-02: Version 3.3.3 - - Added support for generating Visual Studio solution and project files - using GYP. - - Implemented support for ARM EABI calling convention variation where - floating-point arguments are passed in registers (hardfloat). - - Added Object::HasOwnProperty() to the API. - - Added support for compressing startup data to reduce binary size. This - includes build time support and an API for the embedder to decompress - the startup data before initializing V8. - - Reduced the profiling hooks overhead from >400% to 25% when using - ll_prof. - - Performance improvements and bug fixes on all platforms. - - -2011-04-27: Version 3.3.2 - - Fixed crash bug on ARM with no VFP3 hardware. - - Fixed compilation of V8 without debugger support. - - Improved performance on JSLint. - - Added support Float64 WebGL arrays. - - Fixed crash bug in regexp replace. - - -2011-04-20: Version 3.3.1 - - Reduced V8 binary size by removing virtual functions from hydrogen. - - Fixed crash bug on x64. - - Performance improvements on ARM and IA32. - - -2011-04-18: Version 3.3.0 - - Fixed bug in floating point rounding in Crankshaft on ARM - (issue 958) - - Fixed a number of issues with running without VFPv3 support on ARM - (issue 1315) - - Introduced v8Locale.Collator, a partial implementation of Collator - per last ECMAScript meeting + mailing list. - - Minor performance improvements and bug fixes. - - -2011-04-13: Version 3.2.10 - - Fixed bug in external float arrays on ARM (issue 1323). - - Minor performance improvements and bug fixes. - - -2011-04-11: Version 3.2.9 - - Removed support for ABI prior to EABI on ARM. - - Fixed multiple crash bugs. - - Added GCMole to the repository, a simple static analysis tool that - searches for GC-unsafe evaluation order dependent callsites. - - Made preparser API be exported in shared libraries. - - Fixed multiple issues in EcmaScript 5 strict mode implementation. - - Fixed mutable __proto__ property if object is not extensible - (Issue 1309). - - Fixed auto suspension of the sampler thread. - - -2011-04-06: Version 3.2.8 - - Exposed WebGL typed array constructors in the shell sample. - - Performance improvements on all platforms. - - -2011-04-04: Version 3.2.7 - - Disabled the original 'classic' V8 code generator. Crankshaft is - now the default on all platforms. - - Changed the heap profiler to use more descriptive names. - - Performance and stability improvements to isolates on all platforms. - - -2011-03-30: Version 3.2.6 - - Fixed xcode build warning in shell.cc (out of order initialization). - - Fixed null-pointer dereference in the compiler when running without - SSE3 support (Chromium issue 77654). - - Fixed x64 compilation error due to some dead code. (Issue 1286) - - Introduced scons target to build the preparser stand-alone example. - - Made FreeBSD build and pass all tests. - - -2011-03-28: Version 3.2.5 - - Fixed build with Irregexp interpreter (issue 1266). - - Added Crankshaft support for external arrays. - - Fixed two potential crash bugs. - - -2011-03-23: Version 3.2.4 - - Added isolates which allows several V8 instances in the same process. - This is controlled through the new Isolate class in the API. - - Implemented more of EcmaScript 5 strict mode. - - Reduced the time it takes to make detailed heap snapshot. - - Added a number of commands to the ARM simulator and enhanced the ARM - disassembler. - - -2011-03-17: Version 3.2.3 - - Fixed a number of crash bugs. - - Fixed Array::New(length) to return an array with a length (issue 1256). - - Fixed FreeBSD build. - - Changed __defineGetter__ to not throw (matching the behavior of Safari). - - Implemented more of EcmaScript 5 strict mode. - - Improved Crankshaft performance on all platforms. - - -2011-03-14: Version 3.2.2 - - Fixed a number of crash and correctness bugs. - - Improved Crankshaft performance on all platforms. - - Fixed Crankshaft on Solaris/Illumos. - - -2011-03-10: Version 3.2.1 - - Fixed a number of crash bugs. - - Improved Crankshaft for x64 and ARM. - - Implemented more of EcmaScript 5 strict mode. - - -2011-03-07: Version 3.2.0 - - Fixed a number of crash bugs. - - Turned on Crankshaft by default on x64 and ARM. - - Improved Crankshaft for x64 and ARM. - - Implemented more of EcmaScript 5 strict mode. - - 2011-03-02: Version 3.1.8 Fixed a number of crash bugs. @@ -3004,6 +2564,3 @@ Initial export. -# Local Variables: -# mode:text -# End: diff --git a/deps/v8/SConstruct b/deps/v8/SConstruct index 7ee9f136ab5..d76f708b834 100644 --- a/deps/v8/SConstruct +++ b/deps/v8/SConstruct @@ -1,4 +1,4 @@ -# Copyright 2011 the V8 project authors. All rights reserved. +# 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: @@ -36,6 +36,13 @@ root_dir = dirname(File('SConstruct').rfile().abspath) sys.path.insert(0, join(root_dir, 'tools')) import js2c, utils +# ANDROID_TOP is the top of the Android checkout, fetched from the environment +# variable 'TOP'. You will also need to set the CXX, CC, AR and RANLIB +# environment variables to the cross-compiling tools. +ANDROID_TOP = os.environ.get('TOP') +if ANDROID_TOP is None: + ANDROID_TOP="" + # ARM_TARGET_LIB is the path to the dynamic library to use on the target # machine if cross-compiling to an arm machine. You will also need to set # the additional cross-compiling environment variables to the cross compiler. @@ -51,6 +58,50 @@ else: GCC_EXTRA_CCFLAGS = [] GCC_DTOA_EXTRA_CCFLAGS = [] +ANDROID_FLAGS = ['-march=armv7-a', + '-mtune=cortex-a8', + '-mfloat-abi=softfp', + '-mfpu=vfp', + '-fpic', + '-mthumb-interwork', + '-funwind-tables', + '-fstack-protector', + '-fno-short-enums', + '-fmessage-length=0', + '-finline-functions', + '-fno-inline-functions-called-once', + '-fgcse-after-reload', + '-frerun-cse-after-loop', + '-frename-registers', + '-fomit-frame-pointer', + '-finline-limit=64', + '-DCAN_USE_VFP_INSTRUCTIONS=1', + '-DCAN_USE_ARMV7_INSTRUCTIONS=1', + '-DCAN_USE_UNALIGNED_ACCESSES=1', + '-MD'] + +ANDROID_INCLUDES = [ANDROID_TOP + '/bionic/libc/arch-arm/include', + ANDROID_TOP + '/bionic/libc/include', + ANDROID_TOP + '/bionic/libstdc++/include', + ANDROID_TOP + '/bionic/libc/kernel/common', + ANDROID_TOP + '/bionic/libc/kernel/arch-arm', + ANDROID_TOP + '/bionic/libm/include', + ANDROID_TOP + '/bionic/libm/include/arch/arm', + ANDROID_TOP + '/bionic/libthread_db/include', + ANDROID_TOP + '/frameworks/base/include', + ANDROID_TOP + '/system/core/include'] + +ANDROID_LINKFLAGS = ['-nostdlib', + '-Bdynamic', + '-Wl,-T,' + ANDROID_TOP + '/build/core/armelf.x', + '-Wl,-dynamic-linker,/system/bin/linker', + '-Wl,--gc-sections', + '-Wl,-z,nocopyreloc', + '-Wl,-rpath-link=' + ANDROID_TOP + '/out/target/product/generic/obj/lib', + ANDROID_TOP + '/out/target/product/generic/obj/lib/crtbegin_dynamic.o', + ANDROID_TOP + '/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/interwork/libgcc.a', + ANDROID_TOP + '/out/target/product/generic/obj/lib/crtend_android.o']; + LIBRARY_FLAGS = { 'all': { 'CPPPATH': [join(root_dir, 'src')], @@ -78,9 +129,6 @@ LIBRARY_FLAGS = { 'inspector:on': { 'CPPDEFINES': ['INSPECTOR'], }, - 'fasttls:on': { - 'CPPDEFINES': ['V8_FAST_TLS'], - }, 'liveobjectlist:on': { 'CPPDEFINES': ['ENABLE_DEBUGGER_SUPPORT', 'INSPECTOR', 'LIVE_OBJECT_LIST', 'OBJECT_PRINT'], @@ -89,7 +137,7 @@ LIBRARY_FLAGS = { 'gcc': { 'all': { 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], - 'CXXFLAGS': ['-fno-rtti', '-fno-exceptions'], + 'CXXFLAGS': ['$CCFLAGS', '-fno-rtti', '-fno-exceptions'], }, 'visibility:hidden': { # Use visibility=default to disable this. @@ -101,10 +149,17 @@ LIBRARY_FLAGS = { 'mode:debug': { 'CCFLAGS': ['-g', '-O0'], 'CPPDEFINES': ['ENABLE_DISASSEMBLER', 'DEBUG'], + 'os:android': { + 'CCFLAGS': ['-mthumb'] + } }, 'mode:release': { 'CCFLAGS': ['-O3', '-fomit-frame-pointer', '-fdata-sections', '-ffunction-sections'], + 'os:android': { + 'CCFLAGS': ['-mthumb', '-Os'], + 'CPPDEFINES': ['SK_RELEASE', 'NDEBUG'] + } }, 'os:linux': { 'CCFLAGS': ['-ansi'] + GCC_EXTRA_CCFLAGS, @@ -123,7 +178,6 @@ LIBRARY_FLAGS = { 'CPPPATH' : ['/usr/local/include'], 'LIBPATH' : ['/usr/local/lib'], 'CCFLAGS': ['-ansi'], - 'LIBS': ['execinfo'] }, 'os:openbsd': { 'CPPPATH' : ['/usr/local/include'], @@ -142,6 +196,14 @@ LIBRARY_FLAGS = { 'CCFLAGS': ['-DWIN32'], 'CXXFLAGS': ['-DWIN32'], }, + 'os:android': { + 'CPPDEFINES': ['ANDROID', '__ARM_ARCH_5__', '__ARM_ARCH_5T__', + '__ARM_ARCH_5E__', '__ARM_ARCH_5TE__'], + 'CCFLAGS': ANDROID_FLAGS, + 'WARNINGFLAGS': ['-Wall', '-Wno-unused', '-Werror=return-type', + '-Wstrict-aliasing=2'], + 'CPPPATH': ANDROID_INCLUDES, + }, 'arch:ia32': { 'CPPDEFINES': ['V8_TARGET_ARCH_IA32'], 'CCFLAGS': ['-m32'], @@ -154,24 +216,6 @@ LIBRARY_FLAGS = { }, 'unalignedaccesses:off' : { 'CPPDEFINES' : ['CAN_USE_UNALIGNED_ACCESSES=0'] - }, - 'armeabi:soft' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'], - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=soft'], - } - }, - 'armeabi:softfp' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0', 'CAN_USE_VFP_INSTRUCTIONS'], - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=softfp'], - } - }, - 'armeabi:hard' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=1', 'CAN_USE_VFP_INSTRUCTIONS'], - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=hard'], - } } }, 'simulator:arm': { @@ -180,40 +224,14 @@ LIBRARY_FLAGS = { }, 'arch:mips': { 'CPPDEFINES': ['V8_TARGET_ARCH_MIPS'], - 'mips_arch_variant:mips32r2': { - 'CPPDEFINES': ['_MIPS_ARCH_MIPS32R2'] - }, 'simulator:none': { - 'CCFLAGS': ['-EL'], - 'LINKFLAGS': ['-EL'], - 'mips_arch_variant:mips32r2': { - 'CCFLAGS': ['-mips32r2', '-Wa,-mips32r2'] - }, - 'mips_arch_variant:mips32r1': { - 'CCFLAGS': ['-mips32', '-Wa,-mips32'] - }, - 'library:static': { - 'LINKFLAGS': ['-static', '-static-libgcc'] - }, - 'mipsabi:softfloat': { - 'CCFLAGS': ['-msoft-float'], - 'LINKFLAGS': ['-msoft-float'] - }, - 'mipsabi:hardfloat': { - 'CCFLAGS': ['-mhard-float'], - 'LINKFLAGS': ['-mhard-float'] - } + 'CCFLAGS': ['-EL', '-mips32r2', '-Wa,-mips32r2', '-fno-inline'], + 'LDFLAGS': ['-EL'] } }, 'simulator:mips': { 'CCFLAGS': ['-m32'], 'LINKFLAGS': ['-m32'], - 'mipsabi:softfloat': { - 'CPPDEFINES': ['__mips_soft_float=1'], - }, - 'mipsabi:hardfloat': { - 'CPPDEFINES': ['__mips_hard_float=1'], - } }, 'arch:x64': { 'CPPDEFINES': ['V8_TARGET_ARCH_X64'], @@ -222,15 +240,12 @@ LIBRARY_FLAGS = { }, 'gdbjit:on': { 'CPPDEFINES': ['ENABLE_GDB_JIT_INTERFACE'] - }, - 'compress_startup_data:bz2': { - 'CPPDEFINES': ['COMPRESS_STARTUP_DATA_BZ2'] } }, 'msvc': { 'all': { 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], - 'CXXFLAGS': ['/GR-', '/Gy'], + 'CXXFLAGS': ['$CCFLAGS', '/GR-', '/Gy'], 'CPPDEFINES': ['WIN32'], 'LINKFLAGS': ['/INCREMENTAL:NO', '/NXCOMPAT', '/IGNORE:4221'], 'CCPDBFLAGS': ['/Zi'] @@ -291,7 +306,6 @@ V8_EXTRA_FLAGS = { 'gcc': { 'all': { 'WARNINGFLAGS': ['-Wall', - '-Werror', '-W', '-Wno-unused-parameter', '-Wnon-virtual-dtor'] @@ -310,11 +324,6 @@ V8_EXTRA_FLAGS = { 'os:macos': { 'WARNINGFLAGS': ['-pedantic'] }, - 'arch:arm': { - # This is to silence warnings about ABI changes that some versions of the - # CodeSourcery G++ tool chain produce for each occurrence of varargs. - 'WARNINGFLAGS': ['-Wno-abi'] - }, 'disassembler:on': { 'CPPDEFINES': ['ENABLE_DISASSEMBLER'] } @@ -335,9 +344,6 @@ V8_EXTRA_FLAGS = { }, 'arch:mips': { 'CPPDEFINES': ['V8_TARGET_ARCH_MIPS'], - 'mips_arch_variant:mips32r2': { - 'CPPDEFINES': ['_MIPS_ARCH_MIPS32R2'] - }, }, 'disassembler:on': { 'CPPDEFINES': ['ENABLE_DISASSEMBLER'] @@ -367,11 +373,6 @@ MKSNAPSHOT_EXTRA_FLAGS = { 'os:win32': { 'LIBS': ['winmm', 'ws2_32'], }, - 'compress_startup_data:bz2': { - 'os:linux': { - 'LIBS': ['bz2'] - } - }, }, 'msvc': { 'all': { @@ -400,16 +401,10 @@ DTOA_EXTRA_FLAGS = { CCTEST_EXTRA_FLAGS = { 'all': { 'CPPPATH': [join(root_dir, 'src')], - 'library:shared': { - 'CPPDEFINES': ['USING_V8_SHARED'] - }, }, 'gcc': { 'all': { - 'LIBPATH': [abspath('.')], - 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], - 'CXXFLAGS': ['-fno-rtti', '-fno-exceptions'], - 'LINKFLAGS': ['$CCFLAGS'], + 'LIBPATH': [abspath('.')] }, 'os:linux': { 'LIBS': ['pthread'], @@ -430,6 +425,19 @@ CCTEST_EXTRA_FLAGS = { 'os:win32': { 'LIBS': ['winmm', 'ws2_32'] }, + 'os:android': { + 'CPPDEFINES': ['ANDROID', '__ARM_ARCH_5__', '__ARM_ARCH_5T__', + '__ARM_ARCH_5E__', '__ARM_ARCH_5TE__'], + 'CCFLAGS': ANDROID_FLAGS, + 'CPPPATH': ANDROID_INCLUDES, + 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib', + ANDROID_TOP + '/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/interwork'], + 'LINKFLAGS': ANDROID_LINKFLAGS, + 'LIBS': ['log', 'c', 'stdc++', 'm', 'gcc'], + 'mode:release': { + 'CPPDEFINES': ['SK_RELEASE', 'NDEBUG'] + } + }, 'arch:arm': { 'LINKFLAGS': ARM_LINK_FLAGS }, @@ -439,6 +447,9 @@ CCTEST_EXTRA_FLAGS = { 'CPPDEFINES': ['_HAS_EXCEPTIONS=0'], 'LIBS': ['winmm', 'ws2_32'] }, + 'library:shared': { + 'CPPDEFINES': ['USING_V8_SHARED'] + }, 'arch:ia32': { 'CPPDEFINES': ['V8_TARGET_ARCH_IA32'] }, @@ -453,16 +464,11 @@ CCTEST_EXTRA_FLAGS = { SAMPLE_FLAGS = { 'all': { 'CPPPATH': [join(abspath('.'), 'include')], - 'library:shared': { - 'CPPDEFINES': ['USING_V8_SHARED'] - }, }, 'gcc': { 'all': { - 'LIBPATH': ['.'], - 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], - 'CXXFLAGS': ['-fno-rtti', '-fno-exceptions'], - 'LINKFLAGS': ['$CCFLAGS'], + 'LIBPATH': ['.'], + 'CCFLAGS': ['-fno-rtti', '-fno-exceptions'] }, 'os:linux': { 'LIBS': ['pthread'], @@ -471,45 +477,37 @@ SAMPLE_FLAGS = { 'LIBS': ['pthread'], }, 'os:freebsd': { - 'LIBPATH' : ['/usr/local/lib'], - 'LIBS': ['execinfo', 'pthread'] + 'LIBPATH' : ['/usr/local/lib'], + 'LIBS': ['execinfo', 'pthread'] }, 'os:solaris': { - # On Solaris, to get isinf, INFINITY, fpclassify and other macros one - # needs to define __C99FEATURES__. - 'CPPDEFINES': ['__C99FEATURES__'], - 'LIBPATH' : ['/usr/local/lib'], - 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'], - 'LINKFLAGS': ['-mt'] + 'LIBPATH' : ['/usr/local/lib'], + 'LIBS': ['m', 'pthread', 'socket', 'nsl', 'rt'], + 'LINKFLAGS': ['-mt'] }, 'os:openbsd': { - 'LIBPATH' : ['/usr/local/lib'], - 'LIBS': ['execinfo', 'pthread'] + 'LIBPATH' : ['/usr/local/lib'], + 'LIBS': ['execinfo', 'pthread'] }, 'os:win32': { 'LIBS': ['winmm', 'ws2_32'] }, - 'arch:arm': { - 'LINKFLAGS': ARM_LINK_FLAGS, - 'armeabi:soft' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'], - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=soft'], - } - }, - 'armeabi:softfp' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'], - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=softfp'], - } - }, - 'armeabi:hard' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=1', 'CAN_USE_VFP_INSTRUCTIONS'], - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=hard'], - } + 'os:android': { + 'CPPDEFINES': ['ANDROID', '__ARM_ARCH_5__', '__ARM_ARCH_5T__', + '__ARM_ARCH_5E__', '__ARM_ARCH_5TE__'], + 'CCFLAGS': ANDROID_FLAGS, + 'CPPPATH': ANDROID_INCLUDES, + 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib', + ANDROID_TOP + '/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/interwork'], + 'LINKFLAGS': ANDROID_LINKFLAGS, + 'LIBS': ['log', 'c', 'stdc++', 'm', 'gcc'], + 'mode:release': { + 'CPPDEFINES': ['SK_RELEASE', 'NDEBUG'] } }, + 'arch:arm': { + 'LINKFLAGS': ARM_LINK_FLAGS + }, 'arch:ia32': { 'CCFLAGS': ['-m32'], 'LINKFLAGS': ['-m32'] @@ -520,29 +518,10 @@ SAMPLE_FLAGS = { }, 'arch:mips': { 'CPPDEFINES': ['V8_TARGET_ARCH_MIPS'], - 'mips_arch_variant:mips32r2': { - 'CPPDEFINES': ['_MIPS_ARCH_MIPS32R2'] - }, 'simulator:none': { - 'CCFLAGS': ['-EL'], + 'CCFLAGS': ['-EL', '-mips32r2', '-Wa,-mips32r2', '-fno-inline'], 'LINKFLAGS': ['-EL'], - 'mips_arch_variant:mips32r2': { - 'CCFLAGS': ['-mips32r2', '-Wa,-mips32r2'] - }, - 'mips_arch_variant:mips32r1': { - 'CCFLAGS': ['-mips32', '-Wa,-mips32'] - }, - 'library:static': { - 'LINKFLAGS': ['-static', '-static-libgcc'] - }, - 'mipsabi:softfloat': { - 'CCFLAGS': ['-msoft-float'], - 'LINKFLAGS': ['-msoft-float'] - }, - 'mipsabi:hardfloat': { - 'CCFLAGS': ['-mhard-float'], - 'LINKFLAGS': ['-mhard-float'] - } + 'LDFLAGS': ['-EL'] } }, 'simulator:arm': { @@ -560,12 +539,6 @@ SAMPLE_FLAGS = { 'CCFLAGS': ['-g', '-O0'], 'CPPDEFINES': ['DEBUG'] }, - 'compress_startup_data:bz2': { - 'CPPDEFINES': ['COMPRESS_STARTUP_DATA_BZ2'], - 'os:linux': { - 'LIBS': ['bz2'] - } - }, }, 'msvc': { 'all': { @@ -578,161 +551,9 @@ SAMPLE_FLAGS = { 'verbose:on': { 'LINKFLAGS': ['/VERBOSE'] }, - 'prof:on': { - 'LINKFLAGS': ['/MAP'] - }, - 'mode:release': { - 'CCFLAGS': ['/O2'], - 'LINKFLAGS': ['/OPT:REF', '/OPT:ICF'], - 'msvcrt:static': { - 'CCFLAGS': ['/MT'] - }, - 'msvcrt:shared': { - 'CCFLAGS': ['/MD'] - }, - 'msvcltcg:on': { - 'CCFLAGS': ['/GL'], - 'pgo:off': { - 'LINKFLAGS': ['/LTCG'], - }, - }, - 'pgo:instrument': { - 'LINKFLAGS': ['/LTCG:PGI'] - }, - 'pgo:optimize': { - 'LINKFLAGS': ['/LTCG:PGO'] - } - }, - 'arch:ia32': { - 'CPPDEFINES': ['V8_TARGET_ARCH_IA32', 'WIN32'], - 'LINKFLAGS': ['/MACHINE:X86'] - }, - 'arch:x64': { - 'CPPDEFINES': ['V8_TARGET_ARCH_X64', 'WIN32'], - 'LINKFLAGS': ['/MACHINE:X64', '/STACK:2091752'] - }, - 'mode:debug': { - 'CCFLAGS': ['/Od'], - 'LINKFLAGS': ['/DEBUG'], - 'CPPDEFINES': ['DEBUG'], - 'msvcrt:static': { - 'CCFLAGS': ['/MTd'] - }, - 'msvcrt:shared': { - 'CCFLAGS': ['/MDd'] - } - } - } -} - - -PREPARSER_FLAGS = { - 'all': { - 'CPPPATH': [join(abspath('.'), 'include'), join(abspath('.'), 'src')], 'library:shared': { 'CPPDEFINES': ['USING_V8_SHARED'] }, - }, - 'gcc': { - 'all': { - 'LIBPATH': ['.'], - 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], - 'CXXFLAGS': ['-fno-rtti', '-fno-exceptions'], - 'LINKFLAGS': ['$CCFLAGS'], - }, - 'os:win32': { - 'LIBS': ['winmm', 'ws2_32'] - }, - 'arch:arm': { - 'LINKFLAGS': ARM_LINK_FLAGS, - 'armeabi:soft' : { - 'CPPDEFINES' : ['USE_EABI_HARDFLOAT=0'], - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=soft'], - } - }, - 'armeabi:softfp' : { - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=softfp'], - } - }, - 'armeabi:hard' : { - 'simulator:none': { - 'CCFLAGS': ['-mfloat-abi=hard'], - } - } - }, - 'arch:ia32': { - 'CCFLAGS': ['-m32'], - 'LINKFLAGS': ['-m32'] - }, - 'arch:x64': { - 'CCFLAGS': ['-m64'], - 'LINKFLAGS': ['-m64'] - }, - 'arch:mips': { - 'CPPDEFINES': ['V8_TARGET_ARCH_MIPS'], - 'mips_arch_variant:mips32r2': { - 'CPPDEFINES': ['_MIPS_ARCH_MIPS32R2'] - }, - 'simulator:none': { - 'CCFLAGS': ['-EL'], - 'LINKFLAGS': ['-EL'], - 'mips_arch_variant:mips32r2': { - 'CCFLAGS': ['-mips32r2', '-Wa,-mips32r2'] - }, - 'mips_arch_variant:mips32r1': { - 'CCFLAGS': ['-mips32', '-Wa,-mips32'] - }, - 'library:static': { - 'LINKFLAGS': ['-static', '-static-libgcc'] - }, - 'mipsabi:softfloat': { - 'CCFLAGS': ['-msoft-float'], - 'LINKFLAGS': ['-msoft-float'] - }, - 'mipsabi:hardfloat': { - 'CCFLAGS': ['-mhard-float'], - 'LINKFLAGS': ['-mhard-float'] - } - } - }, - 'simulator:arm': { - 'CCFLAGS': ['-m32'], - 'LINKFLAGS': ['-m32'] - }, - 'simulator:mips': { - 'CCFLAGS': ['-m32'], - 'LINKFLAGS': ['-m32'], - 'mipsabi:softfloat': { - 'CPPDEFINES': ['__mips_soft_float=1'], - }, - 'mipsabi:hardfloat': { - 'CPPDEFINES': ['__mips_hard_float=1'], - } - }, - 'mode:release': { - 'CCFLAGS': ['-O2'] - }, - 'mode:debug': { - 'CCFLAGS': ['-g', '-O0'], - 'CPPDEFINES': ['DEBUG'] - }, - 'os:freebsd': { - 'LIBPATH' : ['/usr/local/lib'], - }, - }, - 'msvc': { - 'all': { - 'LIBS': ['winmm', 'ws2_32'] - }, - 'verbose:off': { - 'CCFLAGS': ['/nologo'], - 'LINKFLAGS': ['/NOLOGO'] - }, - 'verbose:on': { - 'LINKFLAGS': ['/VERBOSE'] - }, 'prof:on': { 'LINKFLAGS': ['/MAP'] }, @@ -759,11 +580,11 @@ PREPARSER_FLAGS = { } }, 'arch:ia32': { - 'CPPDEFINES': ['V8_TARGET_ARCH_IA32', 'WIN32'], + 'CPPDEFINES': ['V8_TARGET_ARCH_IA32'], 'LINKFLAGS': ['/MACHINE:X86'] }, 'arch:x64': { - 'CPPDEFINES': ['V8_TARGET_ARCH_X64', 'WIN32'], + 'CPPDEFINES': ['V8_TARGET_ARCH_X64'], 'LINKFLAGS': ['/MACHINE:X64', '/STACK:2091752'] }, 'mode:debug': { @@ -783,11 +604,6 @@ PREPARSER_FLAGS = { D8_FLAGS = { 'gcc': { - 'all': { - 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], - 'CXXFLAGS': ['-fno-rtti', '-fno-exceptions'], - 'LINKFLAGS': ['$CCFLAGS'], - }, 'console:readline': { 'LIBS': ['readline'] }, @@ -807,18 +623,18 @@ D8_FLAGS = { 'os:openbsd': { 'LIBS': ['pthread'], }, + 'os:android': { + 'LIBPATH': [ANDROID_TOP + '/out/target/product/generic/obj/lib', + ANDROID_TOP + '/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/interwork'], + 'LINKFLAGS': ANDROID_LINKFLAGS, + 'LIBS': ['log', 'c', 'stdc++', 'm', 'gcc'], + }, 'os:win32': { 'LIBS': ['winmm', 'ws2_32'], }, 'arch:arm': { 'LINKFLAGS': ARM_LINK_FLAGS }, - 'compress_startup_data:bz2': { - 'CPPDEFINES': ['COMPRESS_STARTUP_DATA_BZ2'], - 'os:linux': { - 'LIBS': ['bz2'] - } - } }, 'msvc': { 'all': { @@ -870,14 +686,12 @@ def GuessVisibility(env): def GuessStrictAliasing(env): - # There seems to be a problem with gcc 4.5.x. - # See http://code.google.com/p/v8/issues/detail?id=884 - # It can be worked around by disabling strict aliasing. + # There seems to be a problem with gcc 4.5.x + # see http://code.google.com/p/v8/issues/detail?id=884 + # it can be worked around by disabling strict aliasing toolchain = env['toolchain']; if toolchain == 'gcc': env = Environment(tools=['gcc']) - # The gcc version should be available in env['CCVERSION'], - # but when scons detects msvc this value is not set. version = subprocess.Popen([env['CC'], '-dumpversion'], stdout=subprocess.PIPE).communicate()[0] if version.find('4.5') == 0: @@ -885,25 +699,22 @@ def GuessStrictAliasing(env): return 'default' -PLATFORM_OPTIONS = { - 'arch': { - 'values': ['arm', 'ia32', 'x64', 'mips'], - 'guess': GuessArch, - 'help': 'the architecture to build for' +SIMPLE_OPTIONS = { + 'toolchain': { + 'values': ['gcc', 'msvc'], + 'guess': GuessToolchain, + 'help': 'the toolchain to use' }, 'os': { - 'values': ['freebsd', 'linux', 'macos', 'win32', 'openbsd', 'solaris', 'cygwin'], + 'values': ['freebsd', 'linux', 'macos', 'win32', 'android', 'openbsd', 'solaris', 'cygwin'], 'guess': GuessOS, 'help': 'the os to build for' }, - 'toolchain': { - 'values': ['gcc', 'msvc'], - 'guess': GuessToolchain, - 'help': 'the toolchain to use' - } -} - -SIMPLE_OPTIONS = { + 'arch': { + 'values':['arm', 'ia32', 'x64', 'mips'], + 'guess': GuessArch, + 'help': 'the architecture to build for' + }, 'regexp': { 'values': ['native', 'interpreted'], 'default': 'native', @@ -994,12 +805,6 @@ SIMPLE_OPTIONS = { 'default': 'off', 'help': 'enable the disassembler to inspect generated code' }, - 'fasttls': { - 'values': ['on', 'off'], - 'default': 'on', - 'help': 'enable fast thread local storage support ' - '(if available on the current architecture/platform)' - }, 'sourcesignatures': { 'values': ['MD5', 'timestamp'], 'default': 'MD5', @@ -1018,55 +823,41 @@ SIMPLE_OPTIONS = { 'visibility': { 'values': ['default', 'hidden'], 'guess': GuessVisibility, + 'depends': ['os', 'toolchain'], 'help': 'shared library symbol visibility' }, 'strictaliasing': { 'values': ['default', 'off'], 'guess': GuessStrictAliasing, + 'depends': ['toolchain'], 'help': 'assume strict aliasing while optimizing' }, 'pgo': { 'values': ['off', 'instrument', 'optimize'], 'default': 'off', 'help': 'select profile guided optimization variant', - }, - 'armeabi': { - 'values': ['hard', 'softfp', 'soft'], - 'default': 'softfp', - 'help': 'generate calling conventiont according to selected ARM EABI variant' - }, - 'mipsabi': { - 'values': ['hardfloat', 'softfloat', 'none'], - 'default': 'hardfloat', - 'help': 'generate calling conventiont according to selected mips ABI' - }, - 'mips_arch_variant': { - 'values': ['mips32r2', 'mips32r1'], - 'default': 'mips32r2', - 'help': 'mips variant' - }, - 'compress_startup_data': { - 'values': ['off', 'bz2'], - 'default': 'off', - 'help': 'compress startup data (snapshot) [Linux only]' - }, + } } -ALL_OPTIONS = dict(PLATFORM_OPTIONS, **SIMPLE_OPTIONS) +def AddOption(result, name, option): + if 'guess' in option: + # Option has a guess function + guess = option.get('guess') + guess_env = Environment(options=result) + # Check if all options that the guess function depends on are set + if 'depends' in option: + for dependency in option.get('depends'): + if not dependency in guess_env: + return False + default = guess(guess_env) + else: + # Option has a fixed default + default = option.get('default') -def AddOptions(options, result): - guess_env = Environment(options=result) - for (name, option) in options.iteritems(): - if 'guess' in option: - # Option has a guess function - guess = option.get('guess') - default = guess(guess_env) - else: - # Option has a fixed default - default = option.get('default') - help = '%s (%s)' % (option.get('help'), ", ".join(option['values'])) - result.Add(name, help, default) + help = '%s (%s)' % (option.get('help'), ", ".join(option['values'])) + result.Add(name, help, default) + return True def GetOptions(): @@ -1076,8 +867,13 @@ def GetOptions(): result.Add('cache', 'directory to use for scons build cache', '') result.Add('env', 'override environment settings (NAME0:value0,NAME1:value1,...)', '') result.Add('importenv', 'import environment settings (NAME0,NAME1,...)', '') - AddOptions(PLATFORM_OPTIONS, result) - AddOptions(SIMPLE_OPTIONS, result) + options = SIMPLE_OPTIONS + while len(options): + postpone = {} + for (name, option) in options.iteritems(): + if not AddOption(result, name, option): + postpone[name] = option + options = postpone return result @@ -1158,8 +954,8 @@ def VerifyOptions(env): return False if env['os'] == 'win32' and env['library'] == 'shared' and env['prof'] == 'on': Abort("Profiling on windows only supported for static library.") - if env['gdbjit'] == 'on' and ((env['os'] != 'linux' and env['os'] != 'macos') or (env['arch'] != 'ia32' and env['arch'] != 'x64' and env['arch'] != 'arm')): - Abort("GDBJIT interface is supported only for Intel-compatible (ia32 or x64) Linux/OSX target.") + if env['gdbjit'] == 'on' and (env['os'] != 'linux' or (env['arch'] != 'ia32' and env['arch'] != 'x64' and env['arch'] != 'arm')): + Abort("GDBJIT interface is supported only for Intel-compatible (ia32 or x64) Linux target.") if env['os'] == 'win32' and env['soname'] == 'on': Abort("Shared Object soname not applicable for Windows.") if env['soname'] == 'on' and env['library'] == 'static': @@ -1172,9 +968,7 @@ def VerifyOptions(env): print env['arch'] print env['simulator'] Abort("Option unalignedaccesses only supported for the ARM architecture.") - if env['os'] != 'linux' and env['compress_startup_data'] != 'off': - Abort("Startup data compression is only available on Linux") - for (name, option) in ALL_OPTIONS.iteritems(): + for (name, option) in SIMPLE_OPTIONS.iteritems(): if (not name in env): message = ("A value for option %s must be specified (%s)." % (name, ", ".join(option['values']))) @@ -1196,7 +990,6 @@ class BuildContext(object): self.options = options self.env_overrides = env_overrides self.samples = samples - self.preparser_targets = [] self.use_snapshot = (options['snapshot'] != 'off') self.build_snapshot = (options['snapshot'] == 'on') self.flags = None @@ -1275,8 +1068,11 @@ def PostprocessOptions(options, os): if 'msvcltcg' in ARGUMENTS: print "Warning: forcing msvcltcg on as it is required for pgo (%s)" % options['pgo'] options['msvcltcg'] = 'on' - if (options['mipsabi'] != 'none') and (options['arch'] != 'mips') and (options['simulator'] != 'mips'): - options['mipsabi'] = 'none' + if options['arch'] == 'mips': + if ('regexp' in ARGUMENTS) and options['regexp'] == 'native': + # Print a warning if native regexp is specified for mips + print "Warning: forcing regexp to interpreted for mips" + options['regexp'] = 'interpreted' if options['liveobjectlist'] == 'on': if (options['debuggersupport'] != 'on') or (options['mode'] == 'release'): # Print a warning that liveobjectlist will implicitly enable the debugger @@ -1303,7 +1099,7 @@ def ParseEnvOverrides(arg, imports): def BuildSpecific(env, mode, env_overrides, tools): options = {'mode': mode} - for option in ALL_OPTIONS: + for option in SIMPLE_OPTIONS: options[option] = env[option] PostprocessOptions(options, env['os']) @@ -1323,7 +1119,6 @@ def BuildSpecific(env, mode, env_overrides, tools): dtoa_flags = context.AddRelevantFlags(library_flags, DTOA_EXTRA_FLAGS) cctest_flags = context.AddRelevantFlags(v8_flags, CCTEST_EXTRA_FLAGS) sample_flags = context.AddRelevantFlags(user_environ, SAMPLE_FLAGS) - preparser_flags = context.AddRelevantFlags(user_environ, PREPARSER_FLAGS) d8_flags = context.AddRelevantFlags(library_flags, D8_FLAGS) context.flags = { @@ -1332,15 +1127,13 @@ def BuildSpecific(env, mode, env_overrides, tools): 'dtoa': dtoa_flags, 'cctest': cctest_flags, 'sample': sample_flags, - 'd8': d8_flags, - 'preparser': preparser_flags + 'd8': d8_flags } # Generate library base name. target_id = mode suffix = SUFFIXES[target_id] library_name = 'v8' + suffix - preparser_library_name = 'v8preparser' + suffix version = GetVersion() if context.options['soname'] == 'on': # When building shared object with SONAME version the library name. @@ -1354,7 +1147,7 @@ def BuildSpecific(env, mode, env_overrides, tools): env['SONAME'] = soname # Build the object files by invoking SCons recursively. - (object_files, shell_files, mksnapshot, preparser_files) = env.SConscript( + (object_files, shell_files, mksnapshot) = env.SConscript( join('src', 'SConscript'), build_dir=join('obj', target_id), exports='context tools', @@ -1369,22 +1162,13 @@ def BuildSpecific(env, mode, env_overrides, tools): context.ApplyEnvOverrides(env) if context.options['library'] == 'static': library = env.StaticLibrary(library_name, object_files) - preparser_library = env.StaticLibrary(preparser_library_name, - preparser_files) else: # There seems to be a glitch in the way scons decides where to put # PDB files when compiling using MSVC so we specify it manually. # This should not affect any other platforms. pdb_name = library_name + '.dll.pdb' library = env.SharedLibrary(library_name, object_files, PDB=pdb_name) - preparser_pdb_name = preparser_library_name + '.dll.pdb'; - preparser_soname = 'lib' + preparser_library_name + '.so'; - preparser_library = env.SharedLibrary(preparser_library_name, - preparser_files, - PDB=preparser_pdb_name, - SONAME=preparser_soname) context.library_targets.append(library) - context.library_targets.append(preparser_library) d8_env = Environment(tools=tools) d8_env.Replace(**context.flags['d8']) @@ -1418,21 +1202,6 @@ def BuildSpecific(env, mode, env_overrides, tools): ) context.cctest_targets.append(cctest_program) - preparser_env = env.Copy() - preparser_env.Replace(**context.flags['preparser']) - preparser_env.Prepend(LIBS=[preparser_library_name]) - context.ApplyEnvOverrides(preparser_env) - preparser_object = preparser_env.SConscript( - join('preparser', 'SConscript'), - build_dir=join('obj', 'preparser', target_id), - exports='context', - duplicate=False - ) - preparser_name = join('obj', 'preparser', target_id, 'preparser') - preparser_program = preparser_env.Program(preparser_name, preparser_object); - preparser_env.Depends(preparser_program, preparser_library) - context.preparser_targets.append(preparser_program) - return context @@ -1451,7 +1220,6 @@ def Build(): mksnapshots = [] cctests = [] samples = [] - preparsers = [] d8s = [] modes = SplitList(env['mode']) for mode in modes: @@ -1460,7 +1228,6 @@ def Build(): mksnapshots += context.mksnapshot_targets cctests += context.cctest_targets samples += context.sample_targets - preparsers += context.preparser_targets d8s += context.d8_targets env.Alias('library', libraries) @@ -1468,7 +1235,6 @@ def Build(): env.Alias('cctests', cctests) env.Alias('sample', samples) env.Alias('d8', d8s) - env.Alias('preparser', preparsers) if env['sample']: env.Default('sample') diff --git a/deps/v8/include/v8-debug.h b/deps/v8/include/v8-debug.h index 504cbfed590..f17b848550d 100755 --- a/deps/v8/include/v8-debug.h +++ b/deps/v8/include/v8-debug.h @@ -127,7 +127,7 @@ class EXPORT Debug { /** * Get the context active when the debug event happened. Note this is not * the current active context as the JavaScript part of the debugger is - * running in its own context which is entered at this point. + * running in it's own context which is entered at this point. */ virtual Handle GetEventContext() const = 0; @@ -164,13 +164,12 @@ class EXPORT Debug { /** * Get the context active when the debug event happened. Note this is not * the current active context as the JavaScript part of the debugger is - * running in its own context which is entered at this point. + * running in it's own context which is entered at this point. */ virtual Handle GetEventContext() const = 0; /** - * Client data passed with the corresponding callback when it was - * registered. + * Client data passed with the corresponding callbak whet it was registered. */ virtual Handle GetCallbackData() const = 0; @@ -228,7 +227,7 @@ class EXPORT Debug { * Debug message callback function. * * \param message the debug message handler message object - * + * A MessageHandler does not take possession of the message data, * and must not rely on the data persisting after the handler returns. */ @@ -254,35 +253,25 @@ class EXPORT Debug { static bool SetDebugEventListener(v8::Handle that, Handle data = Handle()); - // Schedule a debugger break to happen when JavaScript code is run - // in the given isolate. If no isolate is provided the default - // isolate is used. - static void DebugBreak(Isolate* isolate = NULL); + // Schedule a debugger break to happen when JavaScript code is run. + static void DebugBreak(); - // Remove scheduled debugger break in given isolate if it has not - // happened yet. If no isolate is provided the default isolate is - // used. - static void CancelDebugBreak(Isolate* isolate = NULL); + // Remove scheduled debugger break if it has not happened yet. + static void CancelDebugBreak(); - // Break execution of JavaScript in the given isolate (this method - // can be invoked from a non-VM thread) for further client command - // execution on a VM thread. Client data is then passed in - // EventDetails to EventCallback at the moment when the VM actually - // stops. If no isolate is provided the default isolate is used. - static void DebugBreakForCommand(ClientData* data = NULL, - Isolate* isolate = NULL); + // Break execution of JavaScript (this method can be invoked from a + // non-VM thread) for further client command execution on a VM + // thread. Client data is then passed in EventDetails to + // EventCallback at the moment when the VM actually stops. + static void DebugBreakForCommand(ClientData* data = NULL); // Message based interface. The message protocol is JSON. NOTE the message // handler thread is not supported any more parameter must be false. static void SetMessageHandler(MessageHandler handler, bool message_handler_thread = false); static void SetMessageHandler2(MessageHandler2 handler); - - // If no isolate is provided the default isolate is - // used. static void SendCommand(const uint16_t* command, int length, - ClientData* client_data = NULL, - Isolate* isolate = NULL); + ClientData* client_data = NULL); // Dispatch interface. static void SetHostDispatchHandler(HostDispatchHandler handler, @@ -311,7 +300,7 @@ class EXPORT Debug { * get access to information otherwise not available during normal JavaScript * execution e.g. details on stack frames. Receiver of the function call will * be the debugger context global object, however this is a subject to change. - * The following example shows a JavaScript function which when passed to + * The following example show a JavaScript function which when passed to * v8::Debug::Call will return the current line of JavaScript execution. * * \code @@ -353,7 +342,7 @@ class EXPORT Debug { * 2. V8 is suspended on debug breakpoint; in this state V8 is dedicated * to reading and processing debug messages; * 3. V8 is not running at all or has called some long-working C++ function; - * by default it means that processing of all debug messages will be deferred + * by default it means that processing of all debug message will be deferred * until V8 gets control again; however, embedding application may improve * this by manually calling this method. * @@ -377,7 +366,7 @@ class EXPORT Debug { static void ProcessDebugMessages(); /** - * Debugger is running in its own context which is entered while debugger + * Debugger is running in it's own context which is entered while debugger * messages are being dispatched. This is an explicit getter for this * debugger context. Note that the content of the debugger context is subject * to change. diff --git a/deps/v8/include/v8-preparser.h b/deps/v8/include/v8-preparser.h index f11d05ef793..9425f7d4672 100644 --- a/deps/v8/include/v8-preparser.h +++ b/deps/v8/include/v8-preparser.h @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// 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: @@ -66,18 +66,17 @@ namespace v8 { -// The result of preparsing is either a stack overflow error, or an opaque -// blob of data that can be passed back into the parser. -class V8EXPORT PreParserData { + +class PreParserData { public: PreParserData(size_t size, const uint8_t* data) : data_(data), size_(size) { } // Create a PreParserData value where stack_overflow reports true. - static PreParserData StackOverflow() { return PreParserData(0, NULL); } - + static PreParserData StackOverflow() { return PreParserData(NULL, 0); } // Whether the pre-parser stopped due to a stack overflow. // If this is the case, size() and data() should not be used. + bool stack_overflow() { return size_ == 0u; } // The size of the data in bytes. @@ -93,7 +92,7 @@ class V8EXPORT PreParserData { // Interface for a stream of Unicode characters. -class V8EXPORT UnicodeInputStream { // NOLINT - Thinks V8EXPORT is class name. +class UnicodeInputStream { public: virtual ~UnicodeInputStream(); diff --git a/deps/v8/include/v8-profiler.h b/deps/v8/include/v8-profiler.h index 4febcb95969..675a229854e 100644 --- a/deps/v8/include/v8-profiler.h +++ b/deps/v8/include/v8-profiler.h @@ -131,16 +131,6 @@ class V8EXPORT CpuProfile { /** Returns the root node of the top down call tree. */ const CpuProfileNode* GetTopDownRoot() const; - - /** - * Deletes the profile and removes it from CpuProfiler's list. - * All pointers to nodes previously returned become invalid. - * Profiles with the same uid but obtained using different - * security token are not deleted, but become inaccessible - * using FindProfile method. It is embedder's responsibility - * to call Delete on these profiles. - */ - void Delete(); }; @@ -191,13 +181,6 @@ class V8EXPORT CpuProfiler { static const CpuProfile* StopProfiling( Handle title, Handle security_token = Handle()); - - /** - * Deletes all existing profiles, also cancelling all profiling - * activity. All previously returned pointers to profiles and their - * contents become invalid after this call. - */ - static void DeleteAllProfiles(); }; @@ -206,7 +189,7 @@ class HeapGraphNode; /** * HeapSnapshotEdge represents a directed connection between heap - * graph nodes: from retainers to retained nodes. + * graph nodes: from retaners to retained nodes. */ class V8EXPORT HeapGraphEdge { public: @@ -240,21 +223,36 @@ class V8EXPORT HeapGraphEdge { }; +class V8EXPORT HeapGraphPath { + public: + /** Returns the number of edges in the path. */ + int GetEdgesCount() const; + + /** Returns an edge from the path. */ + const HeapGraphEdge* GetEdge(int index) const; + + /** Returns origin node. */ + const HeapGraphNode* GetFromNode() const; + + /** Returns destination node. */ + const HeapGraphNode* GetToNode() const; +}; + + /** * HeapGraphNode represents a node in a heap graph. */ class V8EXPORT HeapGraphNode { public: enum Type { - kHidden = 0, // Hidden node, may be filtered when shown to user. - kArray = 1, // An array of elements. - kString = 2, // A string. - kObject = 3, // A JS object (except for arrays and strings). - kCode = 4, // Compiled code. - kClosure = 5, // Function closure. - kRegExp = 6, // RegExp. - kHeapNumber = 7, // Number stored in the heap. - kNative = 8 // Native object (not from V8 heap). + kHidden = 0, // Hidden node, may be filtered when shown to user. + kArray = 1, // An array of elements. + kString = 2, // A string. + kObject = 3, // A JS object (except for arrays and strings). + kCode = 4, // Compiled code. + kClosure = 5, // Function closure. + kRegExp = 6, // RegExp. + kHeapNumber = 7 // Number stored in the heap. }; /** Returns node type (see HeapGraphNode::Type). */ @@ -269,10 +267,17 @@ class V8EXPORT HeapGraphNode { /** * Returns node id. For the same heap object, the id remains the same - * across all snapshots. + * across all snapshots. Not applicable to aggregated heap snapshots + * as they only contain aggregated instances. */ uint64_t GetId() const; + /** + * Returns the number of instances. Only applicable to aggregated + * heap snapshots. + */ + int GetInstancesCount() const; + /** Returns node's own size, in bytes. */ int GetSelfSize() const; @@ -302,6 +307,12 @@ class V8EXPORT HeapGraphNode { /** Returns a retainer by index. */ const HeapGraphEdge* GetRetainer(int index) const; + /** Returns the number of simple retaining paths from the root to the node. */ + int GetRetainingPathsCount() const; + + /** Returns a retaining path by index. */ + const HeapGraphPath* GetRetainingPath(int index) const; + /** * Returns a dominator node. This is the node that participates in every * path from the snapshot root to the current node. @@ -310,13 +321,25 @@ class V8EXPORT HeapGraphNode { }; +class V8EXPORT HeapSnapshotsDiff { + public: + /** Returns the root node for added nodes. */ + const HeapGraphNode* GetAdditionsRoot() const; + + /** Returns the root node for deleted nodes. */ + const HeapGraphNode* GetDeletionsRoot() const; +}; + + /** * HeapSnapshots record the state of the JS heap at some moment. */ class V8EXPORT HeapSnapshot { public: enum Type { - kFull = 0 // Heap snapshot with all instances and references. + kFull = 0, // Heap snapshot with all instances and references. + kAggregated = 1 // Snapshot doesn't contain individual heap entries, + // instead they are grouped by constructor name. }; enum SerializationFormat { kJSON = 0 // See format description near 'Serialize' method. @@ -337,24 +360,17 @@ class V8EXPORT HeapSnapshot { /** Returns a node by its id. */ const HeapGraphNode* GetNodeById(uint64_t id) const; - /** Returns total nodes count in the snapshot. */ - int GetNodesCount() const; - - /** Returns a node by index. */ - const HeapGraphNode* GetNode(int index) const; - /** - * Deletes the snapshot and removes it from HeapProfiler's list. - * All pointers to nodes, edges and paths previously returned become - * invalid. + * Returns a diff between this snapshot and another one. Only snapshots + * of the same type can be compared. */ - void Delete(); + const HeapSnapshotsDiff* CompareWith(const HeapSnapshot* snapshot) const; /** * Prepare a serialized representation of the snapshot. The result * is written into the stream provided in chunks of specified size. * The total length of the serialized snapshot is unknown in - * advance, it can be roughly equal to JS heap size (that means, + * advance, it is can be roughly equal to JS heap size (that means, * it can be really big - tens of megabytes). * * For the JSON format, heap contents are represented as an object @@ -376,22 +392,11 @@ class V8EXPORT HeapSnapshot { }; -class RetainedObjectInfo; - /** * Interface for controlling heap profiling. */ class V8EXPORT HeapProfiler { public: - /** - * Callback function invoked for obtaining RetainedObjectInfo for - * the given JavaScript wrapper object. It is prohibited to enter V8 - * while the callback is running: only getters on the handle and - * GetPointerFromInternalField on the objects are allowed. - */ - typedef RetainedObjectInfo* (*WrapperInfoCallback) - (uint16_t class_id, Handle wrapper); - /** Returns the number of snapshots taken. */ static int GetSnapshotsCount(); @@ -409,87 +414,6 @@ class V8EXPORT HeapProfiler { Handle title, HeapSnapshot::Type type = HeapSnapshot::kFull, ActivityControl* control = NULL); - - /** - * Deletes all snapshots taken. All previously returned pointers to - * snapshots and their contents become invalid after this call. - */ - static void DeleteAllSnapshots(); - - /** Binds a callback to embedder's class ID. */ - static void DefineWrapperClass( - uint16_t class_id, - WrapperInfoCallback callback); - - /** - * Default value of persistent handle class ID. Must not be used to - * define a class. Can be used to reset a class of a persistent - * handle. - */ - static const uint16_t kPersistentHandleNoClassId = 0; -}; - - -/** - * Interface for providing information about embedder's objects - * held by global handles. This information is reported in two ways: - * - * 1. When calling AddObjectGroup, an embedder may pass - * RetainedObjectInfo instance describing the group. To collect - * this information while taking a heap snapshot, V8 calls GC - * prologue and epilogue callbacks. - * - * 2. When a heap snapshot is collected, V8 additionally - * requests RetainedObjectInfos for persistent handles that - * were not previously reported via AddObjectGroup. - * - * Thus, if an embedder wants to provide information about native - * objects for heap snapshots, he can do it in a GC prologue - * handler, and / or by assigning wrapper class ids in the following way: - * - * 1. Bind a callback to class id by calling DefineWrapperClass. - * 2. Call SetWrapperClassId on certain persistent handles. - * - * V8 takes ownership of RetainedObjectInfo instances passed to it and - * keeps them alive only during snapshot collection. Afterwards, they - * are freed by calling the Dispose class function. - */ -class V8EXPORT RetainedObjectInfo { // NOLINT - public: - /** Called by V8 when it no longer needs an instance. */ - virtual void Dispose() = 0; - - /** Returns whether two instances are equivalent. */ - virtual bool IsEquivalent(RetainedObjectInfo* other) = 0; - - /** - * Returns hash value for the instance. Equivalent instances - * must have the same hash value. - */ - virtual intptr_t GetHash() = 0; - - /** - * Returns human-readable label. It must be a NUL-terminated UTF-8 - * encoded string. V8 copies its contents during a call to GetLabel. - */ - virtual const char* GetLabel() = 0; - - /** - * Returns element count in case if a global handle retains - * a subgraph by holding one of its nodes. - */ - virtual intptr_t GetElementCount() { return -1; } - - /** Returns embedder's object size in bytes. */ - virtual intptr_t GetSizeInBytes() { return -1; } - - protected: - RetainedObjectInfo() {} - virtual ~RetainedObjectInfo() {} - - private: - RetainedObjectInfo(const RetainedObjectInfo&); - RetainedObjectInfo& operator=(const RetainedObjectInfo&); }; diff --git a/deps/v8/include/v8-testing.h b/deps/v8/include/v8-testing.h index 245f74d878d..4db30a44050 100644 --- a/deps/v8/include/v8-testing.h +++ b/deps/v8/include/v8-testing.h @@ -87,11 +87,6 @@ class V8EXPORT Testing { * should be between 0 and one less than the result from GetStressRuns() */ static void PrepareStressRun(int run); - - /** - * Force deoptimization of all functions. - */ - static void DeoptimizeAll(); }; diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index fb10c71576d..83a5744278a 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2007-2009 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: @@ -110,12 +110,11 @@ namespace internal { class Arguments; class Object; class Heap; -class HeapObject; -class Isolate; +class Top; } -// --- Weak Handles --- +// --- W e a k H a n d l e s /** @@ -131,7 +130,7 @@ typedef void (*WeakReferenceCallback)(Persistent object, void* parameter); -// --- Handles --- +// --- H a n d l e s --- #define TYPE_CHECK(T, S) \ while (false) { \ @@ -159,12 +158,13 @@ typedef void (*WeakReferenceCallback)(Persistent object, * * It is safe to extract the object stored in the handle by * dereferencing the handle (for instance, to extract the Object* from - * a Handle); the value will still be governed by a handle + * an Handle); the value will still be governed by a handle * behind the scenes and the same rules apply to these values as to * their handles. */ template class Handle { public: + /** * Creates an empty handle. */ @@ -180,7 +180,7 @@ template class Handle { * constructor allows you to pass handles as arguments by value and * to assign between handles. However, if you try to assign between * incompatible handles, for instance from a Handle to a - * Handle it will cause a compile-time error. Assigning + * Handle it will cause a compiletime error. Assigning * between compatible handles, for instance assigning a * Handle to a variable declared as Handle, is legal * because String is a subclass of Value. @@ -311,6 +311,7 @@ template class Local : public Handle { */ template class Persistent : public Handle { public: + /** * Creates an empty persistent handle that doesn't point to any * storage cell. @@ -323,7 +324,7 @@ template class Persistent : public Handle { * handles as arguments by value and to assign between persistent * handles. However, attempting to assign between incompatible * persistent handles, for instance from a Persistent to a - * Persistent will cause a compile-time error. Assigning + * Persistent will cause a compiletime error. Assigning * between compatible persistent handles, for instance assigning a * Persistent to a variable declared as Persistent, * is allowed as String is a subclass of Value. @@ -369,7 +370,7 @@ template class Persistent : public Handle { /** * Releases the storage cell referenced by this persistent handle. * Does not remove the reference to the cell from any handles. - * This handle's reference, and any other references to the storage + * This handle's reference, and any any other references to the storage * cell remain and IsEmpty will still return false. */ inline void Dispose(); @@ -385,15 +386,6 @@ template class Persistent : public Handle { /** Clears the weak reference to this object.*/ inline void ClearWeak(); - /** - * Marks the reference to this object independent. Garbage collector - * is free to ignore any object groups containing this object. - * Weak callback for an independent handle should not - * assume that it will be preceded by a global GC prologue callback - * or followed by a global GC epilogue callback. - */ - inline void MarkIndependent(); - /** *Checks if the handle holds the only reference to an object. */ @@ -404,12 +396,6 @@ template class Persistent : public Handle { */ inline bool IsWeak() const; - /** - * Assigns a wrapper class ID to the handle. See RetainedObjectInfo - * interface description in v8-profiler.h for details. - */ - inline void SetWrapperClassId(uint16_t class_id); - private: friend class ImplementationUtilities; friend class ObjectTemplate; @@ -451,8 +437,6 @@ class V8EXPORT HandleScope { * Creates a new handle with the given value. */ static internal::Object** CreateHandle(internal::Object* value); - // Faster version, uses HeapObject to obtain the current Isolate. - static internal::Object** CreateHandle(internal::HeapObject* value); private: // Make it impossible to create heap-allocated or illegal handle @@ -469,6 +453,7 @@ class V8EXPORT HandleScope { internal::Object** next; internal::Object** limit; int level; + inline void Initialize() { next = limit = NULL; level = 0; @@ -477,7 +462,6 @@ class V8EXPORT HandleScope { void Leave(); - internal::Isolate* isolate_; internal::Object** prev_next_; internal::Object** prev_limit_; @@ -490,7 +474,7 @@ class V8EXPORT HandleScope { }; -// --- Special objects --- +// --- S p e c i a l o b j e c t s --- /** @@ -584,6 +568,7 @@ class ScriptOrigin { */ class V8EXPORT Script { public: + /** * Compiles the specified script (context-independent). * @@ -781,7 +766,7 @@ class V8EXPORT StackTrace { Local AsArray(); /** - * Grab a snapshot of the current JavaScript execution stack. + * Grab a snapshot of the the current JavaScript execution stack. * * \param frame_limit The maximum number of stack frames we want to capture. * \param options Enumerates the set of things we will capture for each @@ -840,14 +825,14 @@ class V8EXPORT StackFrame { bool IsEval() const; /** - * Returns whether or not the associated function is called as a + * Returns whther or not the associated function is called as a * constructor via "new". */ bool IsConstructor() const; }; -// --- Value --- +// --- V a l u e --- /** @@ -855,6 +840,7 @@ class V8EXPORT StackFrame { */ class Value : public Data { public: + /** * Returns true if this value is the undefined value. See ECMA-262 * 4.3.10. @@ -986,6 +972,7 @@ class Boolean : public Primitive { */ class String : public Primitive { public: + /** * Returns the number of characters in this string. */ @@ -1186,7 +1173,7 @@ class String : public Primitive { * Associate an external string resource with this string by transforming it * in place so that existing references to this string in the JavaScript heap * will use the external string resource. The external string resource's - * character contents need to be equivalent to this string. + * character contents needs to be equivalent to this string. * Returns true if the string has been changed to be an external string. * The string is not modified if the operation fails. See NewExternal for * information on the lifetime of the resource. @@ -1208,7 +1195,7 @@ class String : public Primitive { * Associate an external string resource with this string by transforming it * in place so that existing references to this string in the JavaScript heap * will use the external string resource. The external string resource's - * character contents need to be equivalent to this string. + * character contents needs to be equivalent to this string. * Returns true if the string has been changed to be an external string. * The string is not modified if the operation fails. See NewExternal for * information on the lifetime of the resource. @@ -1353,6 +1340,87 @@ class Uint32 : public Integer { }; +/** + * An instance of the built-in Date constructor (ECMA-262, 15.9). + */ +class Date : public Value { + public: + V8EXPORT static Local New(double time); + + /** + * A specialization of Value::NumberValue that is more efficient + * because we know the structure of this object. + */ + V8EXPORT double NumberValue() const; + + static inline Date* Cast(v8::Value* obj); + + /** + * Notification that the embedder has changed the time zone, + * daylight savings time, or other date / time configuration + * parameters. V8 keeps a cache of various values used for + * date / time computation. This notification will reset + * those cached values for the current context so that date / + * time configuration changes would be reflected in the Date + * object. + * + * This API should not be called more than needed as it will + * negatively impact the performance of date operations. + */ + V8EXPORT static void DateTimeConfigurationChangeNotification(); + + private: + V8EXPORT static void CheckCast(v8::Value* obj); +}; + + +/** + * An instance of the built-in RegExp constructor (ECMA-262, 15.10). + */ +class RegExp : public Value { + public: + /** + * Regular expression flag bits. They can be or'ed to enable a set + * of flags. + */ + enum Flags { + kNone = 0, + kGlobal = 1, + kIgnoreCase = 2, + kMultiline = 4 + }; + + /** + * Creates a regular expression from the given pattern string and + * the flags bit field. May throw a JavaScript exception as + * described in ECMA-262, 15.10.4.1. + * + * For example, + * RegExp::New(v8::String::New("foo"), + * static_cast(kGlobal | kMultiline)) + * is equivalent to evaluating "/foo/gm". + */ + V8EXPORT static Local New(Handle pattern, + Flags flags); + + /** + * Returns the value of the source property: a string representing + * the regular expression. + */ + V8EXPORT Local GetSource() const; + + /** + * Returns the flags bit field. + */ + V8EXPORT Flags GetFlags() const; + + static inline RegExp* Cast(v8::Value* obj); + + private: + V8EXPORT static void CheckCast(v8::Value* obj); +}; + + enum PropertyAttribute { None = 0, ReadOnly = 1 << 0, @@ -1367,9 +1435,7 @@ enum ExternalArrayType { kExternalUnsignedShortArray, kExternalIntArray, kExternalUnsignedIntArray, - kExternalFloatArray, - kExternalDoubleArray, - kExternalPixelArray + kExternalFloatArray }; /** @@ -1464,13 +1530,6 @@ class Object : public Value { */ V8EXPORT Local GetPropertyNames(); - /** - * This function has the same functionality as GetPropertyNames but - * the returned array doesn't contain the names of properties from - * prototype objects. - */ - V8EXPORT Local GetOwnPropertyNames(); - /** * Get the prototype object. This does not skip objects marked to * be skipped by __proto__ and it does not consult the security @@ -1518,7 +1577,6 @@ class Object : public Value { V8EXPORT void SetPointerInInternalField(int index, void* value); // Testers for local properties. - V8EXPORT bool HasOwnProperty(Handle key); V8EXPORT bool HasRealNamedProperty(Handle key); V8EXPORT bool HasRealIndexedProperty(uint32_t index); V8EXPORT bool HasRealNamedCallbackProperty(Handle key); @@ -1551,8 +1609,8 @@ class Object : public Value { V8EXPORT void TurnOnAccessCheck(); /** - * Returns the identity hash for this object. The current implementation - * uses a hidden property on the object to store the identity hash. + * Returns the identity hash for this object. The current implemenation uses + * a hidden property on the object to store the identity hash. * * The return value will never be 0. Also, it is not guaranteed to be * unique. @@ -1584,11 +1642,6 @@ class Object : public Value { */ V8EXPORT Local Clone(); - /** - * Returns the context in which the object was created. - */ - V8EXPORT Local CreationContext(); - /** * Set the backing store of the indexed properties to be managed by the * embedding layer. Access to the indexed properties will follow the rules @@ -1617,32 +1670,8 @@ class Object : public Value { V8EXPORT ExternalArrayType GetIndexedPropertiesExternalArrayDataType(); V8EXPORT int GetIndexedPropertiesExternalArrayDataLength(); - /** - * Checks whether a callback is set by the - * ObjectTemplate::SetCallAsFunctionHandler method. - * When an Object is callable this method returns true. - */ - V8EXPORT bool IsCallable(); - - /** - * Call an Object as a function if a callback is set by the - * ObjectTemplate::SetCallAsFunctionHandler method. - */ - V8EXPORT Local CallAsFunction(Handle recv, - int argc, - Handle argv[]); - - /** - * Call an Object as a constructor if a callback is set by the - * ObjectTemplate::SetCallAsFunctionHandler method. - * Note: This method behaves like the Function::NewInstance method. - */ - V8EXPORT Local CallAsConstructor(int argc, - Handle argv[]); - V8EXPORT static Local New(); static inline Object* Cast(Value* obj); - private: V8EXPORT Object(); V8EXPORT static void CheckCast(Value* obj); @@ -1670,12 +1699,7 @@ class Array : public Object { */ V8EXPORT Local CloneElementAt(uint32_t index); - /** - * Creates a JavaScript array with the given length. If the length - * is negative the returned array will have length 0. - */ V8EXPORT static Local New(int length = 0); - static inline Array* Cast(Value* obj); private: V8EXPORT Array(); @@ -1710,87 +1734,6 @@ class Function : public Object { }; -/** - * An instance of the built-in Date constructor (ECMA-262, 15.9). - */ -class Date : public Object { - public: - V8EXPORT static Local New(double time); - - /** - * A specialization of Value::NumberValue that is more efficient - * because we know the structure of this object. - */ - V8EXPORT double NumberValue() const; - - static inline Date* Cast(v8::Value* obj); - - /** - * Notification that the embedder has changed the time zone, - * daylight savings time, or other date / time configuration - * parameters. V8 keeps a cache of various values used for - * date / time computation. This notification will reset - * those cached values for the current context so that date / - * time configuration changes would be reflected in the Date - * object. - * - * This API should not be called more than needed as it will - * negatively impact the performance of date operations. - */ - V8EXPORT static void DateTimeConfigurationChangeNotification(); - - private: - V8EXPORT static void CheckCast(v8::Value* obj); -}; - - -/** - * An instance of the built-in RegExp constructor (ECMA-262, 15.10). - */ -class RegExp : public Object { - public: - /** - * Regular expression flag bits. They can be or'ed to enable a set - * of flags. - */ - enum Flags { - kNone = 0, - kGlobal = 1, - kIgnoreCase = 2, - kMultiline = 4 - }; - - /** - * Creates a regular expression from the given pattern string and - * the flags bit field. May throw a JavaScript exception as - * described in ECMA-262, 15.10.4.1. - * - * For example, - * RegExp::New(v8::String::New("foo"), - * static_cast(kGlobal | kMultiline)) - * is equivalent to evaluating "/foo/gm". - */ - V8EXPORT static Local New(Handle pattern, - Flags flags); - - /** - * Returns the value of the source property: a string representing - * the regular expression. - */ - V8EXPORT Local GetSource() const; - - /** - * Returns the flags bit field. - */ - V8EXPORT Flags GetFlags() const; - - static inline RegExp* Cast(v8::Value* obj); - - private: - V8EXPORT static void CheckCast(v8::Value* obj); -}; - - /** * A JavaScript value that wraps a C++ void*. This type of value is * mainly used to associate C++ data structures with JavaScript @@ -1818,7 +1761,7 @@ class External : public Value { }; -// --- Templates --- +// --- T e m p l a t e s --- /** @@ -2143,13 +2086,6 @@ class V8EXPORT FunctionTemplate : public Template { */ void SetHiddenPrototype(bool value); - /** - * Sets the property attributes of the 'prototype' property of functions - * created from this FunctionTemplate. Can be any combination of ReadOnly, - * DontEnum and DontDelete. - */ - void SetPrototypeAttributes(int attributes); - /** * Returns true if the given object is an instance of this function * template. @@ -2262,7 +2198,7 @@ class V8EXPORT ObjectTemplate : public Template { * * \param getter The callback to invoke when getting a property. * \param setter The callback to invoke when setting a property. - * \param query The callback to invoke to check if an object has a property. + * \param query The callback to invoke to check is an object has a property. * \param deleter The callback to invoke when deleting a property. * \param enumerator The callback to invoke to enumerate all the indexed * properties of an object. @@ -2359,7 +2295,7 @@ class V8EXPORT TypeSwitch : public Data { }; -// --- Extensions --- +// --- E x t e n s i o n s --- /** @@ -2411,7 +2347,7 @@ class V8EXPORT DeclareExtension { }; -// --- Statics --- +// --- S t a t i c s --- Handle V8EXPORT Undefined(); @@ -2452,7 +2388,7 @@ class V8EXPORT ResourceConstraints { bool V8EXPORT SetResourceConstraints(ResourceConstraints* constraints); -// --- Exceptions --- +// --- E x c e p t i o n s --- typedef void (*FatalErrorCallback)(const char* location, const char* message); @@ -2483,7 +2419,7 @@ class V8EXPORT Exception { }; -// --- Counters Callbacks --- +// --- C o u n t e r s C a l l b a c k s --- typedef int* (*CounterLookupCallback)(const char* name); @@ -2494,7 +2430,7 @@ typedef void* (*CreateHistogramCallback)(const char* name, typedef void (*AddHistogramSampleCallback)(void* histogram, int sample); -// --- Memory Allocation Callback --- +// --- M e m o r y A l l o c a t i o n C a l l b a c k --- enum ObjectSpace { kObjectSpaceNewSpace = 1 << 0, kObjectSpaceOldPointerSpace = 1 << 1, @@ -2518,20 +2454,12 @@ typedef void (*MemoryAllocationCallback)(ObjectSpace space, AllocationAction action, int size); -// --- Failed Access Check Callback --- +// --- F a i l e d A c c e s s C h e c k C a l l b a c k --- typedef void (*FailedAccessCheckCallback)(Local target, AccessType type, Local data); -// --- AllowCodeGenerationFromStrings callbacks --- - -/** - * Callback to check if code generation from strings is allowed. See - * Context::AllowCodeGenerationFromStrings. - */ -typedef bool (*AllowCodeGenerationFromStringsCallback)(Local context); - -// --- Garbage Collection Callbacks --- +// --- G a r b a g e C o l l e c t i o n C a l l b a c k s /** * Applications can register callback functions which will be called @@ -2557,6 +2485,23 @@ typedef void (*GCEpilogueCallback)(GCType type, GCCallbackFlags flags); typedef void (*GCCallback)(); +/** + * Profiler modules. + * + * In V8, profiler consists of several modules: CPU profiler, and different + * kinds of heap profiling. Each can be turned on / off independently. + * When PROFILER_MODULE_HEAP_SNAPSHOT flag is passed to ResumeProfilerEx, + * modules are enabled only temporarily for making a snapshot of the heap. + */ +enum ProfilerModules { + PROFILER_MODULE_NONE = 0, + PROFILER_MODULE_CPU = 1, + PROFILER_MODULE_HEAP_STATS = 1 << 1, + PROFILER_MODULE_JS_CONSTRUCTORS = 1 << 2, + PROFILER_MODULE_HEAP_SNAPSHOT = 1 << 16 +}; + + /** * Collection of V8 heap information. * @@ -2588,139 +2533,6 @@ class V8EXPORT HeapStatistics { }; -class RetainedObjectInfo; - -/** - * Isolate represents an isolated instance of the V8 engine. V8 - * isolates have completely separate states. Objects from one isolate - * must not be used in other isolates. When V8 is initialized a - * default isolate is implicitly created and entered. The embedder - * can create additional isolates and use them in parallel in multiple - * threads. An isolate can be entered by at most one thread at any - * given time. The Locker/Unlocker API can be used to synchronize. - */ -class V8EXPORT Isolate { - public: - /** - * Stack-allocated class which sets the isolate for all operations - * executed within a local scope. - */ - class V8EXPORT Scope { - public: - explicit Scope(Isolate* isolate) : isolate_(isolate) { - isolate->Enter(); - } - - ~Scope() { isolate_->Exit(); } - - private: - Isolate* const isolate_; - - // Prevent copying of Scope objects. - Scope(const Scope&); - Scope& operator=(const Scope&); - }; - - /** - * Creates a new isolate. Does not change the currently entered - * isolate. - * - * When an isolate is no longer used its resources should be freed - * by calling Dispose(). Using the delete operator is not allowed. - */ - static Isolate* New(); - - /** - * Returns the entered isolate for the current thread or NULL in - * case there is no current isolate. - */ - static Isolate* GetCurrent(); - - /** - * Methods below this point require holding a lock (using Locker) in - * a multi-threaded environment. - */ - - /** - * Sets this isolate as the entered one for the current thread. - * Saves the previously entered one (if any), so that it can be - * restored when exiting. Re-entering an isolate is allowed. - */ - void Enter(); - - /** - * Exits this isolate by restoring the previously entered one in the - * current thread. The isolate may still stay the same, if it was - * entered more than once. - * - * Requires: this == Isolate::GetCurrent(). - */ - void Exit(); - - /** - * Disposes the isolate. The isolate must not be entered by any - * thread to be disposable. - */ - void Dispose(); - - /** - * Associate embedder-specific data with the isolate - */ - void SetData(void* data); - - /** - * Retrive embedder-specific data from the isolate. - * Returns NULL if SetData has never been called. - */ - void* GetData(); - - private: - Isolate(); - Isolate(const Isolate&); - ~Isolate(); - Isolate& operator=(const Isolate&); - void* operator new(size_t size); - void operator delete(void*, size_t); -}; - - -class StartupData { - public: - enum CompressionAlgorithm { - kUncompressed, - kBZip2 - }; - - const char* data; - int compressed_size; - int raw_size; -}; - - -/** - * A helper class for driving V8 startup data decompression. It is based on - * "CompressedStartupData" API functions from the V8 class. It isn't mandatory - * for an embedder to use this class, instead, API functions can be used - * directly. - * - * For an example of the class usage, see the "shell.cc" sample application. - */ -class V8EXPORT StartupDataDecompressor { // NOLINT - public: - StartupDataDecompressor(); - virtual ~StartupDataDecompressor(); - int Decompress(); - - protected: - virtual int DecompressData(char* raw_data, - int* raw_data_size, - const char* compressed_data, - int compressed_data_size) = 0; - - private: - char** raw_data; -}; - /** * Container class for static utility functions. */ @@ -2729,13 +2541,6 @@ class V8EXPORT V8 { /** Set the callback to invoke in case of fatal errors. */ static void SetFatalErrorHandler(FatalErrorCallback that); - /** - * Set the callback to invoke to check if code generation from - * strings should be allowed. - */ - static void SetAllowCodeGenerationFromStringsCallback( - AllowCodeGenerationFromStringsCallback that); - /** * Ignore out-of-memory exceptions. * @@ -2743,7 +2548,7 @@ class V8EXPORT V8 { * This means that the fatal error handler is called and that V8 is * terminated. * - * IgnoreOutOfMemoryException can be used to not treat an + * IgnoreOutOfMemoryException can be used to not treat a * out-of-memory situation as a fatal error. This way, the contexts * that did not cause the out of memory problem might be able to * continue execution. @@ -2756,34 +2561,10 @@ class V8EXPORT V8 { */ static bool IsDead(); - /** - * The following 4 functions are to be used when V8 is built with - * the 'compress_startup_data' flag enabled. In this case, the - * embedder must decompress startup data prior to initializing V8. - * - * This is how interaction with V8 should look like: - * int compressed_data_count = v8::V8::GetCompressedStartupDataCount(); - * v8::StartupData* compressed_data = - * new v8::StartupData[compressed_data_count]; - * v8::V8::GetCompressedStartupData(compressed_data); - * ... decompress data (compressed_data can be updated in-place) ... - * v8::V8::SetDecompressedStartupData(compressed_data); - * ... now V8 can be initialized - * ... make sure the decompressed data stays valid until V8 shutdown - * - * A helper class StartupDataDecompressor is provided. It implements - * the protocol of the interaction described above, and can be used in - * most cases instead of calling these API functions directly. - */ - static StartupData::CompressionAlgorithm GetCompressedStartupDataAlgorithm(); - static int GetCompressedStartupDataCount(); - static void GetCompressedStartupData(StartupData* compressed_data); - static void SetDecompressedStartupData(StartupData* decompressed_data); - /** * Adds a message listener. * - * The same message listener can be added more than once and in that + * The same message listener can be added more than once and it that * case it will be called more than once for each message. */ static bool AddMessageListener(MessageCallback that, @@ -2921,22 +2702,8 @@ class V8EXPORT V8 { * intended to be used in the before-garbage-collection callback * function, for instance to simulate DOM tree connections among JS * wrapper objects. - * See v8-profiler.h for RetainedObjectInfo interface description. - */ - static void AddObjectGroup(Persistent* objects, - size_t length, - RetainedObjectInfo* info = NULL); - - /** - * Allows the host application to declare implicit references between - * the objects: if |parent| is alive, all |children| are alive too. - * After each garbage collection, all implicit references - * are removed. It is intended to be used in the before-garbage-collection - * callback function. */ - static void AddImplicitReferences(Persistent parent, - Persistent* children, - size_t length); + static void AddObjectGroup(Persistent* objects, size_t length); /** * Initializes from snapshot if possible. Otherwise, attempts to @@ -2983,6 +2750,40 @@ class V8EXPORT V8 { */ static bool IsProfilerPaused(); + /** + * Resumes specified profiler modules. Can be called several times to + * mark the opening of a profiler events block with the given tag. + * + * "ResumeProfiler" is equivalent to "ResumeProfilerEx(PROFILER_MODULE_CPU)". + * See ProfilerModules enum. + * + * \param flags Flags specifying profiler modules. + * \param tag Profile tag. + */ + static void ResumeProfilerEx(int flags, int tag = 0); + + /** + * Pauses specified profiler modules. Each call to "PauseProfilerEx" closes + * a block of profiler events opened by a call to "ResumeProfilerEx" with the + * same tag value. There is no need for blocks to be properly nested. + * The profiler is paused when the last opened block is closed. + * + * "PauseProfiler" is equivalent to "PauseProfilerEx(PROFILER_MODULE_CPU)". + * See ProfilerModules enum. + * + * \param flags Flags specifying profiler modules. + * \param tag Profile tag. + */ + static void PauseProfilerEx(int flags, int tag = 0); + + /** + * Returns active (resumed) profiler modules. + * See ProfilerModules enum. + * + * \returns active profiler modules. + */ + static int GetActiveProfilerModules(); + /** * If logging is performed into a memory buffer (via --logfile=*), allows to * retrieve previously written messages. This can be used for retrieving @@ -3029,7 +2830,7 @@ class V8EXPORT V8 { * The termination is achieved by throwing an exception that is * uncatchable by JavaScript exception handlers. Termination * exceptions act as if they were caught by a C++ TryCatch exception - * handler. If forceful termination is used, any C++ TryCatch + * handlers. If forceful termination is used, any C++ TryCatch * exception handler that catches an exception should check if that * exception is a termination exception and immediately return if * that is the case. Returning immediately in that case will @@ -3043,16 +2844,12 @@ class V8EXPORT V8 { static void TerminateExecution(int thread_id); /** - * Forcefully terminate the current thread of JavaScript execution - * in the given isolate. If no isolate is provided, the default - * isolate is used. + * Forcefully terminate the current thread of JavaScript execution. * * This method can be used by any thread even if that thread has not * acquired the V8 lock with a Locker object. - * - * \param isolate The isolate in which to terminate the current JS execution. */ - static void TerminateExecution(Isolate* isolate = NULL); + static void TerminateExecution(); /** * Is V8 terminating JavaScript execution. @@ -3061,10 +2858,8 @@ class V8EXPORT V8 { * because of a call to TerminateExecution. In that case there are * still JavaScript frames on the stack and the termination * exception is still active. - * - * \param isolate The isolate in which to check. */ - static bool IsExecutionTerminating(Isolate* isolate = NULL); + static bool IsExecutionTerminating(); /** * Releases any resources used by v8 and stops any utility threads @@ -3115,11 +2910,8 @@ class V8EXPORT V8 { void* data, WeakReferenceCallback); static void ClearWeak(internal::Object** global_handle); - static void MarkIndependent(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); template friend class Handle; template friend class Local; @@ -3133,6 +2925,7 @@ class V8EXPORT V8 { */ class V8EXPORT TryCatch { public: + /** * Creates a new try/catch block and registers it with v8. */ @@ -3224,7 +3017,6 @@ class V8EXPORT TryCatch { void SetCaptureMessage(bool value); private: - v8::internal::Isolate* isolate_; void* next_; void* exception_; void* message_; @@ -3233,11 +3025,11 @@ class V8EXPORT TryCatch { bool capture_message_ : 1; bool rethrow_ : 1; - friend class v8::internal::Isolate; + friend class v8::internal::Top; }; -// --- Context --- +// --- C o n t e x t --- /** @@ -3372,28 +3164,13 @@ class V8EXPORT Context { void SetData(Handle data); Local GetData(); - /** - * Control whether code generation from strings is allowed. Calling - * this method with false will disable 'eval' and the 'Function' - * constructor for code running in this context. If 'eval' or the - * 'Function' constructor are used an exception will be thrown. - * - * If code generation from strings is not allowed the - * V8::AllowCodeGenerationFromStrings callback will be invoked if - * set before blocking the call to 'eval' or the 'Function' - * constructor. If that callback returns true, the call will be - * allowed, otherwise an exception will be thrown. If no callback is - * set an exception will be thrown. - */ - void AllowCodeGenerationFromStrings(bool allow); - /** * Stack-allocated class which sets the execution context for all * operations executed within a local scope. */ class Scope { public: - explicit inline Scope(Handle context) : context_(context) { + inline Scope(Handle context) : context_(context) { context_->Enter(); } inline ~Scope() { context_->Exit(); } @@ -3411,44 +3188,37 @@ class V8EXPORT Context { /** * Multiple threads in V8 are allowed, but only one thread at a time - * is allowed to use any given V8 isolate. See Isolate class - * comments. The definition of 'using V8 isolate' includes - * accessing handles or holding onto object pointers obtained - * from V8 handles while in the particular V8 isolate. It is up - * to the user of V8 to ensure (perhaps with locking) that this - * constraint is not violated. + * is allowed to use V8. The definition of 'using V8' includes + * accessing handles or holding onto object pointers obtained from V8 + * handles. It is up to the user of V8 to ensure (perhaps with + * locking) that this constraint is not violated. * - * v8::Locker is a scoped lock object. While it's - * active (i.e. between its construction and destruction) the current thread is - * allowed to use the locked isolate. V8 guarantees that an isolate can be locked - * by at most one thread at any time. In other words, the scope of a v8::Locker is - * a critical section. + * If you wish to start using V8 in a thread you can do this by constructing + * a v8::Locker object. After the code using V8 has completed for the + * current thread you can call the destructor. This can be combined + * with C++ scope-based construction as follows: * - * Sample usage: -* \code + * \code * ... * { - * v8::Locker locker(isolate); - * v8::Isolate::Scope isolate_scope(isolate); + * v8::Locker locker; * ... - * // Code using V8 and isolate goes here. + * // Code using V8 goes here. * ... * } // Destructor called here * \endcode * - * If you wish to stop using V8 in a thread A you can do this either + * If you wish to stop using V8 in a thread A you can do this by either * by destroying the v8::Locker object as above or by constructing a * v8::Unlocker object: * * \code * { - * isolate->Exit(); - * v8::Unlocker unlocker(isolate); + * v8::Unlocker unlocker; * ... * // Code not using V8 goes here while V8 can run in another thread. * ... * } // Destructor called here. - * isolate->Enter(); * \endcode * * The Unlocker object is intended for use in a long-running callback @@ -3468,51 +3238,38 @@ class V8EXPORT Context { * \code * // V8 not locked. * { - * v8::Locker locker(isolate); - * Isolate::Scope isolate_scope(isolate); + * v8::Locker locker; * // V8 locked. * { - * v8::Locker another_locker(isolate); + * v8::Locker another_locker; * // V8 still locked (2 levels). * { - * isolate->Exit(); - * v8::Unlocker unlocker(isolate); + * v8::Unlocker unlocker; * // V8 not locked. * } - * isolate->Enter(); * // V8 locked again (2 levels). * } * // V8 still locked (1 level). * } * // V8 Now no longer locked. * \endcode - * - * */ class V8EXPORT Unlocker { public: - /** - * Initialize Unlocker for a given Isolate. NULL means default isolate. - */ - explicit Unlocker(Isolate* isolate = NULL); + Unlocker(); ~Unlocker(); - private: - internal::Isolate* isolate_; }; class V8EXPORT Locker { public: - /** - * Initialize Locker for a given Isolate. NULL means default isolate. - */ - explicit Locker(Isolate* isolate = NULL); + Locker(); ~Locker(); /** * Start preemption. * - * When preemption is started, a timer is fired every n milliseconds + * When preemption is started, a timer is fired every n milli seconds * that will switch between multiple threads that are in contention * for the V8 lock. */ @@ -3524,10 +3281,9 @@ class V8EXPORT Locker { static void StopPreemption(); /** - * Returns whether or not the locker for a given isolate, or default isolate if NULL is given, - * is locked by the current thread. + * Returns whether or not the locker is locked by the current thread. */ - static bool IsLocked(Isolate* isolate = NULL); + static bool IsLocked(); /** * Returns whether v8::Locker is being used by this V8 instance. @@ -3537,7 +3293,6 @@ class V8EXPORT Locker { private: bool has_lock_; bool top_level_; - internal::Isolate* isolate_; static bool active_; @@ -3594,7 +3349,7 @@ class V8EXPORT ActivityControl { // NOLINT }; -// --- Implementation --- +// --- I m p l e m e n t a t i o n --- namespace internal { @@ -3679,21 +3434,22 @@ template <> struct InternalConstants<8> { */ class Internals { public: + // These values match non-compiler-dependent values defined within // the implementation of v8. static const int kHeapObjectMapOffset = 0; - static const int kMapInstanceTypeOffset = 1 * kApiPointerSize + kApiIntSize; + static const int kMapInstanceTypeOffset = kApiPointerSize + kApiIntSize; static const int kStringResourceOffset = InternalConstants::kStringResourceOffset; - static const int kForeignAddressOffset = kApiPointerSize; + static const int kProxyProxyOffset = kApiPointerSize; static const int kJSObjectHeaderSize = 3 * kApiPointerSize; static const int kFullStringRepresentationMask = 0x07; static const int kExternalTwoByteRepresentationTag = 0x02; - static const int kJSObjectType = 0xa3; + static const int kJSObjectType = 0xa0; static const int kFirstNonstringType = 0x80; - static const int kForeignType = 0x85; + static const int kProxyType = 0x85; static inline bool HasHeapObjectTag(internal::Object* value) { return ((reinterpret_cast(value) & kHeapObjectTagMask) == @@ -3722,8 +3478,8 @@ class Internals { static inline void* GetExternalPointer(internal::Object* obj) { if (HasSmiTag(obj)) { return GetExternalPointerFromSmi(obj); - } else if (GetInstanceType(obj) == kForeignType) { - return ReadField(obj, kForeignAddressOffset); + } else if (GetInstanceType(obj) == kProxyType) { + return ReadField(obj, kProxyProxyOffset); } else { return NULL; } @@ -3739,14 +3495,6 @@ class Internals { uint8_t* addr = reinterpret_cast(ptr) + offset - kHeapObjectTag; return *reinterpret_cast(addr); } - - static inline bool CanCastToHeapObject(void* o) { return false; } - static inline bool CanCastToHeapObject(Context* o) { return true; } - static inline bool CanCastToHeapObject(String* o) { return true; } - static inline bool CanCastToHeapObject(Object* o) { return true; } - static inline bool CanCastToHeapObject(Message* o) { return true; } - static inline bool CanCastToHeapObject(StackTrace* o) { return true; } - static inline bool CanCastToHeapObject(StackFrame* o) { return true; } }; } // namespace internal @@ -3763,12 +3511,7 @@ Local::Local() : Handle() { } template Local Local::New(Handle that) { if (that.IsEmpty()) return Local(); - T* that_ptr = *that; - internal::Object** p = reinterpret_cast(that_ptr); - if (internal::Internals::CanCastToHeapObject(that_ptr)) { - return Local(reinterpret_cast(HandleScope::CreateHandle( - reinterpret_cast(*p)))); - } + internal::Object** p = reinterpret_cast(*that); return Local(reinterpret_cast(HandleScope::CreateHandle(*p))); } @@ -3817,15 +3560,6 @@ void Persistent::ClearWeak() { V8::ClearWeak(reinterpret_cast(**this)); } -template -void Persistent::MarkIndependent() { - V8::MarkIndependent(reinterpret_cast(**this)); -} - -template -void Persistent::SetWrapperClassId(uint16_t class_id) { - V8::SetWrapperClassId(reinterpret_cast(**this), class_id); -} Arguments::Arguments(internal::Object** implicit_args, internal::Object** values, int length, diff --git a/deps/v8/preparser/SConscript b/deps/v8/preparser/SConscript deleted file mode 100644 index 1d51e826cc8..00000000000 --- a/deps/v8/preparser/SConscript +++ /dev/null @@ -1,38 +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. - -from os.path import join -Import('context') - -def ConfigureObjectFiles(): - env = Environment() - env.Replace(**context.flags['preparser']) - context.ApplyEnvOverrides(env) - return env.Object('preparser-process.cc') - -preparser_object = ConfigureObjectFiles() -Return('preparser_object') diff --git a/deps/v8/preparser/preparser-process.cc b/deps/v8/preparser/preparser-process.cc index d7c96f0c735..26dfc42b53a 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 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: @@ -27,79 +27,105 @@ #include #include -#include -#include - #include "../include/v8stdint.h" #include "../include/v8-preparser.h" +#include "unicode-inl.h" -#include "../src/preparse-data-format.h" +enum ResultCode { kSuccess = 0, kErrorReading = 1, kErrorWriting = 2 }; -namespace i = v8::internal; +namespace v8 { +namespace internal { -// This file is only used for testing the stand-alone preparser -// library. -// The first argument must be the path of a JavaScript source file, or -// the flags "-e" and the next argument is then the source of a JavaScript -// program. -// Optionally this can be followed by the word "throws" (case sensitive), -// which signals that the parsing is expected to throw - the default is -// to expect the parsing to not throw. -// The command line can further be followed by a message text (the -// *type* of the exception to throw), and even more optionally, the -// start and end position reported with the exception. -// -// This source file is preparsed and tested against the expectations, and if -// successful, the resulting preparser data is written to stdout. -// Diagnostic output is output on stderr. -// The source file must contain only ASCII characters (UTF-8 isn't supported). -// The file is read into memory, so it should have a reasonable size. +// THIS FILE IS PROOF-OF-CONCEPT ONLY. +// The final goal is a stand-alone preparser library. -// Adapts an ASCII string to the UnicodeInputStream interface. -class AsciiInputStream : public v8::UnicodeInputStream { +class UTF8InputStream : public v8::UnicodeInputStream { public: - AsciiInputStream(const uint8_t* buffer, size_t length) + UTF8InputStream(uint8_t* buffer, size_t length) : buffer_(buffer), - end_offset_(static_cast(length)), - offset_(0) { } + offset_(0), + pos_(0), + end_offset_(static_cast(length)) { } - virtual ~AsciiInputStream() { } + virtual ~UTF8InputStream() { } virtual void PushBack(int32_t ch) { - offset_--; + // Pushback assumes that the character pushed back is the + // one that was most recently read, and jumps back in the + // UTF-8 stream by the length of that character's encoding. + offset_ -= unibrow::Utf8::Length(ch); + pos_--; #ifdef DEBUG - if (offset_ < 0 || - (ch != ((offset_ >= end_offset_) ? -1 : buffer_[offset_]))) { - fprintf(stderr, "Invalid pushback: '%c' at offset %d.", ch, offset_); - exit(1); + if (static_cast(ch) <= unibrow::Utf8::kMaxOneByteChar) { + if (ch != buffer_[offset_]) { + fprintf(stderr, "Invalid pushback: '%c'.", ch); + exit(1); + } + } else { + unsigned tmp = 0; + if (static_cast(ch) != + unibrow::Utf8::CalculateValue(buffer_ + offset_, + end_offset_ - offset_, + &tmp)) { + fprintf(stderr, "Invalid pushback: 0x%x.", ch); + exit(1); + } } #endif } virtual int32_t Next() { - if (offset_ >= end_offset_) { - offset_++; // Increment anyway to allow symmetric pushbacks. - return -1; - } - uint8_t next_char = buffer_[offset_]; -#ifdef DEBUG - if (next_char > 0x7fu) { - fprintf(stderr, "Non-ASCII character in input: '%c'.", next_char); - exit(1); + if (offset_ == end_offset_) return -1; + uint8_t first_char = buffer_[offset_]; + if (first_char <= unibrow::Utf8::kMaxOneByteChar) { + pos_++; + offset_++; + return static_cast(first_char); } -#endif - offset_++; - return static_cast(next_char); + unibrow::uchar codepoint = + unibrow::Utf8::CalculateValue(buffer_ + offset_, + end_offset_ - offset_, + &offset_); + pos_++; + return static_cast(codepoint); } private: const uint8_t* buffer_; - const int end_offset_; - int offset_; + unsigned offset_; + unsigned pos_; + unsigned end_offset_; }; +// Write a number to dest in network byte order. +void WriteUInt32(FILE* dest, uint32_t value, bool* ok) { + for (int i = 3; i >= 0; i--) { + uint8_t byte = static_cast(value >> (i << 3)); + int result = fputc(byte, dest); + if (result == EOF) { + *ok = false; + return; + } + } +} + +// Read number from FILE* in network byte order. +uint32_t ReadUInt32(FILE* source, bool* ok) { + uint32_t n = 0; + for (int i = 0; i < 4; i++) { + int c = fgetc(source); + if (c == EOF) { + *ok = false; + return 0; + } + n = (n << 8) + static_cast(c); + } + return n; +} + + bool ReadBuffer(FILE* source, void* buffer, size_t length) { size_t actually_read = fread(buffer, 1, length, source); return (actually_read == length); @@ -112,268 +138,69 @@ bool WriteBuffer(FILE* dest, const void* buffer, size_t length) { } -class PreparseDataInterpreter { - public: - PreparseDataInterpreter(const uint8_t* data, int length) - : data_(data), length_(length), message_(NULL) { } - - ~PreparseDataInterpreter() { - if (message_ != NULL) delete[] message_; - } - - bool valid() { - int header_length = - i::PreparseDataConstants::kHeaderSize * sizeof(int); // NOLINT - return length_ >= header_length; - } - - bool throws() { - return valid() && - word(i::PreparseDataConstants::kHasErrorOffset) != 0; - } - - const char* message() { - if (message_ != NULL) return message_; - if (!throws()) return NULL; - int text_pos = i::PreparseDataConstants::kHeaderSize + - i::PreparseDataConstants::kMessageTextPos; - int length = word(text_pos); - char* buffer = new char[length + 1]; - for (int i = 1; i <= length; i++) { - int character = word(text_pos + i); - buffer[i - 1] = character; - } - buffer[length] = '\0'; - message_ = buffer; - return buffer; - } - - int beg_pos() { - if (!throws()) return -1; - return word(i::PreparseDataConstants::kHeaderSize + - i::PreparseDataConstants::kMessageStartPos); - } - - int end_pos() { - if (!throws()) return -1; - return word(i::PreparseDataConstants::kHeaderSize + - i::PreparseDataConstants::kMessageEndPos); - } - - private: - int word(int offset) { - const int* word_data = reinterpret_cast(data_); - if (word_data + offset < reinterpret_cast(data_ + length_)) { - return word_data[offset]; - } - return -1; - } - - const uint8_t* const data_; - const int length_; - const char* message_; -}; - - template class ScopedPointer { public: - explicit ScopedPointer() : pointer_(NULL) {} explicit ScopedPointer(T* pointer) : pointer_(pointer) {} - ~ScopedPointer() { if (pointer_ != NULL) delete[] pointer_; } + ~ScopedPointer() { delete[] pointer_; } T& operator[](int index) { return pointer_[index]; } T* operator*() { return pointer_ ;} - T* operator=(T* new_value) { - if (pointer_ != NULL) delete[] pointer_; - pointer_ = new_value; - return new_value; - } private: T* pointer_; }; +// Preparse input and output result on stdout. +int PreParseIO(FILE* input) { + fprintf(stderr, "LOG: Enter parsing loop\n"); + bool ok = true; + uint32_t length = ReadUInt32(input, &ok); + fprintf(stderr, "LOG: Input length: %d\n", length); + if (!ok) return kErrorReading; + ScopedPointer buffer(new uint8_t[length]); -void fail(v8::PreParserData* data, const char* message, ...) { - va_list args; - va_start(args, message); - vfprintf(stderr, message, args); - va_end(args); - fflush(stderr); - // Print preparser data to stdout. - uint32_t size = data->size(); - fprintf(stderr, "LOG: data size: %u\n", size); - if (!WriteBuffer(stdout, data->data(), size)) { - perror("ERROR: Writing data"); - fflush(stderr); + if (!ReadBuffer(input, *buffer, length)) { + return kErrorReading; } - exit(EXIT_FAILURE); -}; - - -bool IsFlag(const char* arg) { - // Anything starting with '-' is considered a flag. - // It's summarily ignored for now. - return arg[0] == '-'; -} - + UTF8InputStream input_buffer(*buffer, static_cast(length)); -struct ExceptionExpectation { - ExceptionExpectation() - : throws(false), type(NULL), beg_pos(-1), end_pos(-1) { } - bool throws; - const char* type; - int beg_pos; - int end_pos; -}; - - -void CheckException(v8::PreParserData* data, - ExceptionExpectation* expects) { - PreparseDataInterpreter reader(data->data(), data->size()); - if (expects->throws) { - if (!reader.throws()) { - if (expects->type == NULL) { - fail(data, "Didn't throw as expected\n"); - } else { - fail(data, "Didn't throw \"%s\" as expected\n", expects->type); - } - } - if (expects->type != NULL) { - const char* actual_message = reader.message(); - if (strcmp(expects->type, actual_message)) { - fail(data, "Wrong error message. Expected <%s>, found <%s> at %d..%d\n", - expects->type, actual_message, reader.beg_pos(), reader.end_pos()); - } - } - if (expects->beg_pos >= 0) { - if (expects->beg_pos != reader.beg_pos()) { - fail(data, "Wrong error start position: Expected %i, found %i\n", - expects->beg_pos, reader.beg_pos()); - } - } - if (expects->end_pos >= 0) { - if (expects->end_pos != reader.end_pos()) { - fail(data, "Wrong error end position: Expected %i, found %i\n", - expects->end_pos, reader.end_pos()); - } - } - } else if (reader.throws()) { - const char* message = reader.message(); - fail(data, "Throws unexpectedly with message: %s at location %d-%d\n", - message, reader.beg_pos(), reader.end_pos()); + v8::PreParserData data = + v8::Preparse(&input_buffer, 64 * 1024 * sizeof(void*)); // NOLINT + if (data.stack_overflow()) { + fprintf(stderr, "LOG: Stack overflow\n"); + fflush(stderr); + // Report stack overflow error/no-preparser-data. + WriteUInt32(stdout, 0, &ok); + if (!ok) return kErrorWriting; + return 0; } -} - -ExceptionExpectation ParseExpectation(int argc, const char* argv[]) { - ExceptionExpectation expects; - - // Parse exception expectations from (the remainder of) the command line. - int arg_index = 0; - // Skip any flags. - while (argc > arg_index && IsFlag(argv[arg_index])) arg_index++; - if (argc > arg_index) { - if (strncmp("throws", argv[arg_index], 7)) { - // First argument after filename, if present, must be the verbatim - // "throws", marking that the preparsing should fail with an exception. - fail(NULL, "ERROR: Extra arguments not prefixed by \"throws\".\n"); - } - expects.throws = true; - do { - arg_index++; - } while (argc > arg_index && IsFlag(argv[arg_index])); - if (argc > arg_index) { - // Next argument is the exception type identifier. - expects.type = argv[arg_index]; - do { - arg_index++; - } while (argc > arg_index && IsFlag(argv[arg_index])); - if (argc > arg_index) { - expects.beg_pos = atoi(argv[arg_index]); // NOLINT - do { - arg_index++; - } while (argc > arg_index && IsFlag(argv[arg_index])); - if (argc > arg_index) { - expects.end_pos = atoi(argv[arg_index]); // NOLINT - } - } - } + uint32_t size = data.size(); + fprintf(stderr, "LOG: Success, data size: %u\n", size); + fflush(stderr); + WriteUInt32(stdout, size, &ok); + if (!ok) return kErrorWriting; + if (!WriteBuffer(stdout, data.data(), size)) { + return kErrorWriting; } - return expects; + return 0; } +} } // namespace v8::internal -int main(int argc, const char* argv[]) { - // Parse command line. - // Format: preparser ( | -e "") - // ["throws" [ [ []]]] - // Any flags (except an initial -s) are ignored. - - // Check for mandatory filename argument. - int arg_index = 1; - if (argc <= arg_index) { - fail(NULL, "ERROR: No filename on command line.\n"); - } - const uint8_t* source = NULL; - const char* filename = argv[arg_index]; - if (!strcmp(filename, "-e")) { - arg_index++; - if (argc <= arg_index) { - fail(NULL, "ERROR: No source after -e on command line.\n"); - } - source = reinterpret_cast(argv[arg_index]); - } - // Check remainder of command line for exception expectations. - arg_index++; - ExceptionExpectation expects = - ParseExpectation(argc - arg_index, argv + arg_index); - - ScopedPointer buffer; - size_t length; - - if (source == NULL) { - // Open JS file. - FILE* input = fopen(filename, "rb"); - if (input == NULL) { - perror("ERROR: Error opening file"); - fflush(stderr); - return EXIT_FAILURE; - } - // Find length of JS file. - if (fseek(input, 0, SEEK_END) != 0) { - perror("ERROR: Error during seek"); - fflush(stderr); - return EXIT_FAILURE; - } - length = static_cast(ftell(input)); - rewind(input); - // Read JS file into memory buffer. - buffer = new uint8_t[length]; - if (!ReadBuffer(input, *buffer, length)) { - perror("ERROR: Reading file"); - fflush(stderr); - return EXIT_FAILURE; - } - fclose(input); - source = *buffer; - } else { - length = strlen(reinterpret_cast(source)); - } - - // Preparse input file. - AsciiInputStream input_buffer(source, length); - size_t kMaxStackSize = 64 * 1024 * sizeof(void*); // NOLINT - v8::PreParserData data = v8::Preparse(&input_buffer, kMaxStackSize); - // Fail if stack overflow. - if (data.stack_overflow()) { - fail(&data, "ERROR: Stack overflow\n"); +int main(int argc, char* argv[]) { + FILE* input = stdin; + if (argc > 1) { + char* arg = argv[1]; + input = fopen(arg, "rb"); + if (input == NULL) return EXIT_FAILURE; } - - // Check that the expected exception is thrown, if an exception is - // expected. - CheckException(&data, &expects); - - return EXIT_SUCCESS; + int status = 0; + do { + status = v8::internal::PreParseIO(input); + } while (status == 0); + fprintf(stderr, "EXIT: Failure %d\n", status); + fflush(stderr); + return EXIT_FAILURE; } diff --git a/deps/v8/samples/process.cc b/deps/v8/samples/process.cc index 07c48057a5e..6be4ea542ac 100644 --- a/deps/v8/samples/process.cc +++ b/deps/v8/samples/process.cc @@ -30,10 +30,6 @@ #include #include -#ifdef COMPRESS_STARTUP_DATA_BZ2 -#error Using compressed startup data is not supported for this sample -#endif - using namespace std; using namespace v8; @@ -535,7 +531,7 @@ void ParseOptions(int argc, string* file) { for (int i = 1; i < argc; i++) { string arg = argv[i]; - size_t index = arg.find('=', 0); + int index = arg.find('=', 0); if (index == string::npos) { *file = arg; } else { diff --git a/deps/v8/samples/shell.cc b/deps/v8/samples/shell.cc index 7c30beccd5f..64f78f02c61 100644 --- a/deps/v8/samples/shell.cc +++ b/deps/v8/samples/shell.cc @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2009 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: @@ -28,36 +28,12 @@ #include #include #include -#ifdef COMPRESS_STARTUP_DATA_BZ2 -#include -#endif #include #include #include #include -// When building with V8 in a shared library we cannot use functions which -// is not explicitly a part of the public V8 API. This extensive use of -// #ifndef USING_V8_SHARED/#endif is a hack until we can resolve whether to -// still use the shell sample for testing or change to use the developer -// shell d8 TODO(1272). -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) -#include "../src/v8.h" -#endif // USING_V8_SHARED -#if !defined(_WIN32) && !defined(_WIN64) -#include // NOLINT -#endif - -static void ExitShell(int exit_code) { - // Use _exit instead of exit to avoid races between isolate - // threads and static destructors. - fflush(stdout); - fflush(stderr); - _exit(exit_code); -} - -v8::Persistent CreateShellContext(); void RunShell(v8::Handle context); bool ExecuteString(v8::Handle source, v8::Handle name, @@ -68,242 +44,62 @@ v8::Handle Read(const v8::Arguments& args); v8::Handle Load(const v8::Arguments& args); v8::Handle Quit(const v8::Arguments& args); v8::Handle Version(const v8::Arguments& args); -v8::Handle Int8Array(const v8::Arguments& args); -v8::Handle Uint8Array(const v8::Arguments& args); -v8::Handle Int16Array(const v8::Arguments& args); -v8::Handle Uint16Array(const v8::Arguments& args); -v8::Handle Int32Array(const v8::Arguments& args); -v8::Handle Uint32Array(const v8::Arguments& args); -v8::Handle Float32Array(const v8::Arguments& args); -v8::Handle Float64Array(const v8::Arguments& args); -v8::Handle PixelArray(const v8::Arguments& args); v8::Handle ReadFile(const char* name); void ReportException(v8::TryCatch* handler); -static bool last_run = true; - -class SourceGroup { - public: - SourceGroup() : -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) - next_semaphore_(v8::internal::OS::CreateSemaphore(0)), - done_semaphore_(v8::internal::OS::CreateSemaphore(0)), - thread_(NULL), -#endif // USING_V8_SHARED - argv_(NULL), - begin_offset_(0), - end_offset_(0) { } - - void Begin(char** argv, int offset) { - argv_ = const_cast(argv); - begin_offset_ = offset; - } - - void End(int offset) { end_offset_ = offset; } - - void Execute() { - for (int i = begin_offset_; i < end_offset_; ++i) { - const char* arg = argv_[i]; - if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) { - // Execute argument given to -e option directly. - v8::HandleScope handle_scope; - v8::Handle file_name = v8::String::New("unnamed"); - v8::Handle source = v8::String::New(argv_[i + 1]); - if (!ExecuteString(source, file_name, false, true)) { - ExitShell(1); - return; - } - ++i; - } else if (arg[0] == '-') { - // Ignore other options. They have been parsed already. - } else { - // Use all other arguments as names of files to load and run. - v8::HandleScope handle_scope; - v8::Handle file_name = v8::String::New(arg); - v8::Handle source = ReadFile(arg); - if (source.IsEmpty()) { - printf("Error reading '%s'\n", arg); - continue; - } - if (!ExecuteString(source, file_name, false, true)) { - ExitShell(1); - return; - } - } - } - } - -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) - void StartExecuteInThread() { - if (thread_ == NULL) { - thread_ = new IsolateThread(this); - thread_->Start(); - } - next_semaphore_->Signal(); - } - - void WaitForThread() { - if (thread_ == NULL) return; - if (last_run) { - thread_->Join(); - thread_ = NULL; - } else { - done_semaphore_->Wait(); - } - } -#endif // USING_V8_SHARED - - private: -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) - static v8::internal::Thread::Options GetThreadOptions() { - v8::internal::Thread::Options options; - options.name = "IsolateThread"; - // On some systems (OSX 10.6) the stack size default is 0.5Mb or less - // which is not enough to parse the big literal expressions used in tests. - // The stack size should be at least StackGuard::kLimitSize + some - // OS-specific padding for thread startup code. - options.stack_size = 2 << 20; // 2 Mb seems to be enough - return options; - } - - class IsolateThread : public v8::internal::Thread { - public: - explicit IsolateThread(SourceGroup* group) - : v8::internal::Thread(GetThreadOptions()), group_(group) {} - - virtual void Run() { - group_->ExecuteInThread(); - } - - private: - SourceGroup* group_; - }; - - void ExecuteInThread() { - v8::Isolate* isolate = v8::Isolate::New(); - do { - if (next_semaphore_ != NULL) next_semaphore_->Wait(); - { - v8::Isolate::Scope iscope(isolate); - v8::HandleScope scope; - v8::Persistent context = CreateShellContext(); - { - v8::Context::Scope cscope(context); - Execute(); - } - context.Dispose(); - } - if (done_semaphore_ != NULL) done_semaphore_->Signal(); - } while (!last_run); - isolate->Dispose(); - } - - v8::internal::Semaphore* next_semaphore_; - v8::internal::Semaphore* done_semaphore_; - v8::internal::Thread* thread_; -#endif // USING_V8_SHARED - - const char** argv_; - int begin_offset_; - int end_offset_; -}; - - -static SourceGroup* isolate_sources = NULL; - - -#ifdef COMPRESS_STARTUP_DATA_BZ2 -class BZip2Decompressor : public v8::StartupDataDecompressor { - public: - virtual ~BZip2Decompressor() { } - - protected: - virtual int DecompressData(char* raw_data, - int* raw_data_size, - const char* compressed_data, - int compressed_data_size) { - ASSERT_EQ(v8::StartupData::kBZip2, - v8::V8::GetCompressedStartupDataAlgorithm()); - unsigned int decompressed_size = *raw_data_size; - int result = - BZ2_bzBuffToBuffDecompress(raw_data, - &decompressed_size, - const_cast(compressed_data), - compressed_data_size, - 0, 1); - if (result == BZ_OK) { - *raw_data_size = decompressed_size; - } - return result; - } -}; -#endif - - int RunMain(int argc, char* argv[]) { - v8::V8::SetFlagsFromCommandLine(&argc, argv, true); v8::HandleScope handle_scope; - v8::Persistent context = CreateShellContext(); - // Enter the newly created execution environment. - context->Enter(); - if (context.IsEmpty()) { - printf("Error creating context\n"); - return 1; - } - + // Create a template for the global object. + v8::Handle global = v8::ObjectTemplate::New(); + // Bind the global 'print' function to the C++ Print callback. + global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print)); + // Bind the global 'read' function to the C++ Read callback. + global->Set(v8::String::New("read"), v8::FunctionTemplate::New(Read)); + // Bind the global 'load' function to the C++ Load callback. + global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load)); + // Bind the 'quit' function + global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit)); + // Bind the 'version' function + global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version)); + // Create a new execution environment containing the built-in + // functions + v8::Persistent context = v8::Context::New(NULL, global); bool run_shell = (argc == 1); - int num_isolates = 1; for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--isolate") == 0) { -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) - ++num_isolates; -#else // USING_V8_SHARED - printf("Error: --isolate not supported when linked with shared " - "library\n"); - ExitShell(1); -#endif // USING_V8_SHARED - } - } - if (isolate_sources == NULL) { - isolate_sources = new SourceGroup[num_isolates]; - SourceGroup* current = isolate_sources; - current->Begin(argv, 1); - for (int i = 1; i < argc; i++) { - const char* str = argv[i]; - if (strcmp(str, "--isolate") == 0) { - current->End(i); - current++; - current->Begin(argv, i + 1); - } else if (strcmp(str, "--shell") == 0) { - run_shell = true; - } else if (strcmp(str, "-f") == 0) { - // Ignore any -f flags for compatibility with the other stand- - // alone JavaScript engines. - continue; - } else if (strncmp(str, "--", 2) == 0) { - printf("Warning: unknown flag %s.\nTry --help for options\n", str); + // Enter the execution environment before evaluating any code. + v8::Context::Scope context_scope(context); + const char* str = argv[i]; + if (strcmp(str, "--shell") == 0) { + run_shell = true; + } else if (strcmp(str, "-f") == 0) { + // Ignore any -f flags for compatibility with the other stand- + // alone JavaScript engines. + continue; + } 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) { + // Execute argument given to -e option directly + v8::HandleScope handle_scope; + v8::Handle file_name = v8::String::New("unnamed"); + v8::Handle source = v8::String::New(argv[i + 1]); + if (!ExecuteString(source, file_name, false, true)) + return 1; + i++; + } else { + // Use all other arguments as names of files to load and run. + v8::HandleScope handle_scope; + v8::Handle file_name = v8::String::New(str); + v8::Handle source = ReadFile(str); + if (source.IsEmpty()) { + printf("Error reading '%s'\n", str); + return 1; } + if (!ExecuteString(source, file_name, false, true)) + return 1; } - current->End(argc); } -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) - for (int i = 1; i < num_isolates; ++i) { - isolate_sources[i].StartExecuteInThread(); - } -#endif // USING_V8_SHARED - isolate_sources[0].Execute(); if (run_shell) RunShell(context); -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) - for (int i = 1; i < num_isolates; ++i) { - isolate_sources[i].WaitForThread(); - } -#endif // USING_V8_SHARED - if (last_run) { - delete[] isolate_sources; - isolate_sources = NULL; - } - context->Exit(); context.Dispose(); return 0; } @@ -330,15 +126,6 @@ int main(int argc, char* argv[]) { } } -#ifdef COMPRESS_STARTUP_DATA_BZ2 - BZip2Decompressor startup_data_decompressor; - int bz2_result = startup_data_decompressor.Decompress(); - if (bz2_result != BZ_OK) { - fprintf(stderr, "bzip error code: %d\n", bz2_result); - exit(1); - } -#endif - v8::V8::SetFlagsFromCommandLine(&argc, argv, true); int result = 0; if (FLAG_stress_opt || FLAG_stress_deopt) { @@ -350,16 +137,12 @@ int main(int argc, char* argv[]) { printf("============ Stress %d/%d ============\n", i + 1, stress_runs); v8::Testing::PrepareStressRun(i); - last_run = (i == stress_runs - 1); result = RunMain(argc, argv); } - printf("======== Full Deoptimization =======\n"); - v8::Testing::DeoptimizeAll(); } else { result = RunMain(argc, argv); } v8::V8::Dispose(); - return result; } @@ -370,46 +153,6 @@ const char* ToCString(const v8::String::Utf8Value& value) { } -// Creates a new execution environment containing the built-in -// functions. -v8::Persistent CreateShellContext() { - // Create a template for the global object. - v8::Handle global = v8::ObjectTemplate::New(); - // Bind the global 'print' function to the C++ Print callback. - global->Set(v8::String::New("print"), v8::FunctionTemplate::New(Print)); - // Bind the global 'read' function to the C++ Read callback. - global->Set(v8::String::New("read"), v8::FunctionTemplate::New(Read)); - // Bind the global 'load' function to the C++ Load callback. - global->Set(v8::String::New("load"), v8::FunctionTemplate::New(Load)); - // Bind the 'quit' function - global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(Quit)); - // Bind the 'version' function - global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version)); - - // Bind the handlers for external arrays. - global->Set(v8::String::New("Int8Array"), - v8::FunctionTemplate::New(Int8Array)); - global->Set(v8::String::New("Uint8Array"), - v8::FunctionTemplate::New(Uint8Array)); - global->Set(v8::String::New("Int16Array"), - v8::FunctionTemplate::New(Int16Array)); - global->Set(v8::String::New("Uint16Array"), - v8::FunctionTemplate::New(Uint16Array)); - global->Set(v8::String::New("Int32Array"), - v8::FunctionTemplate::New(Int32Array)); - global->Set(v8::String::New("Uint32Array"), - v8::FunctionTemplate::New(Uint32Array)); - global->Set(v8::String::New("Float32Array"), - v8::FunctionTemplate::New(Float32Array)); - global->Set(v8::String::New("Float64Array"), - v8::FunctionTemplate::New(Float64Array)); - global->Set(v8::String::New("PixelArray"), - v8::FunctionTemplate::New(PixelArray)); - - return v8::Context::New(NULL, global); -} - - // The callback that is invoked by v8 whenever the JavaScript 'print' // function is called. Prints its arguments on stdout separated by // spaces and ending with a newline. @@ -479,7 +222,7 @@ v8::Handle Quit(const v8::Arguments& args) { // If not arguments are given args[0] will yield undefined which // converts to the integer value 0. int exit_code = args[0]->Int32Value(); - ExitShell(exit_code); + exit(exit_code); return v8::Undefined(); } @@ -489,113 +232,6 @@ v8::Handle Version(const v8::Arguments& args) { } -void ExternalArrayWeakCallback(v8::Persistent object, void* data) { - free(data); - object.Dispose(); -} - - -v8::Handle CreateExternalArray(const v8::Arguments& args, - v8::ExternalArrayType type, - size_t element_size) { - assert(element_size == 1 || - element_size == 2 || - element_size == 4 || - element_size == 8); - if (args.Length() != 1) { - return v8::ThrowException( - v8::String::New("Array constructor needs one parameter.")); - } - static const int kMaxLength = 0x3fffffff; - size_t length = 0; - if (args[0]->IsUint32()) { - length = args[0]->Uint32Value(); - } else if (args[0]->IsNumber()) { - double raw_length = args[0]->NumberValue(); - if (raw_length < 0) { - return v8::ThrowException( - v8::String::New("Array length must not be negative.")); - } - if (raw_length > kMaxLength) { - return v8::ThrowException( - v8::String::New("Array length exceeds maximum length.")); - } - length = static_cast(raw_length); - } else { - return v8::ThrowException( - v8::String::New("Array length must be a number.")); - } - if (length > static_cast(kMaxLength)) { - return v8::ThrowException( - v8::String::New("Array length exceeds maximum length.")); - } - void* data = calloc(length, element_size); - if (data == NULL) { - return v8::ThrowException(v8::String::New("Memory allocation failed.")); - } - v8::Handle array = v8::Object::New(); - v8::Persistent persistent_array = - v8::Persistent::New(array); - persistent_array.MakeWeak(data, ExternalArrayWeakCallback); - persistent_array.MarkIndependent(); - array->SetIndexedPropertiesToExternalArrayData(data, type, length); - array->Set(v8::String::New("length"), v8::Int32::New(length), - v8::ReadOnly); - array->Set(v8::String::New("BYTES_PER_ELEMENT"), - v8::Int32::New(element_size)); - return array; -} - - -v8::Handle Int8Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t)); -} - - -v8::Handle Uint8Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalUnsignedByteArray, - sizeof(uint8_t)); -} - - -v8::Handle Int16Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalShortArray, sizeof(int16_t)); -} - - -v8::Handle Uint16Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalUnsignedShortArray, - sizeof(uint16_t)); -} - -v8::Handle Int32Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalIntArray, sizeof(int32_t)); -} - - -v8::Handle Uint32Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalUnsignedIntArray, - sizeof(uint32_t)); -} - - -v8::Handle Float32Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalFloatArray, - sizeof(float)); // NOLINT -} - - -v8::Handle Float64Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalDoubleArray, - sizeof(double)); // NOLINT -} - - -v8::Handle PixelArray(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalPixelArray, sizeof(uint8_t)); -} - - // Reads a file into a v8 string. v8::Handle ReadFile(const char* name) { FILE* file = fopen(name, "rb"); diff --git a/deps/v8/src/SConscript b/deps/v8/src/SConscript index 5b2f272a52c..598e4af56ef 100755 --- a/deps/v8/src/SConscript +++ b/deps/v8/src/SConscript @@ -68,6 +68,7 @@ SOURCES = { execution.cc factory.cc flags.cc + frame-element.cc frames.cc full-codegen.cc func-name-inferrer.cc @@ -84,8 +85,8 @@ SOURCES = { ic.cc inspector.cc interpreter-irregexp.cc - isolate.cc jsregexp.cc + jump-target.cc lithium-allocator.cc lithium.cc liveedit.cc @@ -105,6 +106,7 @@ SOURCES = { regexp-macro-assembler-irregexp.cc regexp-macro-assembler.cc regexp-stack.cc + register-allocator.cc rewriter.cc runtime.cc runtime-profiler.cc @@ -121,6 +123,7 @@ SOURCES = { strtod.cc stub-cache.cc token.cc + top.cc type-info.cc unicode.cc utils.cc @@ -129,11 +132,14 @@ SOURCES = { v8threads.cc variables.cc version.cc + virtual-frame.cc zone.cc extensions/gc-extension.cc extensions/externalize-string-extension.cc """), 'arch:arm': Split(""" + jump-target-light.cc + virtual-frame-light.cc arm/builtins-arm.cc arm/code-stubs-arm.cc arm/codegen-arm.cc @@ -145,32 +151,37 @@ SOURCES = { arm/frames-arm.cc arm/full-codegen-arm.cc arm/ic-arm.cc + arm/jump-target-arm.cc arm/lithium-arm.cc arm/lithium-codegen-arm.cc arm/lithium-gap-resolver-arm.cc arm/macro-assembler-arm.cc arm/regexp-macro-assembler-arm.cc + arm/register-allocator-arm.cc arm/stub-cache-arm.cc + arm/virtual-frame-arm.cc arm/assembler-arm.cc """), 'arch:mips': Split(""" mips/assembler-mips.cc mips/builtins-mips.cc - mips/code-stubs-mips.cc mips/codegen-mips.cc mips/constants-mips.cc mips/cpu-mips.cc mips/debug-mips.cc - mips/deoptimizer-mips.cc mips/disasm-mips.cc - mips/frames-mips.cc mips/full-codegen-mips.cc + mips/frames-mips.cc mips/ic-mips.cc + mips/jump-target-mips.cc mips/macro-assembler-mips.cc - mips/regexp-macro-assembler-mips.cc + mips/register-allocator-mips.cc mips/stub-cache-mips.cc + mips/virtual-frame-mips.cc """), 'arch:ia32': Split(""" + jump-target-heavy.cc + virtual-frame-heavy.cc ia32/assembler-ia32.cc ia32/builtins-ia32.cc ia32/code-stubs-ia32.cc @@ -182,14 +193,19 @@ SOURCES = { ia32/frames-ia32.cc ia32/full-codegen-ia32.cc ia32/ic-ia32.cc + ia32/jump-target-ia32.cc ia32/lithium-codegen-ia32.cc ia32/lithium-gap-resolver-ia32.cc ia32/lithium-ia32.cc ia32/macro-assembler-ia32.cc ia32/regexp-macro-assembler-ia32.cc + ia32/register-allocator-ia32.cc ia32/stub-cache-ia32.cc + ia32/virtual-frame-ia32.cc """), 'arch:x64': Split(""" + jump-target-heavy.cc + virtual-frame-heavy.cc x64/assembler-x64.cc x64/builtins-x64.cc x64/code-stubs-x64.cc @@ -201,12 +217,15 @@ SOURCES = { x64/frames-x64.cc x64/full-codegen-x64.cc x64/ic-x64.cc + x64/jump-target-x64.cc x64/lithium-codegen-x64.cc x64/lithium-gap-resolver-x64.cc x64/lithium-x64.cc x64/macro-assembler-x64.cc x64/regexp-macro-assembler-x64.cc + x64/register-allocator-x64.cc x64/stub-cache-x64.cc + x64/virtual-frame-x64.cc """), 'simulator:arm': ['arm/simulator-arm.cc'], 'simulator:mips': ['mips/simulator-mips.cc'], @@ -226,20 +245,6 @@ SOURCES = { } -PREPARSER_SOURCES = { - 'all': Split(""" - allocation.cc - hashmap.cc - preparse-data.cc - preparser.cc - preparser-api.cc - scanner-base.cc - token.cc - unicode.cc - """) -} - - D8_FILES = { 'all': [ 'd8.cc', 'd8-debug.cc' @@ -295,11 +300,6 @@ debug-debugger.js '''.split() -EXPERIMENTAL_LIBRARY_FILES = ''' -proxy.js -'''.split() - - def Abort(message): print message sys.exit(1) @@ -310,22 +310,13 @@ def ConfigureObjectFiles(): env.Replace(**context.flags['v8']) context.ApplyEnvOverrides(env) env['BUILDERS']['JS2C'] = Builder(action=js2c.JS2C) - if 'ENABLE_LOGGING_AND_PROFILING' in env['CPPDEFINES']: - env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET --logfile "$LOGFILE" --log-snapshot-positions') - else: - env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET') - - def BuildJS2CEnv(type): - js2c_env = { 'TYPE': type, 'COMPRESSION': 'off' } - if 'COMPRESS_STARTUP_DATA_BZ2' in env['CPPDEFINES']: - js2c_env['COMPRESSION'] = 'bz2' - return js2c_env + env['BUILDERS']['Snapshot'] = Builder(action='$SOURCE $TARGET --logfile "$LOGFILE" --log-snapshot-positions') # Build the standard platform-independent source files. source_files = context.GetRelevantSources(SOURCES) d8_files = context.GetRelevantSources(D8_FILES) - d8_js = env.JS2C('d8-js.cc', 'd8.js', **{'TYPE': 'D8', 'COMPRESSION': 'off'}) + d8_js = env.JS2C('d8-js.cc', 'd8.js', TYPE='D8') d8_js_obj = context.ConfigureObject(env, d8_js, CPPPATH=['.']) d8_objs = [context.ConfigureObject(env, [d8_files]), d8_js_obj] @@ -333,25 +324,12 @@ def ConfigureObjectFiles(): # compile it. library_files = [s for s in LIBRARY_FILES] library_files.append('macros.py') - libraries_src = env.JS2C( - ['libraries.cc'], library_files, **BuildJS2CEnv('CORE')) + libraries_src, libraries_empty_src = env.JS2C(['libraries.cc', 'libraries-empty.cc'], library_files, TYPE='CORE') libraries_obj = context.ConfigureObject(env, libraries_src, CPPPATH=['.']) - # Combine the experimental JavaScript library files into a C++ file - # and compile it. - experimental_library_files = [ s for s in EXPERIMENTAL_LIBRARY_FILES ] - experimental_library_files.append('macros.py') - experimental_libraries_src = env.JS2C(['experimental-libraries.cc'], - experimental_library_files, - **BuildJS2CEnv('EXPERIMENTAL')) - experimental_libraries_obj = context.ConfigureObject(env, experimental_libraries_src, CPPPATH=['.']) - source_objs = context.ConfigureObject(env, source_files) non_snapshot_files = [source_objs] - preparser_source_files = context.GetRelevantSources(PREPARSER_SOURCES) - preparser_objs = context.ConfigureObject(env, preparser_source_files) - # Create snapshot if necessary. For cross compilation you should either # do without snapshots and take the performance hit or you should build a # host VM with the simulator=arm and snapshot=on options and then take the @@ -362,7 +340,7 @@ def ConfigureObjectFiles(): mksnapshot_env = env.Copy() mksnapshot_env.Replace(**context.flags['mksnapshot']) mksnapshot_src = 'mksnapshot.cc' - mksnapshot = mksnapshot_env.Program('mksnapshot', [mksnapshot_src, libraries_obj, experimental_libraries_obj, non_snapshot_files, empty_snapshot_obj], PDB='mksnapshot.exe.pdb') + mksnapshot = mksnapshot_env.Program('mksnapshot', [mksnapshot_src, libraries_obj, non_snapshot_files, empty_snapshot_obj], PDB='mksnapshot.exe.pdb') if context.use_snapshot: if context.build_snapshot: snapshot_cc = env.Snapshot('snapshot.cc', mksnapshot, LOGFILE=File('snapshot.log').abspath) @@ -371,9 +349,9 @@ def ConfigureObjectFiles(): snapshot_obj = context.ConfigureObject(env, snapshot_cc, CPPPATH=['.']) else: snapshot_obj = empty_snapshot_obj - library_objs = [non_snapshot_files, libraries_obj, experimental_libraries_obj, snapshot_obj] - return (library_objs, d8_objs, [mksnapshot], preparser_objs) + library_objs = [non_snapshot_files, libraries_obj, snapshot_obj] + return (library_objs, d8_objs, [mksnapshot]) -(library_objs, d8_objs, mksnapshot, preparser_objs) = ConfigureObjectFiles() -Return('library_objs d8_objs mksnapshot preparser_objs') +(library_objs, d8_objs, mksnapshot) = ConfigureObjectFiles() +Return('library_objs d8_objs mksnapshot') diff --git a/deps/v8/src/accessors.cc b/deps/v8/src/accessors.cc index 806c679f4bc..8cbdc09edf8 100644 --- a/deps/v8/src/accessors.cc +++ b/deps/v8/src/accessors.cc @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2006-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: @@ -32,9 +32,9 @@ #include "deoptimizer.h" #include "execution.h" #include "factory.h" -#include "list-inl.h" #include "safepoint-table.h" #include "scopeinfo.h" +#include "top.h" namespace v8 { namespace internal { @@ -43,9 +43,8 @@ namespace internal { template static C* FindInPrototypeChain(Object* obj, bool* found_it) { ASSERT(!*found_it); - Heap* heap = HEAP; while (!Is(obj)) { - if (obj == heap->null_value()) return NULL; + if (obj == Heap::null_value()) return NULL; obj = obj->GetPrototype(); } *found_it = true; @@ -91,34 +90,24 @@ 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()-> - has_initial_map()); - Map* number_map = Isolate::Current()->context()->global_context()-> - number_function()->initial_map(); + ASSERT( + Top::context()->global_context()->number_function()->has_initial_map()); + Map* number_map = + Top::context()->global_context()->number_function()->initial_map(); if (wrapper->map() == number_map) return wrapper->value(); return value; } MaybeObject* Accessors::ArraySetLength(JSObject* object, Object* value, void*) { - Isolate* isolate = object->GetIsolate(); - - // This means one of the object's prototypes is a JSArray and the - // object does not have a 'length' property. Calling SetProperty - // causes an infinite loop. - if (!object->IsJSArray()) { - return object->SetLocalPropertyIgnoreAttributes( - isolate->heap()->length_symbol(), value, NONE); - } - value = FlattenNumber(value); // Need to call methods that may trigger GC. - HandleScope scope(isolate); + HandleScope scope; // Protect raw pointers. - Handle object_handle(object, isolate); - Handle value_handle(value, isolate); + Handle object_handle(object); + Handle value_handle(value); bool has_exception; Handle uint32_v = Execution::ToUint32(value_handle, &has_exception); @@ -126,12 +115,23 @@ MaybeObject* Accessors::ArraySetLength(JSObject* object, Object* value, void*) { Handle number_v = Execution::ToNumber(value_handle, &has_exception); if (has_exception) return Failure::Exception(); + // Restore raw pointers, + object = *object_handle; + value = *value_handle; + if (uint32_v->Number() == number_v->Number()) { - return Handle::cast(object_handle)->SetElementsLength(*uint32_v); + if (object->IsJSArray()) { + return JSArray::cast(object)->SetElementsLength(*uint32_v); + } else { + // This means one of the object's prototypes is a JSArray and + // the object does not have a 'length' property. + // Calling SetProperty causes an infinite loop. + return object->SetLocalPropertyIgnoreAttributes(Heap::length_symbol(), + value, NONE); + } } - return isolate->Throw( - *isolate->factory()->NewRangeError("invalid_array_length", - HandleVector(NULL, 0))); + return Top::Throw(*Factory::NewRangeError("invalid_array_length", + HandleVector(NULL, 0))); } @@ -314,18 +314,15 @@ const AccessorDescriptor Accessors::ScriptCompilationType = { MaybeObject* Accessors::ScriptGetLineEnds(Object* object, void*) { - JSValue* wrapper = JSValue::cast(object); - Isolate* isolate = wrapper->GetIsolate(); - HandleScope scope(isolate); - Handle