aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2012-04-12 10:51:47 +0100
committerBen Murdoch <benm@google.com>2012-04-16 16:41:38 +0100
commit3ef787dbeca8a5fb1086949cda830dccee07bfbd (patch)
tree0a22edd97aa148abffdd405c585b22213fccbc82 /test
parent85b71799222b55eb5dd74ea26efe0c64ab655c8c (diff)
downloadv8-3ef787dbeca8a5fb1086949cda830dccee07bfbd.tar.gz
Merge V8 at 3.9.24.13
Bug: 5688872 Change-Id: Id0aa8d23375030494d3189c31774059c0f5398fc
Diffstat (limited to 'test')
-rw-r--r--test/cctest/SConscript7
-rw-r--r--test/cctest/cctest.gyp14
-rw-r--r--test/cctest/cctest.h2
-rw-r--r--test/cctest/cctest.status21
-rw-r--r--test/cctest/test-accessors.cc2
-rw-r--r--test/cctest/test-alloc.cc48
-rw-r--r--test/cctest/test-api.cc1631
-rw-r--r--test/cctest/test-assembler-ia32.cc94
-rw-r--r--test/cctest/test-assembler-mips.cc27
-rw-r--r--test/cctest/test-assembler-x64.cc95
-rw-r--r--test/cctest/test-ast.cc5
-rw-r--r--test/cctest/test-compiler.cc14
-rw-r--r--test/cctest/test-cpu-profiler.cc4
-rw-r--r--test/cctest/test-dataflow.cc31
-rw-r--r--test/cctest/test-date.cc168
-rw-r--r--test/cctest/test-debug.cc209
-rw-r--r--test/cctest/test-decls.cc40
-rw-r--r--test/cctest/test-deoptimization.cc135
-rw-r--r--test/cctest/test-dictionary.cc69
-rw-r--r--test/cctest/test-disasm-arm.cc14
-rw-r--r--test/cctest/test-disasm-ia32.cc53
-rw-r--r--test/cctest/test-disasm-mips.cc110
-rw-r--r--test/cctest/test-disasm-x64.cc429
-rw-r--r--test/cctest/test-heap-profiler.cc439
-rw-r--r--test/cctest/test-heap.cc544
-rw-r--r--test/cctest/test-lockers.cc89
-rw-r--r--test/cctest/test-log-stack-tracer.cc1
-rw-r--r--test/cctest/test-log.cc2
-rw-r--r--test/cctest/test-mark-compact.cc141
-rwxr-xr-xtest/cctest/test-parsing.cc452
-rw-r--r--test/cctest/test-platform-linux.cc2
-rw-r--r--test/cctest/test-platform-win32.cc2
-rw-r--r--test/cctest/test-profile-generator.cc2
-rw-r--r--test/cctest/test-random.cc109
-rw-r--r--test/cctest/test-regexp.cc10
-rw-r--r--test/cctest/test-reloc-info.cc2
-rw-r--r--test/cctest/test-serialize.cc49
-rw-r--r--test/cctest/test-sockets.cc2
-rw-r--r--test/cctest/test-spaces.cc111
-rw-r--r--test/cctest/test-strings.cc33
-rw-r--r--test/cctest/test-threads.cc22
-rw-r--r--test/cctest/test-utils.cc2
-rw-r--r--test/cctest/test-weakmaps.cc35
-rw-r--r--test/es5conform/es5conform.status39
-rw-r--r--test/message/message.status7
-rw-r--r--test/mjsunit/apply.js7
-rw-r--r--test/mjsunit/array-construct-transition.js39
-rw-r--r--test/mjsunit/array-join.js10
-rw-r--r--test/mjsunit/array-literal-transitions.js210
-rw-r--r--test/mjsunit/array-store-and-grow.js183
-rw-r--r--test/mjsunit/array-tostring.js159
-rw-r--r--test/mjsunit/assert-opt-and-deopt.js6
-rw-r--r--test/mjsunit/bugs/bug-618.js2
-rw-r--r--test/mjsunit/bugs/harmony/debug-blockscopes.js2
-rw-r--r--test/mjsunit/builtins.js5
-rw-r--r--test/mjsunit/comparison-ops-and-undefined.js128
-rw-r--r--test/mjsunit/compiler/alloc-object-huge.js308
-rw-r--r--test/mjsunit/compiler/alloc-object.js90
-rw-r--r--test/mjsunit/compiler/compare.js4
-rw-r--r--test/mjsunit/compiler/inline-arguments.js90
-rw-r--r--test/mjsunit/compiler/inline-arity-mismatch.js62
-rw-r--r--test/mjsunit/compiler/inline-construct.js152
-rw-r--r--test/mjsunit/compiler/inline-context-slots.js49
-rw-r--r--test/mjsunit/compiler/inline-literals.js50
-rw-r--r--test/mjsunit/compiler/lazy-const-lookup.js (renamed from test/mjsunit/regress/regress-221.js)17
-rw-r--r--test/mjsunit/compiler/literals-optimized.js121
-rw-r--r--test/mjsunit/compiler/math-floor-global.js161
-rw-r--r--test/mjsunit/compiler/math-floor-local.js161
-rw-r--r--test/mjsunit/compiler/optimized-for-in.js300
-rw-r--r--test/mjsunit/compiler/regress-96989.js (renamed from test/mjsunit/cyclic-error-to-string.js)29
-rw-r--r--test/mjsunit/compiler/regress-deopt-call-as-function.js62
-rw-r--r--test/mjsunit/compiler/regress-funarguments.js20
-rw-r--r--test/mjsunit/compiler/regress-inline-callfunctionstub.js46
-rw-r--r--test/mjsunit/compiler/regress-toint32.js45
-rw-r--r--test/mjsunit/compiler/strict-recompile.js51
-rw-r--r--test/mjsunit/const-redecl.js62
-rw-r--r--test/mjsunit/count-based-osr.js38
-rw-r--r--test/mjsunit/d8-os.js130
-rw-r--r--test/mjsunit/date.js16
-rw-r--r--test/mjsunit/debug-break-inline.js100
-rw-r--r--test/mjsunit/debug-evaluate-locals-optimized-double.js189
-rw-r--r--test/mjsunit/debug-evaluate-locals-optimized.js175
-rw-r--r--test/mjsunit/debug-scopes.js49
-rw-r--r--test/mjsunit/debug-set-script-source.js64
-rw-r--r--test/mjsunit/debug-step-3.js94
-rw-r--r--test/mjsunit/debug-stepin-accessor.js4
-rw-r--r--test/mjsunit/debug-stepin-function-call.js17
-rw-r--r--test/mjsunit/debug-stepout-scope.js423
-rw-r--r--test/mjsunit/element-kind.js102
-rw-r--r--test/mjsunit/elements-kind-depends.js74
-rw-r--r--test/mjsunit/elements-kind.js346
-rw-r--r--test/mjsunit/elements-transition-hoisting.js211
-rw-r--r--test/mjsunit/elements-transition.js113
-rw-r--r--test/mjsunit/error-tostring.js85
-rw-r--r--test/mjsunit/eval.js49
-rw-r--r--test/mjsunit/external-array.js80
-rw-r--r--test/mjsunit/function-bind.js197
-rw-r--r--test/mjsunit/function-call.js6
-rw-r--r--test/mjsunit/function-named-self-reference.js45
-rw-r--r--test/mjsunit/fuzz-natives.js8
-rw-r--r--test/mjsunit/get-own-property-descriptor.js2
-rw-r--r--test/mjsunit/getter-in-value-prototype.js2
-rw-r--r--test/mjsunit/global-const-var-conflicts.js10
-rw-r--r--test/mjsunit/harmony/block-conflicts.js12
-rw-r--r--test/mjsunit/harmony/block-const-assign.js131
-rw-r--r--test/mjsunit/harmony/block-early-errors.js55
-rw-r--r--test/mjsunit/harmony/block-for.js146
-rw-r--r--test/mjsunit/harmony/block-leave.js84
-rw-r--r--test/mjsunit/harmony/block-let-crankshaft.js203
-rw-r--r--test/mjsunit/harmony/block-let-declaration.js80
-rw-r--r--test/mjsunit/harmony/block-let-semantics.js60
-rw-r--r--test/mjsunit/harmony/block-scoping.js59
-rw-r--r--test/mjsunit/harmony/collections.js314
-rw-r--r--test/mjsunit/harmony/debug-blockscopes.js148
-rw-r--r--test/mjsunit/harmony/debug-evaluate-blockscopes.js10
-rw-r--r--test/mjsunit/harmony/module-parsing.js159
-rw-r--r--test/mjsunit/harmony/module-resolution.js139
-rw-r--r--test/mjsunit/harmony/proxies-example-membrane.js512
-rw-r--r--test/mjsunit/harmony/proxies-for.js168
-rw-r--r--test/mjsunit/harmony/proxies-function.js748
-rw-r--r--test/mjsunit/harmony/proxies-hash.js122
-rw-r--r--test/mjsunit/harmony/proxies.js1000
-rw-r--r--test/mjsunit/harmony/weakmaps.js167
-rw-r--r--test/mjsunit/math-min-max.js72
-rw-r--r--test/mjsunit/math-pow.js257
-rw-r--r--test/mjsunit/mjsunit.js4
-rw-r--r--test/mjsunit/mjsunit.status56
-rw-r--r--test/mjsunit/number-is.js58
-rw-r--r--test/mjsunit/object-define-properties.js16
-rw-r--r--test/mjsunit/object-define-property.js37
-rw-r--r--test/mjsunit/object-is.js47
-rw-r--r--test/mjsunit/object-prevent-extensions.js12
-rw-r--r--test/mjsunit/optimized-typeof.js47
-rw-r--r--test/mjsunit/pixel-array-rounding.js44
-rw-r--r--test/mjsunit/regexp-capture-3.js30
-rw-r--r--test/mjsunit/regexp-static.js17
-rw-r--r--test/mjsunit/regexp.js17
-rw-r--r--test/mjsunit/regress/regress-100702.js44
-rw-r--r--test/mjsunit/regress/regress-102153.js57
-rw-r--r--test/mjsunit/regress/regress-108296.js52
-rw-r--r--test/mjsunit/regress/regress-109195.js65
-rw-r--r--test/mjsunit/regress/regress-110509.js41
-rw-r--r--test/mjsunit/regress/regress-1110.js5
-rw-r--r--test/mjsunit/regress/regress-113924.js31
-rw-r--r--test/mjsunit/regress/regress-115452.js48
-rw-r--r--test/mjsunit/regress/regress-1170.js2
-rw-r--r--test/mjsunit/regress/regress-117794.js57
-rw-r--r--test/mjsunit/regress/regress-119429.js37
-rw-r--r--test/mjsunit/regress/regress-119925.js34
-rw-r--r--test/mjsunit/regress/regress-1213575.js11
-rw-r--r--test/mjsunit/regress/regress-121407.js40
-rw-r--r--test/mjsunit/regress/regress-1217.js50
-rw-r--r--test/mjsunit/regress/regress-1229.js109
-rw-r--r--test/mjsunit/regress/regress-1415.js42
-rw-r--r--test/mjsunit/regress/regress-1530.js69
-rw-r--r--test/mjsunit/regress/regress-1624-strict.js140
-rw-r--r--test/mjsunit/regress/regress-1624.js139
-rw-r--r--test/mjsunit/regress/regress-1639-2.js93
-rw-r--r--test/mjsunit/regress/regress-1692.js89
-rw-r--r--test/mjsunit/regress/regress-1708.js63
-rw-r--r--test/mjsunit/regress/regress-1711.js38
-rw-r--r--test/mjsunit/regress/regress-1713.js127
-rw-r--r--test/mjsunit/regress/regress-1748.js35
-rw-r--r--test/mjsunit/regress/regress-1757.js32
-rw-r--r--test/mjsunit/regress/regress-1790.js58
-rw-r--r--test/mjsunit/regress/regress-1849.js39
-rw-r--r--test/mjsunit/regress/regress-1853.js116
-rw-r--r--test/mjsunit/regress/regress-1878.js44
-rw-r--r--test/mjsunit/regress/regress-1898.js37
-rw-r--r--test/mjsunit/regress/regress-1924.js42
-rw-r--r--test/mjsunit/regress/regress-1945.js34
-rw-r--r--test/mjsunit/regress/regress-1969.js5045
-rw-r--r--test/mjsunit/regress/regress-1973.js52
-rw-r--r--test/mjsunit/regress/regress-1980.js40
-rw-r--r--test/mjsunit/regress/regress-2045.js49
-rw-r--r--test/mjsunit/regress/regress-2056.js66
-rw-r--r--test/mjsunit/regress/regress-397.js17
-rw-r--r--test/mjsunit/regress/regress-877615.js12
-rw-r--r--test/mjsunit/regress/regress-91517.js112
-rw-r--r--test/mjsunit/regress/regress-94873.js78
-rw-r--r--test/mjsunit/regress/regress-95113.js2
-rw-r--r--test/mjsunit/regress/regress-98773.js39
-rw-r--r--test/mjsunit/regress/regress-99167.js33
-rw-r--r--test/mjsunit/regress/regress-crbug-100859.js39
-rw-r--r--test/mjsunit/regress/regress-crbug-107996.js64
-rw-r--r--test/mjsunit/regress/regress-crbug-119926.js33
-rw-r--r--test/mjsunit/regress/regress-debug-code-recompilation.js47
-rw-r--r--test/mjsunit/regress/regress-deopt-gc.js2
-rw-r--r--test/mjsunit/regress/regress-inlining-function-literal-context.js53
-rw-r--r--test/mjsunit/regress/regress-smi-only-concat.js37
-rw-r--r--test/mjsunit/regress/regress-sqrt.js47
-rw-r--r--test/mjsunit/regress/short-circuit.js32
-rw-r--r--test/mjsunit/stack-traces-2.js87
-rw-r--r--test/mjsunit/stack-traces.js58
-rw-r--r--test/mjsunit/strict-mode-implicit-receiver.js7
-rw-r--r--test/mjsunit/strict-mode.js6
-rw-r--r--test/mjsunit/string-external-cached.js121
-rw-r--r--test/mjsunit/string-externalize.js2
-rw-r--r--test/mjsunit/string-replace-one-char.js92
-rw-r--r--test/mjsunit/string-slices-regexp.js7
-rwxr-xr-xtest/mjsunit/string-slices.js72
-rw-r--r--test/mjsunit/switch.js173
-rw-r--r--test/mjsunit/to_number_order.js4
-rw-r--r--test/mjsunit/tools/tickprocessor.js7
-rw-r--r--test/mjsunit/unbox-double-arrays.js55
-rw-r--r--test/mjsunit/undeletable-functions.js42
-rw-r--r--test/mozilla/mozilla.status95
-rw-r--r--test/preparser/preparser.status6
-rw-r--r--test/preparser/strict-identifiers.pyt55
-rw-r--r--test/sputnik/sputnik.status98
-rw-r--r--test/test262/README4
-rw-r--r--test/test262/test262.status1404
-rw-r--r--test/test262/testcfg.py63
213 files changed, 22157 insertions, 3728 deletions
diff --git a/test/cctest/SConscript b/test/cctest/SConscript
index 5c926718..bcd1e987 100644
--- a/test/cctest/SConscript
+++ b/test/cctest/SConscript
@@ -1,4 +1,4 @@
-# Copyright 2008 the V8 project authors. All rights reserved.
+# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
@@ -62,6 +62,7 @@ SOURCES = {
'test-conversions.cc',
'test-cpu-profiler.cc',
'test-dataflow.cc',
+ 'test-date.cc',
'test-debug.cc',
'test-decls.cc',
'test-deoptimization.cc',
@@ -86,6 +87,7 @@ SOURCES = {
'test-parsing.cc',
'test-platform-tls.cc',
'test-profile-generator.cc',
+ 'test-random.cc',
'test-regexp.cc',
'test-reloc-info.cc',
'test-serialize.cc',
@@ -111,7 +113,8 @@ SOURCES = {
],
'arch:x64': ['test-assembler-x64.cc',
'test-macro-assembler-x64.cc',
- 'test-log-stack-tracer.cc'],
+ 'test-log-stack-tracer.cc',
+ 'test-disasm-x64.cc'],
'arch:mips': ['test-assembler-mips.cc',
'test-disasm-mips.cc'],
'os:linux': ['test-platform-linux.cc'],
diff --git a/test/cctest/cctest.gyp b/test/cctest/cctest.gyp
index 5d0cab3e..a242fe3c 100644
--- a/test/cctest/cctest.gyp
+++ b/test/cctest/cctest.gyp
@@ -1,4 +1,4 @@
-# Copyright 2011 the V8 project authors. All rights reserved.
+# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
@@ -57,6 +57,7 @@
'test-conversions.cc',
'test-cpu-profiler.cc',
'test-dataflow.cc',
+ 'test-date.cc',
'test-debug.cc',
'test-decls.cc',
'test-deoptimization.cc',
@@ -68,6 +69,7 @@
'test-fixed-dtoa.cc',
'test-flags.cc',
'test-func-name-inference.cc',
+ 'test-hashing.cc',
'test-hashmap.cc',
'test-heap.cc',
'test-heap-profiler.cc',
@@ -80,6 +82,7 @@
'test-parsing.cc',
'test-platform-tls.cc',
'test-profile-generator.cc',
+ 'test-random.cc',
'test-regexp.cc',
'test-reloc-info.cc',
'test-serialize.cc',
@@ -91,7 +94,8 @@
'test-threads.cc',
'test-unbound-queue.cc',
'test-utils.cc',
- 'test-version.cc'
+ 'test-version.cc',
+ 'test-weakmaps.cc'
],
'conditions': [
['v8_target_arch=="ia32"', {
@@ -134,6 +138,12 @@
'sources': [
'test-platform-win32.cc',
],
+ 'msvs_settings': {
+ 'VCCLCompilerTool': {
+ # MSVS wants this for gay-{precision,shortest}.cc.
+ 'AdditionalOptions': ['/bigobj'],
+ },
+ },
}],
['component=="shared_library"', {
# cctest can't be built against a shared library, so we need to
diff --git a/test/cctest/cctest.h b/test/cctest/cctest.h
index c04d893c..0b935622 100644
--- a/test/cctest/cctest.h
+++ b/test/cctest/cctest.h
@@ -104,7 +104,7 @@ class ApiTestFuzzer: public v8::internal::Thread {
FOURTH_PART,
LAST_PART = FOURTH_PART };
- static void Setup(PartOfTest part);
+ static void SetUp(PartOfTest part);
static void RunAllTests();
static void TearDown();
// This method switches threads if we are running the Threading test.
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 5122da5a..af28be19 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -33,11 +33,22 @@ test-api/Bug*: FAIL
# BUG(382): Weird test. Can't guarantee that it never times out.
test-api/ApplyInterruption: PASS || TIMEOUT
+# BUG(484): This test which we thought was originally corrected in r5236
+# is re-appearing. Disabled until bug in test is fixed. This only fails
+# when snapshot is on, so I am marking it PASS || FAIL
+test-heap-profiler/HeapSnapshotsDiff: PASS || FAIL
+
# These tests always fail. They are here to test test.py. If
# they don't fail then test.py has failed.
test-serialize/TestThatAlwaysFails: FAIL
test-serialize/DependentTestThatAlwaysFails: FAIL
+# TODO(gc): Temporarily disabled in the GC branch.
+test-log/EquivalenceOfLoggingAndTraversal: PASS || FAIL
+
+# BUG(1261): Flakey test.
+test-profile-generator/RecordStackTraceAtStartProfiling: PASS || FAIL
+
# We do not yet shrink weak maps after they have been emptied by the GC
test-weakmaps/Shrinking: FAIL
@@ -73,10 +84,8 @@ test-debug/DebugBreakLoop: SKIP
##############################################################################
-[ $arch == mips ]
-test-deoptimization: SKIP
-test-serialize: SKIP
+[ $arch == mips && $crankshaft ]
-# Tests that may time out.
-test-api/ExternalArrays: PASS || TIMEOUT
-test-api/Threading: PASS || TIMEOUT
+# Tests that time out with crankshaft.
+test-debug/ThreadedDebugging: SKIP
+test-debug/DebugBreakLoop: SKIP
diff --git a/test/cctest/test-accessors.cc b/test/cctest/test-accessors.cc
index d95536d2..b1900f9e 100644
--- a/test/cctest/test-accessors.cc
+++ b/test/cctest/test-accessors.cc
@@ -241,7 +241,7 @@ static v8::Handle<Value> CheckAccessorArgsCorrect(Local<String> name,
ApiTestFuzzer::Fuzz();
CHECK(info.This() == info.Holder());
CHECK(info.Data()->Equals(v8::String::New("data")));
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK(info.This() == info.Holder());
CHECK(info.Data()->Equals(v8::String::New("data")));
return v8::Integer::New(17);
diff --git a/test/cctest/test-alloc.cc b/test/cctest/test-alloc.cc
index 97671923..769fe7be 100644
--- a/test/cctest/test-alloc.cc
+++ b/test/cctest/test-alloc.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 the V8 project authors. All rights reserved.
+// 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:
@@ -72,11 +72,29 @@ static MaybeObject* AllocateAfterFailures() {
}
CHECK(!heap->AllocateRawAsciiString(100, TENURED)->IsFailure());
+ // Old pointer space.
+ OldSpace* old_pointer_space = heap->old_pointer_space();
+ static const int kOldPointerSpaceFillerLength = 10000;
+ static const int kOldPointerSpaceFillerSize = FixedArray::SizeFor(
+ kOldPointerSpaceFillerLength);
+ while (old_pointer_space->Available() > kOldPointerSpaceFillerSize) {
+ CHECK(!heap->AllocateFixedArray(kOldPointerSpaceFillerLength, TENURED)->
+ IsFailure());
+ }
+ CHECK(!heap->AllocateFixedArray(kOldPointerSpaceFillerLength, TENURED)->
+ IsFailure());
+
// Large object space.
- while (!heap->OldGenerationAllocationLimitReached()) {
- CHECK(!heap->AllocateFixedArray(10000, TENURED)->IsFailure());
+ static const int kLargeObjectSpaceFillerLength = 300000;
+ static const int kLargeObjectSpaceFillerSize = FixedArray::SizeFor(
+ kLargeObjectSpaceFillerLength);
+ ASSERT(kLargeObjectSpaceFillerSize > heap->old_pointer_space()->AreaSize());
+ while (heap->OldGenerationSpaceAvailable() > kLargeObjectSpaceFillerSize) {
+ CHECK(!heap->AllocateFixedArray(kLargeObjectSpaceFillerLength, TENURED)->
+ IsFailure());
}
- CHECK(!heap->AllocateFixedArray(10000, TENURED)->IsFailure());
+ CHECK(!heap->AllocateFixedArray(kLargeObjectSpaceFillerLength, TENURED)->
+ IsFailure());
// Map space.
MapSpace* map_space = heap->map_space();
@@ -175,20 +193,20 @@ unsigned int Pseudorandom() {
// Plain old data class. Represents a block of allocated memory.
class Block {
public:
- Block(void* base_arg, int size_arg)
+ Block(Address base_arg, int size_arg)
: base(base_arg), size(size_arg) {}
- void *base;
+ Address base;
int size;
};
TEST(CodeRange) {
- const int code_range_size = 16*MB;
- OS::Setup();
+ const int code_range_size = 32*MB;
+ OS::SetUp();
Isolate::Current()->InitializeLoggingAndCounters();
CodeRange* code_range = new CodeRange(Isolate::Current());
- code_range->Setup(code_range_size);
+ code_range->SetUp(code_range_size);
int current_allocated = 0;
int total_allocated = 0;
List<Block> blocks(1000);
@@ -196,11 +214,15 @@ TEST(CodeRange) {
while (total_allocated < 5 * code_range_size) {
if (current_allocated < code_range_size / 10) {
// Allocate a block.
- // Geometrically distributed sizes, greater than Page::kPageSize.
- size_t requested = (Page::kPageSize << (Pseudorandom() % 6)) +
- Pseudorandom() % 5000 + 1;
+ // Geometrically distributed sizes, greater than
+ // Page::kMaxNonCodeHeapObjectSize (which is greater than code page area).
+ // TODO(gc): instead of using 3 use some contant based on code_range_size
+ // kMaxHeapObjectSize.
+ size_t requested =
+ (Page::kMaxNonCodeHeapObjectSize << (Pseudorandom() % 3)) +
+ Pseudorandom() % 5000 + 1;
size_t allocated = 0;
- void* base = code_range->AllocateRawMemory(requested, &allocated);
+ Address base = code_range->AllocateRawMemory(requested, &allocated);
CHECK(base != NULL);
blocks.Add(Block(base, static_cast<int>(allocated)));
current_allocated += static_cast<int>(allocated);
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index c1c8aae5..b1a23c1e 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -80,6 +80,11 @@ static void ExpectString(const char* code, const char* expected) {
CHECK_EQ(expected, *ascii);
}
+static void ExpectInt32(const char* code, int expected) {
+ Local<Value> result = CompileRun(code);
+ CHECK(result->IsInt32());
+ CHECK_EQ(expected, result->Int32Value());
+}
static void ExpectBoolean(const char* code, bool expected) {
Local<Value> result = CompileRun(code);
@@ -393,11 +398,11 @@ THREADED_TEST(ScriptUsingStringResource) {
CHECK(source->IsExternal());
CHECK_EQ(resource,
static_cast<TestResource*>(source->GetExternalStringResource()));
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(0, dispose_count);
}
v8::internal::Isolate::Current()->compilation_cache()->Clear();
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllAvailableGarbage();
CHECK_EQ(1, dispose_count);
}
@@ -415,11 +420,11 @@ THREADED_TEST(ScriptUsingAsciiStringResource) {
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(0, dispose_count);
}
i::Isolate::Current()->compilation_cache()->Clear();
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllAvailableGarbage();
CHECK_EQ(1, dispose_count);
}
@@ -441,11 +446,11 @@ THREADED_TEST(ScriptMakingExternalString) {
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(0, dispose_count);
}
i::Isolate::Current()->compilation_cache()->Clear();
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
CHECK_EQ(1, dispose_count);
}
@@ -467,11 +472,11 @@ THREADED_TEST(ScriptMakingExternalAsciiString) {
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(0, dispose_count);
}
i::Isolate::Current()->compilation_cache()->Clear();
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
CHECK_EQ(1, dispose_count);
}
@@ -484,7 +489,7 @@ TEST(MakingExternalStringConditions) {
HEAP->CollectGarbage(i::NEW_SPACE);
HEAP->CollectGarbage(i::NEW_SPACE);
- uint16_t* two_byte_string = AsciiToTwoByteString("small");
+ uint16_t* two_byte_string = AsciiToTwoByteString("s1");
Local<String> small_string = String::New(two_byte_string);
i::DeleteArray(two_byte_string);
@@ -496,7 +501,7 @@ TEST(MakingExternalStringConditions) {
// Old space strings should be accepted.
CHECK(small_string->CanMakeExternal());
- two_byte_string = AsciiToTwoByteString("small 2");
+ two_byte_string = AsciiToTwoByteString("small string 2");
small_string = String::New(two_byte_string);
i::DeleteArray(two_byte_string);
@@ -530,7 +535,7 @@ TEST(MakingExternalAsciiStringConditions) {
HEAP->CollectGarbage(i::NEW_SPACE);
HEAP->CollectGarbage(i::NEW_SPACE);
- Local<String> small_string = String::New("small");
+ Local<String> small_string = String::New("s1");
// We should refuse to externalize newly created small string.
CHECK(!small_string->CanMakeExternal());
// Trigger GCs so that the newly allocated string moves to old gen.
@@ -539,7 +544,7 @@ TEST(MakingExternalAsciiStringConditions) {
// Old space strings should be accepted.
CHECK(small_string->CanMakeExternal());
- small_string = String::New("small 2");
+ small_string = String::New("small string 2");
// We should refuse externalizing newly created small string.
CHECK(!small_string->CanMakeExternal());
for (int i = 0; i < 100; i++) {
@@ -572,8 +577,8 @@ THREADED_TEST(UsingExternalString) {
i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring);
CHECK(isymbol->IsSymbol());
}
- HEAP->CollectAllGarbage(false);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
@@ -590,8 +595,8 @@ THREADED_TEST(UsingExternalAsciiString) {
i::Handle<i::String> isymbol = FACTORY->SymbolFromString(istring);
CHECK(isymbol->IsSymbol());
}
- HEAP->CollectAllGarbage(false);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
@@ -672,11 +677,11 @@ TEST(ExternalStringWithDisposeHandling) {
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count);
}
i::Isolate::Current()->compilation_cache()->Clear();
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllAvailableGarbage();
CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls);
CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count);
@@ -693,11 +698,11 @@ TEST(ExternalStringWithDisposeHandling) {
Local<Value> value = script->Run();
CHECK(value->IsNumber());
CHECK_EQ(7, value->Int32Value());
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllAvailableGarbage();
CHECK_EQ(0, TestAsciiResourceWithDisposeControl::dispose_count);
}
i::Isolate::Current()->compilation_cache()->Clear();
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllAvailableGarbage();
CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_calls);
CHECK_EQ(1, TestAsciiResourceWithDisposeControl::dispose_count);
}
@@ -744,8 +749,8 @@ THREADED_TEST(StringConcat) {
CHECK_EQ(68, value->Int32Value());
}
i::Isolate::Current()->compilation_cache()->Clear();
- HEAP->CollectAllGarbage(false);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
@@ -1182,9 +1187,8 @@ THREADED_TEST(GlobalPrototype) {
templ->Set("x", v8_num(200));
templ->SetAccessor(v8_str("m"), GetM);
LocalContext env(0, templ);
- v8::Handle<v8::Object> obj = env->Global();
- v8::Handle<Script> script = v8_compile("dummy()");
- v8::Handle<Value> result = script->Run();
+ v8::Handle<Script> script(v8_compile("dummy()"));
+ v8::Handle<Value> result(script->Run());
CHECK_EQ(13.4, result->NumberValue());
CHECK_EQ(200, v8_compile("x")->Run()->Int32Value());
CHECK_EQ(876, v8_compile("m")->Run()->Int32Value());
@@ -1294,6 +1298,279 @@ static v8::Handle<Value> EchoNamedProperty(Local<String> name,
return name;
}
+// Helper functions for Interceptor/Accessor interaction tests
+
+Handle<Value> SimpleAccessorGetter(Local<String> name,
+ const AccessorInfo& info) {
+ Handle<Object> self = info.This();
+ return self->Get(String::Concat(v8_str("accessor_"), name));
+}
+
+void SimpleAccessorSetter(Local<String> name, Local<Value> value,
+ const AccessorInfo& info) {
+ Handle<Object> self = info.This();
+ self->Set(String::Concat(v8_str("accessor_"), name), value);
+}
+
+Handle<Value> EmptyInterceptorGetter(Local<String> name,
+ const AccessorInfo& info) {
+ return Handle<Value>();
+}
+
+Handle<Value> EmptyInterceptorSetter(Local<String> name,
+ Local<Value> value,
+ const AccessorInfo& info) {
+ return Handle<Value>();
+}
+
+Handle<Value> InterceptorGetter(Local<String> name,
+ const AccessorInfo& info) {
+ // Intercept names that start with 'interceptor_'.
+ String::AsciiValue ascii(name);
+ char* name_str = *ascii;
+ char prefix[] = "interceptor_";
+ int i;
+ for (i = 0; name_str[i] && prefix[i]; ++i) {
+ if (name_str[i] != prefix[i]) return Handle<Value>();
+ }
+ Handle<Object> self = info.This();
+ return self->GetHiddenValue(v8_str(name_str + i));
+}
+
+Handle<Value> InterceptorSetter(Local<String> name,
+ Local<Value> value,
+ const AccessorInfo& info) {
+ // Intercept accesses that set certain integer values.
+ if (value->IsInt32() && value->Int32Value() < 10000) {
+ Handle<Object> self = info.This();
+ self->SetHiddenValue(name, value);
+ return value;
+ }
+ return Handle<Value>();
+}
+
+void AddAccessor(Handle<FunctionTemplate> templ,
+ Handle<String> name,
+ v8::AccessorGetter getter,
+ v8::AccessorSetter setter) {
+ templ->PrototypeTemplate()->SetAccessor(name, getter, setter);
+}
+
+void AddInterceptor(Handle<FunctionTemplate> templ,
+ v8::NamedPropertyGetter getter,
+ v8::NamedPropertySetter setter) {
+ templ->InstanceTemplate()->SetNamedPropertyHandler(getter, setter);
+}
+
+THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) {
+ v8::HandleScope scope;
+ Handle<FunctionTemplate> parent = FunctionTemplate::New();
+ Handle<FunctionTemplate> child = FunctionTemplate::New();
+ child->Inherit(parent);
+ AddAccessor(parent, v8_str("age"),
+ SimpleAccessorGetter, SimpleAccessorSetter);
+ AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Child"), child->GetFunction());
+ CompileRun("var child = new Child;"
+ "child.age = 10;");
+ ExpectBoolean("child.hasOwnProperty('age')", false);
+ ExpectInt32("child.age", 10);
+ ExpectInt32("child.accessor_age", 10);
+}
+
+THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) {
+ v8::HandleScope scope;
+ Handle<FunctionTemplate> parent = FunctionTemplate::New();
+ Handle<FunctionTemplate> child = FunctionTemplate::New();
+ child->Inherit(parent);
+ AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Child"), child->GetFunction());
+ CompileRun("var child = new Child;"
+ "var parent = child.__proto__;"
+ "Object.defineProperty(parent, 'age', "
+ " {get: function(){ return this.accessor_age; }, "
+ " set: function(v){ this.accessor_age = v; }, "
+ " enumerable: true, configurable: true});"
+ "child.age = 10;");
+ ExpectBoolean("child.hasOwnProperty('age')", false);
+ ExpectInt32("child.age", 10);
+ ExpectInt32("child.accessor_age", 10);
+}
+
+THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) {
+ v8::HandleScope scope;
+ Handle<FunctionTemplate> parent = FunctionTemplate::New();
+ Handle<FunctionTemplate> child = FunctionTemplate::New();
+ child->Inherit(parent);
+ AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Child"), child->GetFunction());
+ CompileRun("var child = new Child;"
+ "var parent = child.__proto__;"
+ "parent.name = 'Alice';");
+ ExpectBoolean("child.hasOwnProperty('name')", false);
+ ExpectString("child.name", "Alice");
+ CompileRun("child.name = 'Bob';");
+ ExpectString("child.name", "Bob");
+ ExpectBoolean("child.hasOwnProperty('name')", true);
+ ExpectString("parent.name", "Alice");
+}
+
+THREADED_TEST(SwitchFromInterceptorToAccessor) {
+ v8::HandleScope scope;
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddAccessor(templ, v8_str("age"),
+ SimpleAccessorGetter, SimpleAccessorSetter);
+ AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Obj"), templ->GetFunction());
+ CompileRun("var obj = new Obj;"
+ "function setAge(i){ obj.age = i; };"
+ "for(var i = 0; i <= 10000; i++) setAge(i);");
+ // All i < 10000 go to the interceptor.
+ ExpectInt32("obj.interceptor_age", 9999);
+ // The last i goes to the accessor.
+ ExpectInt32("obj.accessor_age", 10000);
+}
+
+THREADED_TEST(SwitchFromAccessorToInterceptor) {
+ v8::HandleScope scope;
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddAccessor(templ, v8_str("age"),
+ SimpleAccessorGetter, SimpleAccessorSetter);
+ AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Obj"), templ->GetFunction());
+ CompileRun("var obj = new Obj;"
+ "function setAge(i){ obj.age = i; };"
+ "for(var i = 20000; i >= 9999; i--) setAge(i);");
+ // All i >= 10000 go to the accessor.
+ ExpectInt32("obj.accessor_age", 10000);
+ // The last i goes to the interceptor.
+ ExpectInt32("obj.interceptor_age", 9999);
+}
+
+THREADED_TEST(SwitchFromInterceptorToAccessorWithInheritance) {
+ v8::HandleScope scope;
+ Handle<FunctionTemplate> parent = FunctionTemplate::New();
+ Handle<FunctionTemplate> child = FunctionTemplate::New();
+ child->Inherit(parent);
+ AddAccessor(parent, v8_str("age"),
+ SimpleAccessorGetter, SimpleAccessorSetter);
+ AddInterceptor(child, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Child"), child->GetFunction());
+ CompileRun("var child = new Child;"
+ "function setAge(i){ child.age = i; };"
+ "for(var i = 0; i <= 10000; i++) setAge(i);");
+ // All i < 10000 go to the interceptor.
+ ExpectInt32("child.interceptor_age", 9999);
+ // The last i goes to the accessor.
+ ExpectInt32("child.accessor_age", 10000);
+}
+
+THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) {
+ v8::HandleScope scope;
+ Handle<FunctionTemplate> parent = FunctionTemplate::New();
+ Handle<FunctionTemplate> child = FunctionTemplate::New();
+ child->Inherit(parent);
+ AddAccessor(parent, v8_str("age"),
+ SimpleAccessorGetter, SimpleAccessorSetter);
+ AddInterceptor(child, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Child"), child->GetFunction());
+ CompileRun("var child = new Child;"
+ "function setAge(i){ child.age = i; };"
+ "for(var i = 20000; i >= 9999; i--) setAge(i);");
+ // All i >= 10000 go to the accessor.
+ ExpectInt32("child.accessor_age", 10000);
+ // The last i goes to the interceptor.
+ ExpectInt32("child.interceptor_age", 9999);
+}
+
+THREADED_TEST(SwitchFromInterceptorToJSAccessor) {
+ v8::HandleScope scope;
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Obj"), templ->GetFunction());
+ CompileRun("var obj = new Obj;"
+ "function setter(i) { this.accessor_age = i; };"
+ "function getter() { return this.accessor_age; };"
+ "function setAge(i) { obj.age = i; };"
+ "Object.defineProperty(obj, 'age', { get:getter, set:setter });"
+ "for(var i = 0; i <= 10000; i++) setAge(i);");
+ // All i < 10000 go to the interceptor.
+ ExpectInt32("obj.interceptor_age", 9999);
+ // The last i goes to the JavaScript accessor.
+ ExpectInt32("obj.accessor_age", 10000);
+ // The installed JavaScript getter is still intact.
+ // This last part is a regression test for issue 1651 and relies on the fact
+ // that both interceptor and accessor are being installed on the same object.
+ ExpectInt32("obj.age", 10000);
+ ExpectBoolean("obj.hasOwnProperty('age')", true);
+ ExpectUndefined("Object.getOwnPropertyDescriptor(obj, 'age').value");
+}
+
+THREADED_TEST(SwitchFromJSAccessorToInterceptor) {
+ v8::HandleScope scope;
+ Handle<FunctionTemplate> templ = FunctionTemplate::New();
+ AddInterceptor(templ, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Obj"), templ->GetFunction());
+ CompileRun("var obj = new Obj;"
+ "function setter(i) { this.accessor_age = i; };"
+ "function getter() { return this.accessor_age; };"
+ "function setAge(i) { obj.age = i; };"
+ "Object.defineProperty(obj, 'age', { get:getter, set:setter });"
+ "for(var i = 20000; i >= 9999; i--) setAge(i);");
+ // All i >= 10000 go to the accessor.
+ ExpectInt32("obj.accessor_age", 10000);
+ // The last i goes to the interceptor.
+ ExpectInt32("obj.interceptor_age", 9999);
+ // The installed JavaScript getter is still intact.
+ // This last part is a regression test for issue 1651 and relies on the fact
+ // that both interceptor and accessor are being installed on the same object.
+ ExpectInt32("obj.age", 10000);
+ ExpectBoolean("obj.hasOwnProperty('age')", true);
+ ExpectUndefined("Object.getOwnPropertyDescriptor(obj, 'age').value");
+}
+
+THREADED_TEST(SwitchFromInterceptorToProperty) {
+ v8::HandleScope scope;
+ Handle<FunctionTemplate> parent = FunctionTemplate::New();
+ Handle<FunctionTemplate> child = FunctionTemplate::New();
+ child->Inherit(parent);
+ AddInterceptor(child, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Child"), child->GetFunction());
+ CompileRun("var child = new Child;"
+ "function setAge(i){ child.age = i; };"
+ "for(var i = 0; i <= 10000; i++) setAge(i);");
+ // All i < 10000 go to the interceptor.
+ ExpectInt32("child.interceptor_age", 9999);
+ // The last i goes to child's own property.
+ ExpectInt32("child.age", 10000);
+}
+
+THREADED_TEST(SwitchFromPropertyToInterceptor) {
+ v8::HandleScope scope;
+ Handle<FunctionTemplate> parent = FunctionTemplate::New();
+ Handle<FunctionTemplate> child = FunctionTemplate::New();
+ child->Inherit(parent);
+ AddInterceptor(child, InterceptorGetter, InterceptorSetter);
+ LocalContext env;
+ env->Global()->Set(v8_str("Child"), child->GetFunction());
+ CompileRun("var child = new Child;"
+ "function setAge(i){ child.age = i; };"
+ "for(var i = 20000; i >= 9999; i--) setAge(i);");
+ // All i >= 10000 go to child's own property.
+ ExpectInt32("child.age", 10000);
+ // The last i goes to the interceptor.
+ ExpectInt32("child.interceptor_age", 9999);
+}
THREADED_TEST(NamedPropertyHandlerGetter) {
echo_named_call_count = 0;
@@ -1567,7 +1844,7 @@ THREADED_TEST(DeepCrossLanguageRecursion) {
env->Global()->Set(v8_str("depth"), v8::Integer::New(0));
call_recursively_script = v8_compile("callScriptRecursively()");
- v8::Handle<Value> result = call_recursively_script->Run();
+ call_recursively_script->Run();
call_recursively_script = v8::Handle<Script>();
env->Global()->Set(v8_str("depth"), v8::Integer::New(0));
@@ -1666,12 +1943,12 @@ THREADED_TEST(InternalFieldsNativePointers) {
// Check reading and writing aligned pointers.
obj->SetPointerInInternalField(0, aligned);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(aligned, obj->GetPointerFromInternalField(0));
// Check reading and writing unaligned pointers.
obj->SetPointerInInternalField(0, unaligned);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0));
delete[] data;
@@ -1697,19 +1974,19 @@ THREADED_TEST(InternalFieldsNativePointersAndExternal) {
CHECK_EQ(1, static_cast<int>(reinterpret_cast<uintptr_t>(unaligned) & 0x1));
obj->SetPointerInInternalField(0, aligned);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(aligned, v8::External::Unwrap(obj->GetInternalField(0)));
obj->SetPointerInInternalField(0, unaligned);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(unaligned, v8::External::Unwrap(obj->GetInternalField(0)));
obj->SetInternalField(0, v8::External::Wrap(aligned));
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(aligned, obj->GetPointerFromInternalField(0));
obj->SetInternalField(0, v8::External::Wrap(unaligned));
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(unaligned, obj->GetPointerFromInternalField(0));
delete[] data;
@@ -1722,7 +1999,7 @@ THREADED_TEST(IdentityHash) {
// Ensure that the test starts with an fresh heap to test whether the hash
// code is based on the address.
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
Local<v8::Object> obj = v8::Object::New();
int hash = obj->GetIdentityHash();
int hash1 = obj->GetIdentityHash();
@@ -1732,7 +2009,7 @@ THREADED_TEST(IdentityHash) {
// objects should not be assigned the same hash code. If the test below fails
// the random number generator should be evaluated.
CHECK_NE(hash, hash2);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
int hash3 = v8::Object::New()->GetIdentityHash();
// Make sure that the identity hash is not based on the initial address of
// the object alone. If the test below fails the random number generator
@@ -1769,7 +2046,7 @@ THREADED_TEST(HiddenProperties) {
v8::Local<v8::String> empty = v8_str("");
v8::Local<v8::String> prop_name = v8_str("prop_name");
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
// Make sure delete of a non-existent hidden value works
CHECK(obj->DeleteHiddenValue(key));
@@ -1779,7 +2056,7 @@ THREADED_TEST(HiddenProperties) {
CHECK(obj->SetHiddenValue(key, v8::Integer::New(2002)));
CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
// Make sure we do not find the hidden property.
CHECK(!obj->Has(empty));
@@ -1790,7 +2067,7 @@ THREADED_TEST(HiddenProperties) {
CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
CHECK_EQ(2003, obj->Get(empty)->Int32Value());
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
// Add another property and delete it afterwards to force the object in
// slow case.
@@ -1801,7 +2078,7 @@ THREADED_TEST(HiddenProperties) {
CHECK(obj->Delete(prop_name));
CHECK_EQ(2002, obj->GetHiddenValue(key)->Int32Value());
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK(obj->DeleteHiddenValue(key));
CHECK(obj->GetHiddenValue(key).IsEmpty());
@@ -1908,19 +2185,30 @@ THREADED_TEST(GlobalHandle) {
}
-static int NumberOfWeakCalls = 0;
+class WeakCallCounter {
+ public:
+ explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) { }
+ int id() { return id_; }
+ void increment() { number_of_weak_calls_++; }
+ int NumberOfWeakCalls() { return number_of_weak_calls_; }
+ private:
+ int id_;
+ int number_of_weak_calls_;
+};
+
+
static void WeakPointerCallback(Persistent<Value> handle, void* id) {
- CHECK_EQ(reinterpret_cast<void*>(1234), id);
- NumberOfWeakCalls++;
+ WeakCallCounter* counter = reinterpret_cast<WeakCallCounter*>(id);
+ CHECK_EQ(1234, counter->id());
+ counter->increment();
handle.Dispose();
}
+
THREADED_TEST(ApiObjectGroups) {
HandleScope scope;
LocalContext env;
- NumberOfWeakCalls = 0;
-
Persistent<Object> g1s1;
Persistent<Object> g1s2;
Persistent<Object> g1c1;
@@ -1928,21 +2216,23 @@ THREADED_TEST(ApiObjectGroups) {
Persistent<Object> g2s2;
Persistent<Object> g2c1;
+ WeakCallCounter counter(1234);
+
{
HandleScope scope;
g1s1 = Persistent<Object>::New(Object::New());
g1s2 = Persistent<Object>::New(Object::New());
g1c1 = Persistent<Object>::New(Object::New());
- g1s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
- g1s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
- g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ g1c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
g2s1 = Persistent<Object>::New(Object::New());
g2s2 = Persistent<Object>::New(Object::New());
g2c1 = Persistent<Object>::New(Object::New());
- g2s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
- g2s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
- g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ g2c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
}
Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root.
@@ -1961,14 +2251,14 @@ THREADED_TEST(ApiObjectGroups) {
V8::AddObjectGroup(g2_objects, 2);
V8::AddImplicitReferences(g2s2, g2_children, 1);
}
- // Do a full GC
- HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
+ // Do a single full GC, ensure incremental marking is stopped.
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
// All object should be alive.
- CHECK_EQ(0, NumberOfWeakCalls);
+ CHECK_EQ(0, counter.NumberOfWeakCalls());
// Weaken the root.
- root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
// But make children strong roots---all the objects (except for children)
// should be collectable now.
g1c1.ClearWeak();
@@ -1986,17 +2276,17 @@ THREADED_TEST(ApiObjectGroups) {
V8::AddImplicitReferences(g2s2, g2_children, 1);
}
- HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
// All objects should be gone. 5 global handles in total.
- CHECK_EQ(5, NumberOfWeakCalls);
+ CHECK_EQ(5, counter.NumberOfWeakCalls());
// And now make children weak again and collect them.
- g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
- g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g1c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ g2c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
- HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
- CHECK_EQ(7, NumberOfWeakCalls);
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
+ CHECK_EQ(7, counter.NumberOfWeakCalls());
}
@@ -2004,7 +2294,7 @@ THREADED_TEST(ApiObjectGroupsCycle) {
HandleScope scope;
LocalContext env;
- NumberOfWeakCalls = 0;
+ WeakCallCounter counter(1234);
Persistent<Object> g1s1;
Persistent<Object> g1s2;
@@ -2017,18 +2307,18 @@ THREADED_TEST(ApiObjectGroupsCycle) {
HandleScope scope;
g1s1 = Persistent<Object>::New(Object::New());
g1s2 = Persistent<Object>::New(Object::New());
- g1s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
- g1s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
g2s1 = Persistent<Object>::New(Object::New());
g2s2 = Persistent<Object>::New(Object::New());
- g2s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
- g2s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
g3s1 = Persistent<Object>::New(Object::New());
g3s2 = Persistent<Object>::New(Object::New());
- g3s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
- g3s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ g3s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ g3s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
}
Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root.
@@ -2050,14 +2340,14 @@ THREADED_TEST(ApiObjectGroupsCycle) {
V8::AddObjectGroup(g3_objects, 2);
V8::AddImplicitReferences(g3s1, g3_children, 1);
}
- // Do a full GC
- HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
+ // Do a single full GC
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
// All object should be alive.
- CHECK_EQ(0, NumberOfWeakCalls);
+ CHECK_EQ(0, counter.NumberOfWeakCalls());
// Weaken the root.
- root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback);
+ root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
// Groups are deleted, rebuild groups.
{
@@ -2075,10 +2365,10 @@ THREADED_TEST(ApiObjectGroupsCycle) {
V8::AddImplicitReferences(g3s1, g3_children, 1);
}
- HEAP->CollectGarbage(i::OLD_POINTER_SPACE);
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
// All objects should be gone. 7 global handles in total.
- CHECK_EQ(7, NumberOfWeakCalls);
+ CHECK_EQ(7, counter.NumberOfWeakCalls());
}
@@ -2573,6 +2863,16 @@ THREADED_TEST(isNumberType) {
obj = env->Global()->Get(v8_str("obj"));
CHECK(!obj->IsInt32());
CHECK(!obj->IsUint32());
+ // Positive zero
+ CompileRun("var obj = 0.0;");
+ obj = env->Global()->Get(v8_str("obj"));
+ CHECK(obj->IsInt32());
+ CHECK(obj->IsUint32());
+ // Positive zero
+ CompileRun("var obj = -0.0;");
+ obj = env->Global()->Get(v8_str("obj"));
+ CHECK(!obj->IsInt32());
+ CHECK(!obj->IsUint32());
}
@@ -4172,7 +4472,7 @@ THREADED_TEST(ExtensibleOnUndetectable) {
source = v8_str("undetectable.y = 2000;");
script = Script::Compile(source);
- Local<Value> result = script->Run();
+ script->Run();
ExpectBoolean("undetectable.y == undefined", true);
}
@@ -4305,6 +4605,47 @@ THREADED_TEST(SimpleExtensions) {
}
+static const char* kEmbeddedExtensionSource =
+ "function Ret54321(){return 54321;}~~@@$"
+ "$%% THIS IS A SERIES OF NON-NULL-TERMINATED STRINGS.";
+static const int kEmbeddedExtensionSourceValidLen = 34;
+
+
+THREADED_TEST(ExtensionMissingSourceLength) {
+ v8::HandleScope handle_scope;
+ v8::RegisterExtension(new Extension("srclentest_fail",
+ kEmbeddedExtensionSource));
+ const char* extension_names[] = { "srclentest_fail" };
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Handle<Context> context = Context::New(&extensions);
+ CHECK_EQ(0, *context);
+}
+
+
+THREADED_TEST(ExtensionWithSourceLength) {
+ for (int source_len = kEmbeddedExtensionSourceValidLen - 1;
+ source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) {
+ v8::HandleScope handle_scope;
+ i::ScopedVector<char> extension_name(32);
+ i::OS::SNPrintF(extension_name, "ext #%d", source_len);
+ v8::RegisterExtension(new Extension(extension_name.start(),
+ kEmbeddedExtensionSource, 0, 0,
+ source_len));
+ const char* extension_names[1] = { extension_name.start() };
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Handle<Context> context = Context::New(&extensions);
+ if (source_len == kEmbeddedExtensionSourceValidLen) {
+ Context::Scope lock(context);
+ v8::Handle<Value> result = Script::Compile(v8_str("Ret54321()"))->Run();
+ CHECK_EQ(v8::Integer::New(54321), result);
+ } else {
+ // Anything but exactly the right length should fail to compile.
+ CHECK_EQ(0, *context);
+ }
+ }
+}
+
+
static const char* kEvalExtensionSource1 =
"function UseEval1() {"
" var x = 42;"
@@ -4483,10 +4824,11 @@ THREADED_TEST(NativeFunctionDeclarationError) {
"native\nfunction foo();"));
const char* extension_names[] = { name };
v8::ExtensionConfiguration extensions(1, extension_names);
- v8::Handle<Context> context = Context::New(&extensions);
- ASSERT(context.IsEmpty());
+ v8::Handle<Context> context(Context::New(&extensions));
+ CHECK(context.IsEmpty());
}
+
THREADED_TEST(NativeFunctionDeclarationErrorEscape) {
v8::HandleScope handle_scope;
const char* name = "nativedeclerresc";
@@ -4497,8 +4839,8 @@ THREADED_TEST(NativeFunctionDeclarationErrorEscape) {
"nativ\\u0065 function foo();"));
const char* extension_names[] = { name };
v8::ExtensionConfiguration extensions(1, extension_names);
- v8::Handle<Context> context = Context::New(&extensions);
- ASSERT(context.IsEmpty());
+ v8::Handle<Context> context(Context::New(&extensions));
+ CHECK(context.IsEmpty());
}
@@ -4664,7 +5006,7 @@ TEST(RegexpOutOfMemory) {
Local<Script> script =
Script::Compile(String::New(js_code_causing_huge_string_flattening));
last_location = NULL;
- Local<Value> result = script->Run();
+ script->Run();
CHECK(false); // Should not return.
}
@@ -4805,7 +5147,7 @@ static void InvokeScavenge() {
static void InvokeMarkSweep() {
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
@@ -4898,7 +5240,7 @@ static v8::Handle<Value> ArgumentsTestCallback(const v8::Arguments& args) {
CHECK_EQ(v8::Integer::New(3), args[2]);
CHECK_EQ(v8::Undefined(), args[3]);
v8::HandleScope scope;
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
return v8::Undefined();
}
@@ -5184,68 +5526,121 @@ static int StrNCmp16(uint16_t* a, uint16_t* b, int n) {
}
+int GetUtf8Length(Handle<String> str) {
+ int len = str->Utf8Length();
+ if (len < 0) {
+ i::Handle<i::String> istr(v8::Utils::OpenHandle(*str));
+ i::FlattenString(istr);
+ len = str->Utf8Length();
+ }
+ return len;
+}
+
+
THREADED_TEST(StringWrite) {
+ LocalContext context;
v8::HandleScope scope;
v8::Handle<String> str = v8_str("abcde");
// abc<Icelandic eth><Unicode snowman>.
v8::Handle<String> str2 = v8_str("abc\303\260\342\230\203");
+ const int kStride = 4; // Must match stride in for loops in JS below.
+ CompileRun(
+ "var left = '';"
+ "for (var i = 0; i < 0xd800; i += 4) {"
+ " left = left + String.fromCharCode(i);"
+ "}");
+ CompileRun(
+ "var right = '';"
+ "for (var i = 0; i < 0xd800; i += 4) {"
+ " right = String.fromCharCode(i) + right;"
+ "}");
+ v8::Handle<v8::Object> global = Context::GetCurrent()->Global();
+ Handle<String> left_tree = global->Get(v8_str("left")).As<String>();
+ Handle<String> right_tree = global->Get(v8_str("right")).As<String>();
CHECK_EQ(5, str2->Length());
+ CHECK_EQ(0xd800 / kStride, left_tree->Length());
+ CHECK_EQ(0xd800 / kStride, right_tree->Length());
char buf[100];
- char utf8buf[100];
+ char utf8buf[0xd800 * 3];
uint16_t wbuf[100];
int len;
int charlen;
- memset(utf8buf, 0x1, sizeof(utf8buf));
+ memset(utf8buf, 0x1, 1000);
len = str2->WriteUtf8(utf8buf, sizeof(utf8buf), &charlen);
CHECK_EQ(9, len);
CHECK_EQ(5, charlen);
CHECK_EQ(0, strcmp(utf8buf, "abc\303\260\342\230\203"));
- memset(utf8buf, 0x1, sizeof(utf8buf));
+ memset(utf8buf, 0x1, 1000);
len = str2->WriteUtf8(utf8buf, 8, &charlen);
CHECK_EQ(8, len);
CHECK_EQ(5, charlen);
CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\342\230\203\1", 9));
- memset(utf8buf, 0x1, sizeof(utf8buf));
+ memset(utf8buf, 0x1, 1000);
len = str2->WriteUtf8(utf8buf, 7, &charlen);
CHECK_EQ(5, len);
CHECK_EQ(4, charlen);
CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5));
- memset(utf8buf, 0x1, sizeof(utf8buf));
+ memset(utf8buf, 0x1, 1000);
len = str2->WriteUtf8(utf8buf, 6, &charlen);
CHECK_EQ(5, len);
CHECK_EQ(4, charlen);
CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5));
- memset(utf8buf, 0x1, sizeof(utf8buf));
+ memset(utf8buf, 0x1, 1000);
len = str2->WriteUtf8(utf8buf, 5, &charlen);
CHECK_EQ(5, len);
CHECK_EQ(4, charlen);
CHECK_EQ(0, strncmp(utf8buf, "abc\303\260\1", 5));
- memset(utf8buf, 0x1, sizeof(utf8buf));
+ memset(utf8buf, 0x1, 1000);
len = str2->WriteUtf8(utf8buf, 4, &charlen);
CHECK_EQ(3, len);
CHECK_EQ(3, charlen);
CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4));
- memset(utf8buf, 0x1, sizeof(utf8buf));
+ memset(utf8buf, 0x1, 1000);
len = str2->WriteUtf8(utf8buf, 3, &charlen);
CHECK_EQ(3, len);
CHECK_EQ(3, charlen);
CHECK_EQ(0, strncmp(utf8buf, "abc\1", 4));
- memset(utf8buf, 0x1, sizeof(utf8buf));
+ memset(utf8buf, 0x1, 1000);
len = str2->WriteUtf8(utf8buf, 2, &charlen);
CHECK_EQ(2, len);
CHECK_EQ(2, charlen);
CHECK_EQ(0, strncmp(utf8buf, "ab\1", 3));
+ memset(utf8buf, 0x1, sizeof(utf8buf));
+ len = GetUtf8Length(left_tree);
+ int utf8_expected =
+ (0x80 + (0x800 - 0x80) * 2 + (0xd800 - 0x800) * 3) / kStride;
+ CHECK_EQ(utf8_expected, len);
+ len = left_tree->WriteUtf8(utf8buf, utf8_expected, &charlen);
+ CHECK_EQ(utf8_expected, len);
+ CHECK_EQ(0xd800 / kStride, charlen);
+ CHECK_EQ(0xed, static_cast<unsigned char>(utf8buf[utf8_expected - 3]));
+ CHECK_EQ(0x9f, static_cast<unsigned char>(utf8buf[utf8_expected - 2]));
+ CHECK_EQ(0xc0 - kStride,
+ static_cast<unsigned char>(utf8buf[utf8_expected - 1]));
+ CHECK_EQ(1, utf8buf[utf8_expected]);
+
+ memset(utf8buf, 0x1, sizeof(utf8buf));
+ len = GetUtf8Length(right_tree);
+ CHECK_EQ(utf8_expected, len);
+ len = right_tree->WriteUtf8(utf8buf, utf8_expected, &charlen);
+ CHECK_EQ(utf8_expected, len);
+ CHECK_EQ(0xd800 / kStride, charlen);
+ CHECK_EQ(0xed, static_cast<unsigned char>(utf8buf[0]));
+ CHECK_EQ(0x9f, static_cast<unsigned char>(utf8buf[1]));
+ CHECK_EQ(0xc0 - kStride, static_cast<unsigned char>(utf8buf[2]));
+ CHECK_EQ(1, utf8buf[utf8_expected]);
+
memset(buf, 0x1, sizeof(buf));
memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf);
@@ -5361,6 +5756,225 @@ THREADED_TEST(StringWrite) {
}
+static void Utf16Helper(
+ LocalContext& context,
+ const char* name,
+ const char* lengths_name,
+ int len) {
+ Local<v8::Array> a =
+ Local<v8::Array>::Cast(context->Global()->Get(v8_str(name)));
+ Local<v8::Array> alens =
+ Local<v8::Array>::Cast(context->Global()->Get(v8_str(lengths_name)));
+ for (int i = 0; i < len; i++) {
+ Local<v8::String> string =
+ Local<v8::String>::Cast(a->Get(i));
+ Local<v8::Number> expected_len =
+ Local<v8::Number>::Cast(alens->Get(i));
+ CHECK_EQ(expected_len->Value() != string->Length(),
+ string->MayContainNonAscii());
+ int length = GetUtf8Length(string);
+ CHECK_EQ(static_cast<int>(expected_len->Value()), length);
+ }
+}
+
+
+static uint16_t StringGet(Handle<String> str, int index) {
+ i::Handle<i::String> istring =
+ v8::Utils::OpenHandle(String::Cast(*str));
+ return istring->Get(index);
+}
+
+
+static void WriteUtf8Helper(
+ LocalContext& context,
+ const char* name,
+ const char* lengths_name,
+ int len) {
+ Local<v8::Array> b =
+ Local<v8::Array>::Cast(context->Global()->Get(v8_str(name)));
+ Local<v8::Array> alens =
+ Local<v8::Array>::Cast(context->Global()->Get(v8_str(lengths_name)));
+ char buffer[1000];
+ char buffer2[1000];
+ for (int i = 0; i < len; i++) {
+ Local<v8::String> string =
+ Local<v8::String>::Cast(b->Get(i));
+ Local<v8::Number> expected_len =
+ Local<v8::Number>::Cast(alens->Get(i));
+ int utf8_length = static_cast<int>(expected_len->Value());
+ for (int j = utf8_length + 1; j >= 0; j--) {
+ memset(reinterpret_cast<void*>(&buffer), 42, sizeof(buffer));
+ memset(reinterpret_cast<void*>(&buffer2), 42, sizeof(buffer2));
+ int nchars;
+ int utf8_written =
+ string->WriteUtf8(buffer, j, &nchars, String::NO_OPTIONS);
+ int utf8_written2 =
+ string->WriteUtf8(buffer2, j, &nchars, String::NO_NULL_TERMINATION);
+ CHECK_GE(utf8_length + 1, utf8_written);
+ CHECK_GE(utf8_length, utf8_written2);
+ for (int k = 0; k < utf8_written2; k++) {
+ CHECK_EQ(buffer[k], buffer2[k]);
+ }
+ CHECK(nchars * 3 >= utf8_written - 1);
+ CHECK(nchars <= utf8_written);
+ if (j == utf8_length + 1) {
+ CHECK_EQ(utf8_written2, utf8_length);
+ CHECK_EQ(utf8_written2 + 1, utf8_written);
+ }
+ CHECK_EQ(buffer[utf8_written], 42);
+ if (j > utf8_length) {
+ if (utf8_written != 0) CHECK_EQ(buffer[utf8_written - 1], 0);
+ if (utf8_written > 1) CHECK_NE(buffer[utf8_written - 2], 42);
+ Handle<String> roundtrip = v8_str(buffer);
+ CHECK(roundtrip->Equals(string));
+ } else {
+ if (utf8_written != 0) CHECK_NE(buffer[utf8_written - 1], 42);
+ }
+ if (utf8_written2 != 0) CHECK_NE(buffer[utf8_written - 1], 42);
+ if (nchars >= 2) {
+ uint16_t trail = StringGet(string, nchars - 1);
+ uint16_t lead = StringGet(string, nchars - 2);
+ if (((lead & 0xfc00) == 0xd800) &&
+ ((trail & 0xfc00) == 0xdc00)) {
+ unsigned char u1 = buffer2[utf8_written2 - 4];
+ unsigned char u2 = buffer2[utf8_written2 - 3];
+ unsigned char u3 = buffer2[utf8_written2 - 2];
+ unsigned char u4 = buffer2[utf8_written2 - 1];
+ CHECK_EQ((u1 & 0xf8), 0xf0);
+ CHECK_EQ((u2 & 0xc0), 0x80);
+ CHECK_EQ((u3 & 0xc0), 0x80);
+ CHECK_EQ((u4 & 0xc0), 0x80);
+ uint32_t c = 0x10000 + ((lead & 0x3ff) << 10) + (trail & 0x3ff);
+ CHECK_EQ((u4 & 0x3f), (c & 0x3f));
+ CHECK_EQ((u3 & 0x3f), ((c >> 6) & 0x3f));
+ CHECK_EQ((u2 & 0x3f), ((c >> 12) & 0x3f));
+ CHECK_EQ((u1 & 0x3), c >> 18);
+ }
+ }
+ }
+ }
+}
+
+
+THREADED_TEST(Utf16) {
+ LocalContext context;
+ v8::HandleScope scope;
+ CompileRun(
+ "var pad = '01234567890123456789';"
+ "var p = [];"
+ "var plens = [20, 3, 3];"
+ "p.push('01234567890123456789');"
+ "var lead = 0xd800;"
+ "var trail = 0xdc00;"
+ "p.push(String.fromCharCode(0xd800));"
+ "p.push(String.fromCharCode(0xdc00));"
+ "var a = [];"
+ "var b = [];"
+ "var c = [];"
+ "var alens = [];"
+ "for (var i = 0; i < 3; i++) {"
+ " p[1] = String.fromCharCode(lead++);"
+ " for (var j = 0; j < 3; j++) {"
+ " p[2] = String.fromCharCode(trail++);"
+ " a.push(p[i] + p[j]);"
+ " b.push(p[i] + p[j]);"
+ " c.push(p[i] + p[j]);"
+ " alens.push(plens[i] + plens[j]);"
+ " }"
+ "}"
+ "alens[5] -= 2;" // Here the surrogate pairs match up.
+ "var a2 = [];"
+ "var b2 = [];"
+ "var c2 = [];"
+ "var a2lens = [];"
+ "for (var m = 0; m < 9; m++) {"
+ " for (var n = 0; n < 9; n++) {"
+ " a2.push(a[m] + a[n]);"
+ " b2.push(b[m] + b[n]);"
+ " var newc = 'x' + c[m] + c[n] + 'y';"
+ " c2.push(newc.substring(1, newc.length - 1));"
+ " var utf = alens[m] + alens[n];" // And here.
+ // The 'n's that start with 0xdc.. are 6-8
+ // The 'm's that end with 0xd8.. are 1, 4 and 7
+ " if ((m % 3) == 1 && n >= 6) utf -= 2;"
+ " a2lens.push(utf);"
+ " }"
+ "}");
+ Utf16Helper(context, "a", "alens", 9);
+ Utf16Helper(context, "a2", "a2lens", 81);
+ WriteUtf8Helper(context, "b", "alens", 9);
+ WriteUtf8Helper(context, "b2", "a2lens", 81);
+ WriteUtf8Helper(context, "c2", "a2lens", 81);
+}
+
+
+static bool SameSymbol(Handle<String> s1, Handle<String> s2) {
+ i::Handle<i::String> is1(v8::Utils::OpenHandle(*s1));
+ i::Handle<i::String> is2(v8::Utils::OpenHandle(*s2));
+ return *is1 == *is2;
+}
+
+
+static void SameSymbolHelper(const char* a, const char* b) {
+ Handle<String> symbol1 = v8::String::NewSymbol(a);
+ Handle<String> symbol2 = v8::String::NewSymbol(b);
+ CHECK(SameSymbol(symbol1, symbol2));
+}
+
+
+THREADED_TEST(Utf16Symbol) {
+ LocalContext context;
+ v8::HandleScope scope;
+
+ Handle<String> symbol1 = v8::String::NewSymbol("abc");
+ Handle<String> symbol2 = v8::String::NewSymbol("abc");
+ CHECK(SameSymbol(symbol1, symbol2));
+
+ SameSymbolHelper("\360\220\220\205", // 4 byte encoding.
+ "\355\240\201\355\260\205"); // 2 3-byte surrogates.
+ SameSymbolHelper("\355\240\201\355\260\206", // 2 3-byte surrogates.
+ "\360\220\220\206"); // 4 byte encoding.
+ SameSymbolHelper("x\360\220\220\205", // 4 byte encoding.
+ "x\355\240\201\355\260\205"); // 2 3-byte surrogates.
+ SameSymbolHelper("x\355\240\201\355\260\206", // 2 3-byte surrogates.
+ "x\360\220\220\206"); // 4 byte encoding.
+ CompileRun(
+ "var sym0 = 'benedictus';"
+ "var sym0b = 'S\303\270ren';"
+ "var sym1 = '\355\240\201\355\260\207';"
+ "var sym2 = '\360\220\220\210';"
+ "var sym3 = 'x\355\240\201\355\260\207';"
+ "var sym4 = 'x\360\220\220\210';"
+ "if (sym1.length != 2) throw sym1;"
+ "if (sym1.charCodeAt(1) != 0xdc07) throw sym1.charCodeAt(1);"
+ "if (sym2.length != 2) throw sym2;"
+ "if (sym2.charCodeAt(1) != 0xdc08) throw sym2.charCodeAt(2);"
+ "if (sym3.length != 3) throw sym3;"
+ "if (sym3.charCodeAt(2) != 0xdc07) throw sym1.charCodeAt(2);"
+ "if (sym4.length != 3) throw sym4;"
+ "if (sym4.charCodeAt(2) != 0xdc08) throw sym2.charCodeAt(2);");
+ Handle<String> sym0 = v8::String::NewSymbol("benedictus");
+ Handle<String> sym0b = v8::String::NewSymbol("S\303\270ren");
+ Handle<String> sym1 = v8::String::NewSymbol("\355\240\201\355\260\207");
+ Handle<String> sym2 = v8::String::NewSymbol("\360\220\220\210");
+ Handle<String> sym3 = v8::String::NewSymbol("x\355\240\201\355\260\207");
+ Handle<String> sym4 = v8::String::NewSymbol("x\360\220\220\210");
+ v8::Local<v8::Object> global = context->Global();
+ Local<Value> s0 = global->Get(v8_str("sym0"));
+ Local<Value> s0b = global->Get(v8_str("sym0b"));
+ Local<Value> s1 = global->Get(v8_str("sym1"));
+ Local<Value> s2 = global->Get(v8_str("sym2"));
+ Local<Value> s3 = global->Get(v8_str("sym3"));
+ Local<Value> s4 = global->Get(v8_str("sym4"));
+ CHECK(SameSymbol(sym0, Handle<String>(String::Cast(*s0))));
+ CHECK(SameSymbol(sym0b, Handle<String>(String::Cast(*s0b))));
+ CHECK(SameSymbol(sym1, Handle<String>(String::Cast(*s1))));
+ CHECK(SameSymbol(sym2, Handle<String>(String::Cast(*s2))));
+ CHECK(SameSymbol(sym3, Handle<String>(String::Cast(*s3))));
+ CHECK(SameSymbol(sym4, Handle<String>(String::Cast(*s4))));
+}
+
+
THREADED_TEST(ToArrayIndex) {
v8::HandleScope scope;
LocalContext context;
@@ -5400,7 +6014,6 @@ THREADED_TEST(ErrorConstruction) {
v8::Handle<String> message = v8_str("message");
v8::Handle<Value> range_error = v8::Exception::RangeError(foo);
CHECK(range_error->IsObject());
- v8::Handle<v8::Object> range_obj = range_error.As<v8::Object>();
CHECK(range_error.As<v8::Object>()->Get(message)->Equals(foo));
v8::Handle<Value> reference_error = v8::Exception::ReferenceError(foo);
CHECK(reference_error->IsObject());
@@ -6970,7 +7583,7 @@ THREADED_TEST(CallKnownGlobalReceiver) {
// Create new environment reusing the global object.
LocalContext env(NULL, instance_template, global_object);
env->Global()->Set(v8_str("foo"), foo);
- Local<Value> value = Script::Compile(v8_str("foo()"))->Run();
+ Script::Compile(v8_str("foo()"))->Run();
}
}
@@ -7158,6 +7771,60 @@ THREADED_TEST(SetPrototype) {
}
+// Getting property names of an object with a prototype chain that
+// triggers dictionary elements in GetLocalPropertyNames() shouldn't
+// crash the runtime.
+THREADED_TEST(Regress91517) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope handle_scope;
+ LocalContext context;
+
+ Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+ t1->SetHiddenPrototype(true);
+ t1->InstanceTemplate()->Set(v8_str("foo"), v8_num(1));
+ Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New();
+ t2->SetHiddenPrototype(true);
+ t2->InstanceTemplate()->Set(v8_str("fuz1"), v8_num(2));
+ t2->InstanceTemplate()->Set(v8_str("objects"), v8::Object::New());
+ t2->InstanceTemplate()->Set(v8_str("fuz2"), v8_num(2));
+ Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New();
+ t3->SetHiddenPrototype(true);
+ t3->InstanceTemplate()->Set(v8_str("boo"), v8_num(3));
+ Local<v8::FunctionTemplate> t4 = v8::FunctionTemplate::New();
+ t4->InstanceTemplate()->Set(v8_str("baz"), v8_num(4));
+
+ // Force dictionary-based properties.
+ i::ScopedVector<char> name_buf(1024);
+ for (int i = 1; i <= 1000; i++) {
+ i::OS::SNPrintF(name_buf, "sdf%d", i);
+ t2->InstanceTemplate()->Set(v8_str(name_buf.start()), v8_num(2));
+ }
+
+ Local<v8::Object> o1 = t1->GetFunction()->NewInstance();
+ Local<v8::Object> o2 = t2->GetFunction()->NewInstance();
+ Local<v8::Object> o3 = t3->GetFunction()->NewInstance();
+ Local<v8::Object> o4 = t4->GetFunction()->NewInstance();
+
+ // Create prototype chain of hidden prototypes.
+ CHECK(o4->SetPrototype(o3));
+ CHECK(o3->SetPrototype(o2));
+ CHECK(o2->SetPrototype(o1));
+
+ // Call the runtime version of GetLocalPropertyNames() on the natively
+ // created object through JavaScript.
+ context->Global()->Set(v8_str("obj"), o4);
+ CompileRun("var names = %GetLocalPropertyNames(obj);");
+
+ ExpectInt32("names.length", 1006);
+ ExpectTrue("names.indexOf(\"baz\") >= 0");
+ ExpectTrue("names.indexOf(\"boo\") >= 0");
+ ExpectTrue("names.indexOf(\"foo\") >= 0");
+ ExpectTrue("names.indexOf(\"fuz1\") >= 0");
+ ExpectTrue("names.indexOf(\"fuz2\") >= 0");
+ ExpectFalse("names[1005] == undefined");
+}
+
+
THREADED_TEST(FunctionReadOnlyPrototype) {
v8::HandleScope handle_scope;
LocalContext context;
@@ -7241,7 +7908,8 @@ THREADED_TEST(Constructor) {
Local<Function> cons = templ->GetFunction();
context->Global()->Set(v8_str("Fun"), cons);
Local<v8::Object> inst = cons->NewInstance();
- i::Handle<i::JSObject> obj = v8::Utils::OpenHandle(*inst);
+ i::Handle<i::JSObject> obj(v8::Utils::OpenHandle(*inst));
+ CHECK(obj->IsJSObject());
Local<Value> value = CompileRun("(new Fun()).constructor === Fun");
CHECK(value->BooleanValue());
}
@@ -7492,9 +8160,11 @@ THREADED_TEST(EvalAliasedDynamic) {
" var bar = 2;"
" with (x) { return eval('bar'); }"
"}"
- "f(this)"));
+ "result4 = f(this)"));
script->Run();
- CHECK(try_catch.HasCaught());
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(2, current->Global()->Get(v8_str("result4"))->Int32Value());
+
try_catch.Reset();
}
@@ -7508,7 +8178,7 @@ THREADED_TEST(CrossEval) {
other->SetSecurityToken(token);
current->SetSecurityToken(token);
- // Setup reference from current to other.
+ // Set up reference from current to other.
current->Global()->Set(v8_str("other"), other->Global());
// Check that new variables are introduced in other context.
@@ -7588,7 +8258,7 @@ THREADED_TEST(EvalInDetachedGlobal) {
v8::Persistent<Context> context0 = Context::New();
v8::Persistent<Context> context1 = Context::New();
- // Setup function in context0 that uses eval from context0.
+ // Set up function in context0 that uses eval from context0.
context0->Enter();
v8::Handle<v8::Value> fun =
CompileRun("var x = 42;"
@@ -7626,7 +8296,7 @@ THREADED_TEST(CrossLazyLoad) {
other->SetSecurityToken(token);
current->SetSecurityToken(token);
- // Setup reference from current to other.
+ // Set up reference from current to other.
current->Global()->Set(v8_str("other"), other->Global());
// Trigger lazy loading in other context.
@@ -7710,7 +8380,8 @@ THREADED_TEST(CallAsFunction) {
}
{ Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
- Local<ObjectTemplate> instance_template = t->InstanceTemplate();
+ Local<ObjectTemplate> instance_template(t->InstanceTemplate());
+ USE(instance_template);
Local<v8::Object> instance = t->GetFunction()->NewInstance();
context->Global()->Set(v8_str("obj2"), instance);
v8::TryCatch try_catch;
@@ -7815,7 +8486,7 @@ static int Recurse(int depth, int iterations) {
v8::HandleScope scope;
if (depth == 0) return CountHandles();
for (int i = 0; i < iterations; i++) {
- Local<v8::Number> n = v8::Integer::New(42);
+ Local<v8::Number> n(v8::Integer::New(42));
}
return Recurse(depth - 1, iterations);
}
@@ -7829,7 +8500,7 @@ THREADED_TEST(HandleIteration) {
v8::HandleScope scope1;
CHECK_EQ(0, CountHandles());
for (int i = 0; i < kIterations; i++) {
- Local<v8::Number> n = v8::Integer::New(42);
+ Local<v8::Number> n(v8::Integer::New(42));
CHECK_EQ(i + 1, CountHandles());
}
@@ -7837,7 +8508,7 @@ THREADED_TEST(HandleIteration) {
{
v8::HandleScope scope2;
for (int j = 0; j < kIterations; j++) {
- Local<v8::Number> n = v8::Integer::New(42);
+ Local<v8::Number> n(v8::Integer::New(42));
CHECK_EQ(j + 1 + kIterations, CountHandles());
}
}
@@ -7883,7 +8554,7 @@ static v8::Handle<Value> InterceptorHasOwnPropertyGetterGC(
Local<String> name,
const AccessorInfo& info) {
ApiTestFuzzer::Fuzz();
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
return v8::Handle<Value>();
}
@@ -8340,10 +9011,10 @@ THREADED_TEST(InterceptorStoreIC) {
0, 0, 0, v8_str("data"));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
- v8::Handle<Value> value = CompileRun(
- "for (var i = 0; i < 1000; i++) {"
- " o.x = 42;"
- "}");
+ CompileRun(
+ "for (var i = 0; i < 1000; i++) {"
+ " o.x = 42;"
+ "}");
}
@@ -8469,17 +9140,6 @@ THREADED_TEST(InterceptorCallICInvalidatedCacheable) {
}
-static v8::Handle<Value> call_ic_function5;
-static v8::Handle<Value> InterceptorCallICGetter5(Local<String> name,
- const AccessorInfo& info) {
- ApiTestFuzzer::Fuzz();
- if (v8_str("x")->Equals(name))
- return call_ic_function5;
- else
- return Local<Value>();
-}
-
-
// This test checks that if interceptor doesn't provide a function,
// cached constant function is used
THREADED_TEST(InterceptorCallICConstantFunctionUsed) {
@@ -8500,6 +9160,17 @@ THREADED_TEST(InterceptorCallICConstantFunctionUsed) {
}
+static v8::Handle<Value> call_ic_function5;
+static v8::Handle<Value> InterceptorCallICGetter5(Local<String> name,
+ const AccessorInfo& info) {
+ ApiTestFuzzer::Fuzz();
+ if (v8_str("x")->Equals(name))
+ return call_ic_function5;
+ else
+ return Local<Value>();
+}
+
+
// This test checks that if interceptor provides a function,
// even if we cached constant function, interceptor's function
// is invoked
@@ -8523,6 +9194,48 @@ THREADED_TEST(InterceptorCallICConstantFunctionNotNeeded) {
}
+static v8::Handle<Value> call_ic_function6;
+static v8::Handle<Value> InterceptorCallICGetter6(Local<String> name,
+ const AccessorInfo& info) {
+ ApiTestFuzzer::Fuzz();
+ if (v8_str("x")->Equals(name))
+ return call_ic_function6;
+ else
+ return Local<Value>();
+}
+
+
+// Same test as above, except the code is wrapped in a function
+// to test the optimized compiler.
+THREADED_TEST(InterceptorCallICConstantFunctionNotNeededWrapped) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope;
+ v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New();
+ templ->SetNamedPropertyHandler(InterceptorCallICGetter6);
+ LocalContext context;
+ context->Global()->Set(v8_str("o"), templ->NewInstance());
+ call_ic_function6 =
+ v8_compile("function f(x) { return x - 1; }; f")->Run();
+ v8::Handle<Value> value = CompileRun(
+ "function inc(x) { return x + 1; };"
+ "inc(1);"
+ "o.x = inc;"
+ "function test() {"
+ " var result = 0;"
+ " for (var i = 0; i < 1000; i++) {"
+ " result = o.x(42);"
+ " }"
+ " return result;"
+ "};"
+ "test();"
+ "test();"
+ "test();"
+ "%OptimizeFunctionOnNextCall(test);"
+ "test()");
+ CHECK_EQ(41, value->Int32Value());
+}
+
+
// Test the case when we stored constant function into
// a stub, but it got invalidated later on
THREADED_TEST(InterceptorCallICInvalidatedConstantFunction) {
@@ -8613,7 +9326,7 @@ static v8::Handle<Value> InterceptorCallICFastApi(Local<String> name,
int* call_count = reinterpret_cast<int*>(v8::External::Unwrap(info.Data()));
++(*call_count);
if ((*call_count) % 20 == 0) {
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
return v8::Handle<Value>();
}
@@ -8769,7 +9482,7 @@ THREADED_TEST(InterceptorCallICFastApi_TrivialSignature) {
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"var result = 0;"
"for (var i = 0; i < 100; i++) {"
" result = o.method(41);"
@@ -8796,7 +9509,7 @@ THREADED_TEST(InterceptorCallICFastApi_SimpleSignature) {
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"o.foo = 17;"
"var receiver = {};"
"receiver.__proto__ = o;"
@@ -8826,7 +9539,7 @@ THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) {
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"o.foo = 17;"
"var receiver = {};"
"receiver.__proto__ = o;"
@@ -8862,7 +9575,7 @@ THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) {
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"o.foo = 17;"
"var receiver = {};"
"receiver.__proto__ = o;"
@@ -8899,7 +9612,7 @@ THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) {
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
v8::TryCatch try_catch;
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"o.foo = 17;"
"var receiver = {};"
"receiver.__proto__ = o;"
@@ -8938,7 +9651,7 @@ THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) {
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
v8::TryCatch try_catch;
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"o.foo = 17;"
"var receiver = {};"
"receiver.__proto__ = o;"
@@ -8967,12 +9680,13 @@ THREADED_TEST(CallICFastApi_TrivialSignature) {
v8::Handle<v8::Signature>());
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
- v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+ v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
+ USE(templ);
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"var result = 0;"
"for (var i = 0; i < 100; i++) {"
" result = o.method(41);"
@@ -8990,12 +9704,13 @@ THREADED_TEST(CallICFastApi_SimpleSignature) {
v8::Signature::New(fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
- v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+ v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
+ CHECK(!templ.IsEmpty());
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"o.foo = 17;"
"var receiver = {};"
"receiver.__proto__ = o;"
@@ -9016,12 +9731,13 @@ THREADED_TEST(CallICFastApi_SimpleSignature_Miss1) {
v8::Signature::New(fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
- v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+ v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
+ CHECK(!templ.IsEmpty());
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"o.foo = 17;"
"var receiver = {};"
"receiver.__proto__ = o;"
@@ -9047,13 +9763,14 @@ THREADED_TEST(CallICFastApi_SimpleSignature_Miss2) {
v8::Signature::New(fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
- v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
+ v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
+ CHECK(!templ.IsEmpty());
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
v8::TryCatch try_catch;
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"o.foo = 17;"
"var receiver = {};"
"receiver.__proto__ = o;"
@@ -9093,7 +9810,7 @@ THREADED_TEST(InterceptorKeyedCallICKeyChange1) {
templ->SetNamedPropertyHandler(NoBlockGetterX);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"proto = new Object();"
"proto.y = function(x) { return x + 1; };"
"proto.z = function(x) { return x - 1; };"
@@ -9119,7 +9836,7 @@ THREADED_TEST(InterceptorKeyedCallICKeyChange2) {
context->Global()->Set(v8_str("proto1"), templ->NewInstance());
keyed_call_ic_function =
v8_compile("function f(x) { return x - 1; }; f")->Run();
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"o = new Object();"
"proto2 = new Object();"
"o.y = function(x) { return x + 1; };"
@@ -9144,7 +9861,7 @@ THREADED_TEST(InterceptorKeyedCallICKeyChangeOnGlobal) {
templ->SetNamedPropertyHandler(NoBlockGetterX);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"function inc(x) { return x + 1; };"
"inc(1);"
"function dec(x) { return x - 1; };"
@@ -9170,7 +9887,7 @@ THREADED_TEST(InterceptorKeyedCallICFromGlobal) {
LocalContext context;
context->Global()->Set(v8_str("o"), templ_o->NewInstance());
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"function len(x) { return x.length; };"
"o.__proto__ = this;"
"var m = 'parseFloat';"
@@ -9194,7 +9911,7 @@ THREADED_TEST(InterceptorKeyedCallICMapChangeBefore) {
LocalContext context;
context->Global()->Set(v8_str("proto"), templ_o->NewInstance());
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"var o = new Object();"
"o.__proto__ = proto;"
"o.method = function(x) { return x + 1; };"
@@ -9216,7 +9933,7 @@ THREADED_TEST(InterceptorKeyedCallICMapChangeAfter) {
LocalContext context;
context->Global()->Set(v8_str("o"), templ_o->NewInstance());
- v8::Handle<Value> value = CompileRun(
+ CompileRun(
"var proto = new Object();"
"o.__proto__ = proto;"
"proto.method = function(x) { return x + 1; };"
@@ -9737,7 +10454,7 @@ void ApiTestFuzzer::Run() {
static unsigned linear_congruential_generator;
-void ApiTestFuzzer::Setup(PartOfTest part) {
+void ApiTestFuzzer::SetUp(PartOfTest part) {
linear_congruential_generator = i::FLAG_testing_prng_seed;
fuzzing_ = true;
int count = RegisterThreadedTest::count();
@@ -9801,25 +10518,25 @@ void ApiTestFuzzer::TearDown() {
// Lets not be needlessly self-referential.
TEST(Threading) {
- ApiTestFuzzer::Setup(ApiTestFuzzer::FIRST_PART);
+ ApiTestFuzzer::SetUp(ApiTestFuzzer::FIRST_PART);
ApiTestFuzzer::RunAllTests();
ApiTestFuzzer::TearDown();
}
TEST(Threading2) {
- ApiTestFuzzer::Setup(ApiTestFuzzer::SECOND_PART);
+ ApiTestFuzzer::SetUp(ApiTestFuzzer::SECOND_PART);
ApiTestFuzzer::RunAllTests();
ApiTestFuzzer::TearDown();
}
TEST(Threading3) {
- ApiTestFuzzer::Setup(ApiTestFuzzer::THIRD_PART);
+ ApiTestFuzzer::SetUp(ApiTestFuzzer::THIRD_PART);
ApiTestFuzzer::RunAllTests();
ApiTestFuzzer::TearDown();
}
TEST(Threading4) {
- ApiTestFuzzer::Setup(ApiTestFuzzer::FOURTH_PART);
+ ApiTestFuzzer::SetUp(ApiTestFuzzer::FOURTH_PART);
ApiTestFuzzer::RunAllTests();
ApiTestFuzzer::TearDown();
}
@@ -9964,6 +10681,7 @@ THREADED_TEST(LockUnlockLock) {
static int GetGlobalObjectsCount() {
+ i::Isolate::Current()->heap()->EnsureHeapIsIterable();
int count = 0;
i::HeapIterator it;
for (i::HeapObject* object = it.next(); object != NULL; object = it.next())
@@ -9978,9 +10696,8 @@ static void CheckSurvivingGlobalObjectsCount(int expected) {
// the first garbage collection but some of the maps have already
// been marked at that point. Therefore some of the maps are not
// collected until the second garbage collection.
- HEAP->global_context_map();
- HEAP->CollectAllGarbage(false);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
int count = GetGlobalObjectsCount();
#ifdef DEBUG
if (count != expected) HEAP->TracePathToGlobal();
@@ -10049,7 +10766,7 @@ THREADED_TEST(NewPersistentHandleFromWeakCallback) {
// weak callback of the first handle would be able to 'reallocate' it.
handle1.MakeWeak(NULL, NewPersistentHandleCallback);
handle2.Dispose();
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
@@ -10057,7 +10774,7 @@ v8::Persistent<v8::Object> to_be_disposed;
void DisposeAndForceGcCallback(v8::Persistent<v8::Value> handle, void*) {
to_be_disposed.Dispose();
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
handle.Dispose();
}
@@ -10073,7 +10790,7 @@ THREADED_TEST(DoNotUseDeletedNodesInSecondLevelGc) {
}
handle1.MakeWeak(NULL, DisposeAndForceGcCallback);
to_be_disposed = handle2;
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
void DisposingCallback(v8::Persistent<v8::Value> handle, void*) {
@@ -10099,7 +10816,7 @@ THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) {
}
handle2.MakeWeak(NULL, DisposingCallback);
handle3.MakeWeak(NULL, HandleCreatingCallback);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
@@ -10141,7 +10858,8 @@ THREADED_TEST(NestedHandleScopeAndContexts) {
v8::Persistent<Context> env = Context::New();
env->Enter();
v8::Handle<Value> value = NestedScope(env);
- v8::Handle<String> str = value->ToString();
+ v8::Handle<String> str(value->ToString());
+ CHECK(!str.IsEmpty());
env->Exit();
env.Dispose();
}
@@ -10149,7 +10867,8 @@ THREADED_TEST(NestedHandleScopeAndContexts) {
THREADED_TEST(ExternalAllocatedMemory) {
v8::HandleScope outer;
- v8::Persistent<Context> env = Context::New();
+ v8::Persistent<Context> env(Context::New());
+ CHECK(!env.IsEmpty());
const int kSize = 1024*1024;
CHECK_EQ(v8::V8::AdjustAmountOfExternalAllocatedMemory(kSize), kSize);
CHECK_EQ(v8::V8::AdjustAmountOfExternalAllocatedMemory(-kSize), 0);
@@ -10487,7 +11206,8 @@ THREADED_TEST(AccessControlRepeatedContextCreation) {
i::Handle<i::FunctionTemplateInfo> constructor(
i::FunctionTemplateInfo::cast(internal_template->constructor()));
CHECK(!constructor->access_check_info()->IsUndefined());
- v8::Persistent<Context> context0 = Context::New(NULL, global_template);
+ v8::Persistent<Context> context0(Context::New(NULL, global_template));
+ CHECK(!context0.IsEmpty());
CHECK(!constructor->access_check_info()->IsUndefined());
}
@@ -10557,14 +11277,18 @@ THREADED_TEST(TurnOnAccessCheck) {
}
-v8::Handle<v8::String> a;
-v8::Handle<v8::String> h;
+static const char* kPropertyA = "a";
+static const char* kPropertyH = "h";
static bool NamedGetAccessBlockAandH(Local<v8::Object> obj,
Local<Value> name,
v8::AccessType type,
Local<Value> data) {
- return !(name->Equals(a) || name->Equals(h));
+ if (!name->IsString()) return false;
+ i::Handle<i::String> name_handle =
+ v8::Utils::OpenHandle(String::Cast(*name));
+ return !name_handle->IsEqualTo(i::CStrVector(kPropertyA))
+ && !name_handle->IsEqualTo(i::CStrVector(kPropertyH));
}
@@ -10573,9 +11297,7 @@ THREADED_TEST(TurnOnAccessCheckAndRecompile) {
// Create an environment with access check to the global object disabled by
// default. When the registered access checker will block access to properties
- // a and h
- a = v8_str("a");
- h = v8_str("h");
+ // a and h.
v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
global_template->SetAccessCheckCallbacks(NamedGetAccessBlockAandH,
IndexedGetAccessBlocker,
@@ -10915,7 +11637,7 @@ class RegExpInterruptTest {
{
v8::Locker lock;
// TODO(lrn): Perhaps create some garbage before collecting.
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
gc_count_++;
}
i::OS::Sleep(1);
@@ -11037,7 +11759,7 @@ class ApplyInterruptTest {
while (gc_during_apply_ < kRequiredGCs) {
{
v8::Locker lock;
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
gc_count_++;
}
i::OS::Sleep(1);
@@ -11187,6 +11909,7 @@ static void MorphAString(i::String* string,
// Test that we can still flatten a string if the components it is built up
// from have been turned into 16 bit strings in the mean time.
THREADED_TEST(MorphCompositeStringTest) {
+ char utf_buffer[129];
const char* c_string = "Now is the time for all good men"
" to come to the aid of the party";
uint16_t* two_byte_string = AsciiToTwoByteString(c_string);
@@ -11212,9 +11935,23 @@ THREADED_TEST(MorphCompositeStringTest) {
"var slice = lhs.substring(1, lhs.length - 1);"
"var slice_on_cons = (lhs + rhs).substring(1, lhs.length *2 - 1);");
+ CHECK(!lhs->MayContainNonAscii());
+ CHECK(!rhs->MayContainNonAscii());
+
MorphAString(*v8::Utils::OpenHandle(*lhs), &ascii_resource, &uc16_resource);
MorphAString(*v8::Utils::OpenHandle(*rhs), &ascii_resource, &uc16_resource);
+ // This should UTF-8 without flattening, since everything is ASCII.
+ Handle<String> cons = v8_compile("cons")->Run().As<String>();
+ CHECK_EQ(128, cons->Utf8Length());
+ int nchars = -1;
+ CHECK_EQ(129, cons->WriteUtf8(utf_buffer, -1, &nchars));
+ CHECK_EQ(128, nchars);
+ CHECK_EQ(0, strcmp(
+ utf_buffer,
+ "Now is the time for all good men to come to the aid of the party"
+ "Now is the time for all good men to come to the aid of the party"));
+
// Now do some stuff to make sure the strings are flattened, etc.
CompileRun(
"/[^a-z]/.test(cons);"
@@ -11666,7 +12403,7 @@ THREADED_TEST(GetCallingContext) {
callback_templ->GetFunction());
calling_context0->Exit();
- // Expose context0 in context1 and setup a function that calls the
+ // Expose context0 in context1 and set up a function that calls the
// callback function.
calling_context1->Enter();
calling_context1->Global()->Set(v8_str("context0"),
@@ -11753,13 +12490,15 @@ THREADED_TEST(PixelArray) {
i::Handle<i::ExternalPixelArray> pixels =
i::Handle<i::ExternalPixelArray>::cast(
FACTORY->NewExternalArray(kElementCount,
- v8::kExternalPixelArray,
- pixel_data));
- HEAP->CollectAllGarbage(false); // Force GC to trigger verification.
+ v8::kExternalPixelArray,
+ pixel_data));
+ // Force GC to trigger verification.
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
for (int i = 0; i < kElementCount; i++) {
pixels->set(i, i % 256);
}
- HEAP->CollectAllGarbage(false); // Force GC to trigger verification.
+ // Force GC to trigger verification.
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
for (int i = 0; i < kElementCount; i++) {
CHECK_EQ(i % 256, pixels->get_scalar(i));
CHECK_EQ(i % 256, pixel_data[i]);
@@ -11822,18 +12561,21 @@ THREADED_TEST(PixelArray) {
i::Handle<i::Smi> value(i::Smi::FromInt(2));
i::Handle<i::Object> no_failure;
- no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode);
+ no_failure =
+ i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode);
ASSERT(!no_failure.is_null());
i::USE(no_failure);
CHECK_EQ(2, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
*value.location() = i::Smi::FromInt(256);
- no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode);
+ no_failure =
+ i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode);
ASSERT(!no_failure.is_null());
i::USE(no_failure);
CHECK_EQ(255,
i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
*value.location() = i::Smi::FromInt(-1);
- no_failure = i::SetElement(jsobj, 1, value, i::kNonStrictMode);
+ no_failure =
+ i::JSObject::SetElement(jsobj, 1, value, NONE, i::kNonStrictMode);
ASSERT(!no_failure.is_null());
i::USE(no_failure);
CHECK_EQ(0, i::Smi::cast(jsobj->GetElement(1)->ToObjectChecked())->value());
@@ -12235,11 +12977,13 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
i::Handle<ExternalArrayClass> array =
i::Handle<ExternalArrayClass>::cast(
FACTORY->NewExternalArray(kElementCount, array_type, array_data));
- HEAP->CollectAllGarbage(false); // Force GC to trigger verification.
+ // Force GC to trigger verification.
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
for (int i = 0; i < kElementCount; i++) {
array->set(i, static_cast<ElementType>(i));
}
- HEAP->CollectAllGarbage(false); // Force GC to trigger verification.
+ // Force GC to trigger verification.
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
for (int i = 0; i < kElementCount; i++) {
CHECK_EQ(static_cast<int64_t>(i),
static_cast<int64_t>(array->get_scalar(i)));
@@ -12357,7 +13101,8 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
" }"
"}"
"sum;");
- HEAP->CollectAllGarbage(false); // Force GC to trigger verification.
+ // Force GC to trigger verification.
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(28, result->Int32Value());
// Make sure out-of-range loads do not throw.
@@ -12392,8 +13137,15 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
"}"
"ext_array[7];");
CHECK_EQ(0, result->Int32Value());
- CHECK_EQ(
- 0, static_cast<int>(jsobj->GetElement(7)->ToObjectChecked()->Number()));
+ if (array_type == v8::kExternalDoubleArray ||
+ array_type == v8::kExternalFloatArray) {
+ CHECK_EQ(
+ static_cast<int>(i::OS::nan_value()),
+ static_cast<int>(jsobj->GetElement(7)->ToObjectChecked()->Number()));
+ } else {
+ CHECK_EQ(0, static_cast<int>(
+ jsobj->GetElement(7)->ToObjectChecked()->Number()));
+ }
result = CompileRun("for (var i = 0; i < 8; i++) {"
" ext_array[6] = '2.3';"
@@ -12546,11 +13298,6 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
const int kLargeElementCount = kXSize * kYSize * 4;
ElementType* large_array_data =
static_cast<ElementType*>(malloc(kLargeElementCount * element_size));
- i::Handle<ExternalArrayClass> large_array =
- i::Handle<ExternalArrayClass>::cast(
- FACTORY->NewExternalArray(kLargeElementCount,
- array_type,
- array_data));
v8::Handle<v8::Object> large_obj = v8::Object::New();
// Set the elements to be the external array.
large_obj->SetIndexedPropertiesToExternalArrayData(large_array_data,
@@ -12949,10 +13696,10 @@ TEST(CaptureStackTrace) {
"}\n"
"var x;eval('new foo();');";
v8::Handle<v8::String> overview_src = v8::String::New(overview_source);
- v8::Handle<Value> overview_result =
- v8::Script::New(overview_src, origin)->Run();
- ASSERT(!overview_result.IsEmpty());
- ASSERT(overview_result->IsObject());
+ v8::Handle<Value> overview_result(
+ v8::Script::New(overview_src, origin)->Run());
+ CHECK(!overview_result.IsEmpty());
+ CHECK(overview_result->IsObject());
// Test getting DETAILED information.
const char *detailed_source =
@@ -12970,9 +13717,9 @@ TEST(CaptureStackTrace) {
v8::ScriptOrigin detailed_origin(origin, line_offset, column_offset);
v8::Handle<v8::Script> detailed_script(
v8::Script::New(detailed_src, &detailed_origin));
- v8::Handle<Value> detailed_result = detailed_script->Run();
- ASSERT(!detailed_result.IsEmpty());
- ASSERT(detailed_result->IsObject());
+ v8::Handle<Value> detailed_result(detailed_script->Run());
+ CHECK(!detailed_result.IsEmpty());
+ CHECK(detailed_result->IsObject());
}
@@ -13030,6 +13777,137 @@ TEST(CaptureStackTraceForUncaughtExceptionAndSetters) {
}
+static void RethrowStackTraceHandler(v8::Handle<v8::Message> message,
+ v8::Handle<v8::Value> data) {
+ // Use the frame where JavaScript is called from.
+ v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace();
+ CHECK(!stack_trace.IsEmpty());
+ int frame_count = stack_trace->GetFrameCount();
+ CHECK_EQ(3, frame_count);
+ int line_number[] = {1, 2, 5};
+ for (int i = 0; i < frame_count; i++) {
+ CHECK_EQ(line_number[i], stack_trace->GetFrame(i)->GetLineNumber());
+ }
+}
+
+
+// Test that we only return the stack trace at the site where the exception
+// is first thrown (not where it is rethrown).
+TEST(RethrowStackTrace) {
+ v8::HandleScope scope;
+ LocalContext env;
+ // We make sure that
+ // - the stack trace of the ReferenceError in g() is reported.
+ // - the stack trace is not overwritten when e1 is rethrown by t().
+ // - the stack trace of e2 does not overwrite that of e1.
+ const char* source =
+ "function g() { error; } \n"
+ "function f() { g(); } \n"
+ "function t(e) { throw e; } \n"
+ "try { \n"
+ " f(); \n"
+ "} catch (e1) { \n"
+ " try { \n"
+ " error; \n"
+ " } catch (e2) { \n"
+ " t(e1); \n"
+ " } \n"
+ "} \n";
+ v8::V8::AddMessageListener(RethrowStackTraceHandler);
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(true);
+ CompileRun(source);
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
+ v8::V8::RemoveMessageListeners(RethrowStackTraceHandler);
+}
+
+
+static void RethrowPrimitiveStackTraceHandler(v8::Handle<v8::Message> message,
+ v8::Handle<v8::Value> data) {
+ v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace();
+ CHECK(!stack_trace.IsEmpty());
+ int frame_count = stack_trace->GetFrameCount();
+ CHECK_EQ(2, frame_count);
+ int line_number[] = {3, 7};
+ for (int i = 0; i < frame_count; i++) {
+ CHECK_EQ(line_number[i], stack_trace->GetFrame(i)->GetLineNumber());
+ }
+}
+
+
+// Test that we do not recognize identity for primitive exceptions.
+TEST(RethrowPrimitiveStackTrace) {
+ v8::HandleScope scope;
+ LocalContext env;
+ // We do not capture stack trace for non Error objects on creation time.
+ // Instead, we capture the stack trace on last throw.
+ const char* source =
+ "function g() { throw 404; } \n"
+ "function f() { g(); } \n"
+ "function t(e) { throw e; } \n"
+ "try { \n"
+ " f(); \n"
+ "} catch (e1) { \n"
+ " t(e1) \n"
+ "} \n";
+ v8::V8::AddMessageListener(RethrowPrimitiveStackTraceHandler);
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(true);
+ CompileRun(source);
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
+ v8::V8::RemoveMessageListeners(RethrowPrimitiveStackTraceHandler);
+}
+
+
+static void RethrowExistingStackTraceHandler(v8::Handle<v8::Message> message,
+ v8::Handle<v8::Value> data) {
+ // Use the frame where JavaScript is called from.
+ v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace();
+ CHECK(!stack_trace.IsEmpty());
+ CHECK_EQ(1, stack_trace->GetFrameCount());
+ CHECK_EQ(1, stack_trace->GetFrame(0)->GetLineNumber());
+}
+
+
+// Test that the stack trace is captured when the error object is created and
+// not where it is thrown.
+TEST(RethrowExistingStackTrace) {
+ v8::HandleScope scope;
+ LocalContext env;
+ const char* source =
+ "var e = new Error(); \n"
+ "throw e; \n";
+ v8::V8::AddMessageListener(RethrowExistingStackTraceHandler);
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(true);
+ CompileRun(source);
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
+ v8::V8::RemoveMessageListeners(RethrowExistingStackTraceHandler);
+}
+
+
+static void RethrowBogusErrorStackTraceHandler(v8::Handle<v8::Message> message,
+ v8::Handle<v8::Value> data) {
+ // Use the frame where JavaScript is called from.
+ v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace();
+ CHECK(!stack_trace.IsEmpty());
+ CHECK_EQ(1, stack_trace->GetFrameCount());
+ CHECK_EQ(2, stack_trace->GetFrame(0)->GetLineNumber());
+}
+
+
+// Test that the stack trace is captured where the bogus Error object is thrown.
+TEST(RethrowBogusErrorStackTrace) {
+ v8::HandleScope scope;
+ LocalContext env;
+ const char* source =
+ "var e = {__proto__: new Error()} \n"
+ "throw e; \n";
+ v8::V8::AddMessageListener(RethrowBogusErrorStackTraceHandler);
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(true);
+ CompileRun(source);
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
+ v8::V8::RemoveMessageListeners(RethrowBogusErrorStackTraceHandler);
+}
+
+
v8::Handle<Value> AnalyzeStackOfEvalWithSourceURL(const v8::Arguments& args) {
v8::HandleScope scope;
v8::Handle<v8::StackTrace> stackTrace =
@@ -13070,14 +13948,71 @@ TEST(SourceURLInStackTrace) {
// Test that idle notification can be handled and eventually returns true.
+// This just checks the contract of the IdleNotification() function,
+// and does not verify that it does reasonable work.
THREADED_TEST(IdleNotification) {
- bool rv = false;
- for (int i = 0; i < 100; i++) {
- rv = v8::V8::IdleNotification();
- if (rv)
- break;
+ v8::HandleScope scope;
+ LocalContext env;
+ {
+ // Create garbage in old-space to generate work for idle notification.
+ i::AlwaysAllocateScope always_allocate;
+ for (int i = 0; i < 100; i++) {
+ FACTORY->NewFixedArray(1000, i::TENURED);
+ }
}
- CHECK(rv == true);
+ bool finshed_idle_work = false;
+ for (int i = 0; i < 100 && !finshed_idle_work; i++) {
+ finshed_idle_work = v8::V8::IdleNotification();
+ }
+ CHECK(finshed_idle_work);
+}
+
+// Test that idle notification can be handled and eventually returns true.
+// This just checks the contract of the IdleNotification() function,
+// and does not verify that it does reasonable work.
+TEST(IdleNotificationWithSmallHint) {
+ v8::HandleScope scope;
+ LocalContext env;
+ {
+ // Create garbage in old-space to generate work for idle notification.
+ i::AlwaysAllocateScope always_allocate;
+ for (int i = 0; i < 100; i++) {
+ FACTORY->NewFixedArray(1000, i::TENURED);
+ }
+ }
+ intptr_t old_size = HEAP->SizeOfObjects();
+ bool finshed_idle_work = false;
+ bool no_idle_work = v8::V8::IdleNotification(10);
+ for (int i = 0; i < 200 && !finshed_idle_work; i++) {
+ finshed_idle_work = v8::V8::IdleNotification(10);
+ }
+ intptr_t new_size = HEAP->SizeOfObjects();
+ CHECK(finshed_idle_work);
+ CHECK(no_idle_work || new_size < old_size);
+}
+
+
+// This just checks the contract of the IdleNotification() function,
+// and does not verify that it does reasonable work.
+TEST(IdleNotificationWithLargeHint) {
+ v8::HandleScope scope;
+ LocalContext env;
+ {
+ // Create garbage in old-space to generate work for idle notification.
+ i::AlwaysAllocateScope always_allocate;
+ for (int i = 0; i < 100; i++) {
+ FACTORY->NewFixedArray(1000, i::TENURED);
+ }
+ }
+ intptr_t old_size = HEAP->SizeOfObjects();
+ bool finshed_idle_work = false;
+ bool no_idle_work = v8::V8::IdleNotification(900);
+ for (int i = 0; i < 200 && !finshed_idle_work; i++) {
+ finshed_idle_work = v8::V8::IdleNotification(900);
+ }
+ intptr_t new_size = HEAP->SizeOfObjects();
+ CHECK(finshed_idle_work);
+ CHECK(no_idle_work || new_size < old_size);
}
@@ -13168,6 +14103,63 @@ THREADED_TEST(GetHeapStatistics) {
}
+class VisitorImpl : public v8::ExternalResourceVisitor {
+ public:
+ VisitorImpl(TestResource* r1, TestResource* r2)
+ : resource1_(r1),
+ resource2_(r2),
+ found_resource1_(false),
+ found_resource2_(false) {}
+ virtual ~VisitorImpl() {}
+ virtual void VisitExternalString(v8::Handle<v8::String> string) {
+ if (!string->IsExternal()) {
+ CHECK(string->IsExternalAscii());
+ return;
+ }
+ v8::String::ExternalStringResource* resource =
+ string->GetExternalStringResource();
+ CHECK(resource);
+ if (resource1_ == resource) {
+ CHECK(!found_resource1_);
+ found_resource1_ = true;
+ }
+ if (resource2_ == resource) {
+ CHECK(!found_resource2_);
+ found_resource2_ = true;
+ }
+ }
+ void CheckVisitedResources() {
+ CHECK(found_resource1_);
+ CHECK(found_resource2_);
+ }
+
+ private:
+ v8::String::ExternalStringResource* resource1_;
+ v8::String::ExternalStringResource* resource2_;
+ bool found_resource1_;
+ bool found_resource2_;
+};
+
+TEST(VisitExternalStrings) {
+ v8::HandleScope scope;
+ LocalContext env;
+ const char* string = "Some string";
+ uint16_t* two_byte_string = AsciiToTwoByteString(string);
+ TestResource* resource1 = new TestResource(two_byte_string);
+ v8::Local<v8::String> string1 = v8::String::NewExternal(resource1);
+ TestResource* resource2 = new TestResource(two_byte_string);
+ v8::Local<v8::String> string2 = v8::String::NewExternal(resource2);
+
+ // We need to add usages for string1 and string2 to avoid warnings in GCC 4.7
+ CHECK(string1->IsExternal());
+ CHECK(string2->IsExternal());
+
+ VisitorImpl visitor(resource1, resource2);
+ v8::V8::VisitExternalResources(&visitor);
+ visitor.CheckVisitedResources();
+}
+
+
static double DoubleFromBits(uint64_t value) {
double target;
memcpy(&target, &value, sizeof(target));
@@ -13250,7 +14242,13 @@ THREADED_TEST(QuietSignalingNaNs) {
} else {
uint64_t stored_bits = DoubleToBits(stored_number);
// Check if quiet nan (bits 51..62 all set).
+#if defined(V8_TARGET_ARCH_MIPS) && !defined(USE_SIMULATOR)
+ // Most significant fraction bit for quiet nan is set to 0
+ // on MIPS architecture. Allowed by IEEE-754.
+ CHECK_EQ(0xffe, static_cast<int>((stored_bits >> 51) & 0xfff));
+#else
CHECK_EQ(0xfff, static_cast<int>((stored_bits >> 51) & 0xfff));
+#endif
}
// Check that Date::New preserves non-NaNs in the date range and
@@ -13263,7 +14261,13 @@ THREADED_TEST(QuietSignalingNaNs) {
} else {
uint64_t stored_bits = DoubleToBits(stored_date);
// Check if quiet nan (bits 51..62 all set).
+#if defined(V8_TARGET_ARCH_MIPS) && !defined(USE_SIMULATOR)
+ // Most significant fraction bit for quiet nan is set to 0
+ // on MIPS architecture. Allowed by IEEE-754.
+ CHECK_EQ(0xffe, static_cast<int>((stored_bits >> 51) & 0xfff));
+#else
CHECK_EQ(0xfff, static_cast<int>((stored_bits >> 51) & 0xfff));
+#endif
}
}
}
@@ -13272,7 +14276,8 @@ THREADED_TEST(QuietSignalingNaNs) {
static v8::Handle<Value> SpaghettiIncident(const v8::Arguments& args) {
v8::HandleScope scope;
v8::TryCatch tc;
- v8::Handle<v8::String> str = args[0]->ToString();
+ v8::Handle<v8::String> str(args[0]->ToString());
+ USE(str);
if (tc.HasCaught())
return tc.ReThrow();
return v8::Undefined();
@@ -13337,7 +14342,7 @@ TEST(Regress528) {
other_context->Enter();
CompileRun(source_simple);
other_context->Exit();
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
if (GetGlobalObjectsCount() == 1) break;
}
CHECK_GE(2, gc_count);
@@ -13359,7 +14364,7 @@ TEST(Regress528) {
other_context->Enter();
CompileRun(source_eval);
other_context->Exit();
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
if (GetGlobalObjectsCount() == 1) break;
}
CHECK_GE(2, gc_count);
@@ -13386,7 +14391,7 @@ TEST(Regress528) {
other_context->Enter();
CompileRun(source_exception);
other_context->Exit();
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
if (GetGlobalObjectsCount() == 1) break;
}
CHECK_GE(2, gc_count);
@@ -13417,6 +14422,17 @@ THREADED_TEST(ScriptOrigin) {
CHECK_EQ(0, script_origin_g.ResourceLineOffset()->Int32Value());
}
+THREADED_TEST(FunctionGetInferredName) {
+ v8::HandleScope scope;
+ LocalContext env;
+ v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"));
+ v8::Handle<v8::String> script = v8::String::New(
+ "var foo = { bar : { baz : function() {}}}; var f = foo.bar.baz;");
+ v8::Script::Compile(script, &origin)->Run();
+ v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
+ env->Global()->Get(v8::String::New("f")));
+ CHECK_EQ("foo.bar.baz", *v8::String::AsciiValue(f->GetInferredName()));
+}
THREADED_TEST(ScriptLineNumber) {
v8::HandleScope scope;
@@ -13434,6 +14450,41 @@ THREADED_TEST(ScriptLineNumber) {
}
+THREADED_TEST(ScriptColumnNumber) {
+ v8::HandleScope scope;
+ LocalContext env;
+ v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"),
+ v8::Integer::New(3), v8::Integer::New(2));
+ v8::Handle<v8::String> script = v8::String::New(
+ "function foo() {}\n\n function bar() {}");
+ v8::Script::Compile(script, &origin)->Run();
+ v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
+ env->Global()->Get(v8::String::New("foo")));
+ v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast(
+ env->Global()->Get(v8::String::New("bar")));
+ CHECK_EQ(14, foo->GetScriptColumnNumber());
+ CHECK_EQ(17, bar->GetScriptColumnNumber());
+}
+
+
+THREADED_TEST(FunctionGetScriptId) {
+ v8::HandleScope scope;
+ LocalContext env;
+ v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::New("test"),
+ v8::Integer::New(3), v8::Integer::New(2));
+ v8::Handle<v8::String> scriptSource = v8::String::New(
+ "function foo() {}\n\n function bar() {}");
+ v8::Local<v8::Script> script(v8::Script::Compile(scriptSource, &origin));
+ script->Run();
+ v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
+ env->Global()->Get(v8::String::New("foo")));
+ v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast(
+ env->Global()->Get(v8::String::New("bar")));
+ CHECK_EQ(script->Id(), foo->GetScriptId());
+ CHECK_EQ(script->Id(), bar->GetScriptId());
+}
+
+
static v8::Handle<Value> GetterWhichReturns42(Local<String> name,
const AccessorInfo& info) {
return v8_num(42);
@@ -13604,26 +14655,26 @@ TEST(GCCallbacks) {
v8::V8::AddGCEpilogueCallback(EpilogueCallback);
CHECK_EQ(0, prologue_call_count);
CHECK_EQ(0, epilogue_call_count);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(1, prologue_call_count);
CHECK_EQ(1, epilogue_call_count);
v8::V8::AddGCPrologueCallback(PrologueCallbackSecond);
v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(2, prologue_call_count);
CHECK_EQ(2, epilogue_call_count);
CHECK_EQ(1, prologue_call_count_second);
CHECK_EQ(1, epilogue_call_count_second);
v8::V8::RemoveGCPrologueCallback(PrologueCallback);
v8::V8::RemoveGCEpilogueCallback(EpilogueCallback);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(2, prologue_call_count);
CHECK_EQ(2, epilogue_call_count);
CHECK_EQ(2, prologue_call_count_second);
CHECK_EQ(2, epilogue_call_count_second);
v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond);
v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(2, prologue_call_count);
CHECK_EQ(2, epilogue_call_count);
CHECK_EQ(2, prologue_call_count_second);
@@ -13694,7 +14745,7 @@ THREADED_TEST(RoundRobinGetFromCache) {
" for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);"
" for (var i = 0; i < 16; i++) {"
" var v = %_GetFromCache(0, keys[i]);"
- " if (v !== values[i])"
+ " if (v.toString() !== values[i].toString())"
" return 'Wrong value for ' + "
" keys[i] + ': ' + v + ' vs. ' + values[i];"
" };"
@@ -13840,7 +14891,7 @@ THREADED_TEST(TwoByteStringInAsciiCons) {
void FailedAccessCheckCallbackGC(Local<v8::Object> target,
v8::AccessType type,
Local<v8::Value> data) {
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
}
@@ -14414,7 +15465,7 @@ TEST(DontDeleteCellLoadIC) {
"})()",
"ReferenceError: cell is not defined");
CompileRun("cell = \"new_second\";");
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
ExpectString("readCell()", "new_second");
ExpectString("readCell()", "new_second");
}
@@ -14535,8 +15586,8 @@ TEST(RegExp) {
// RegExps are objects on which you can set properties.
re->Set(v8_str("property"), v8::Integer::New(32));
- v8::Handle<v8::Value> value = CompileRun("re.property");
- ASSERT_EQ(32, value->Int32Value());
+ v8::Handle<v8::Value> value(CompileRun("re.property"));
+ CHECK_EQ(32, value->Int32Value());
v8::TryCatch try_catch;
re = v8::RegExp::New(v8_str("foo["), v8::RegExp::kNone);
@@ -14887,10 +15938,12 @@ THREADED_TEST(AllowCodeGenFromStrings) {
LocalContext context;
// eval and the Function constructor allowed by default.
+ CHECK(context->IsCodeGenerationFromStringsAllowed());
CheckCodeGenerationAllowed();
// Disallow eval and the Function constructor.
context->AllowCodeGenerationFromStrings(false);
+ CHECK(!context->IsCodeGenerationFromStringsAllowed());
CheckCodeGenerationDisallowed();
// Allow again.
@@ -14900,10 +15953,12 @@ THREADED_TEST(AllowCodeGenFromStrings) {
// Disallow but setting a global callback that will allow the calls.
context->AllowCodeGenerationFromStrings(false);
V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationAllowed);
+ CHECK(!context->IsCodeGenerationFromStringsAllowed());
CheckCodeGenerationAllowed();
// Set a callback that disallows the code generation.
V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationDisallowed);
+ CHECK(!context->IsCodeGenerationFromStringsAllowed());
CheckCodeGenerationDisallowed();
}
@@ -15182,3 +16237,167 @@ THREADED_TEST(ForeignFunctionReceiver) {
foreign_context.Dispose();
}
+
+
+uint8_t callback_fired = 0;
+
+
+void CallCompletedCallback1() {
+ i::OS::Print("Firing callback 1.\n");
+ callback_fired ^= 1; // Toggle first bit.
+}
+
+
+void CallCompletedCallback2() {
+ i::OS::Print("Firing callback 2.\n");
+ callback_fired ^= 2; // Toggle second bit.
+}
+
+
+Handle<Value> RecursiveCall(const Arguments& args) {
+ int32_t level = args[0]->Int32Value();
+ if (level < 3) {
+ level++;
+ i::OS::Print("Entering recursion level %d.\n", level);
+ char script[64];
+ i::Vector<char> script_vector(script, sizeof(script));
+ i::OS::SNPrintF(script_vector, "recursion(%d)", level);
+ CompileRun(script_vector.start());
+ i::OS::Print("Leaving recursion level %d.\n", level);
+ CHECK_EQ(0, callback_fired);
+ } else {
+ i::OS::Print("Recursion ends.\n");
+ CHECK_EQ(0, callback_fired);
+ }
+ return Undefined();
+}
+
+
+TEST(CallCompletedCallback) {
+ v8::HandleScope scope;
+ LocalContext env;
+ v8::Handle<v8::FunctionTemplate> recursive_runtime =
+ v8::FunctionTemplate::New(RecursiveCall);
+ env->Global()->Set(v8_str("recursion"),
+ recursive_runtime->GetFunction());
+ // Adding the same callback a second time has no effect.
+ v8::V8::AddCallCompletedCallback(CallCompletedCallback1);
+ v8::V8::AddCallCompletedCallback(CallCompletedCallback1);
+ v8::V8::AddCallCompletedCallback(CallCompletedCallback2);
+ i::OS::Print("--- Script (1) ---\n");
+ Local<Script> script =
+ v8::Script::Compile(v8::String::New("recursion(0)"));
+ script->Run();
+ CHECK_EQ(3, callback_fired);
+
+ i::OS::Print("\n--- Script (2) ---\n");
+ callback_fired = 0;
+ v8::V8::RemoveCallCompletedCallback(CallCompletedCallback1);
+ script->Run();
+ CHECK_EQ(2, callback_fired);
+
+ i::OS::Print("\n--- Function ---\n");
+ callback_fired = 0;
+ Local<Function> recursive_function =
+ Local<Function>::Cast(env->Global()->Get(v8_str("recursion")));
+ v8::Handle<Value> args[] = { v8_num(0) };
+ recursive_function->Call(env->Global(), 1, args);
+ CHECK_EQ(2, callback_fired);
+}
+
+
+void CallCompletedCallbackNoException() {
+ v8::HandleScope scope;
+ CompileRun("1+1;");
+}
+
+
+void CallCompletedCallbackException() {
+ v8::HandleScope scope;
+ CompileRun("throw 'second exception';");
+}
+
+
+TEST(CallCompletedCallbackOneException) {
+ v8::HandleScope scope;
+ LocalContext env;
+ v8::V8::AddCallCompletedCallback(CallCompletedCallbackNoException);
+ CompileRun("throw 'exception';");
+}
+
+
+TEST(CallCompletedCallbackTwoExceptions) {
+ v8::HandleScope scope;
+ LocalContext env;
+ v8::V8::AddCallCompletedCallback(CallCompletedCallbackException);
+ CompileRun("throw 'first exception';");
+}
+
+
+static int probes_counter = 0;
+static int misses_counter = 0;
+static int updates_counter = 0;
+
+
+static int* LookupCounter(const char* name) {
+ if (strcmp(name, "c:V8.MegamorphicStubCacheProbes") == 0) {
+ return &probes_counter;
+ } else if (strcmp(name, "c:V8.MegamorphicStubCacheMisses") == 0) {
+ return &misses_counter;
+ } else if (strcmp(name, "c:V8.MegamorphicStubCacheUpdates") == 0) {
+ return &updates_counter;
+ }
+ return NULL;
+}
+
+
+static const char* kMegamorphicTestProgram =
+ "function ClassA() { };"
+ "function ClassB() { };"
+ "ClassA.prototype.foo = function() { };"
+ "ClassB.prototype.foo = function() { };"
+ "function fooify(obj) { obj.foo(); };"
+ "var a = new ClassA();"
+ "var b = new ClassB();"
+ "for (var i = 0; i < 10000; i++) {"
+ " fooify(a);"
+ " fooify(b);"
+ "}";
+
+
+static void StubCacheHelper(bool primary) {
+ V8::SetCounterFunction(LookupCounter);
+ USE(kMegamorphicTestProgram);
+#ifdef DEBUG
+ i::FLAG_native_code_counters = true;
+ if (primary) {
+ i::FLAG_test_primary_stub_cache = true;
+ } else {
+ i::FLAG_test_secondary_stub_cache = true;
+ }
+ i::FLAG_crankshaft = false;
+ v8::HandleScope scope;
+ LocalContext env;
+ int initial_probes = probes_counter;
+ int initial_misses = misses_counter;
+ int initial_updates = updates_counter;
+ CompileRun(kMegamorphicTestProgram);
+ int probes = probes_counter - initial_probes;
+ int misses = misses_counter - initial_misses;
+ int updates = updates_counter - initial_updates;
+ CHECK_LT(updates, 10);
+ CHECK_LT(misses, 10);
+ CHECK_GE(probes, 10000);
+#endif
+}
+
+
+TEST(SecondaryStubCache) {
+ StubCacheHelper(true);
+}
+
+
+TEST(PrimaryStubCache) {
+ StubCacheHelper(false);
+}
+
diff --git a/test/cctest/test-assembler-ia32.cc b/test/cctest/test-assembler-ia32.cc
index 839b7f56..815e6184 100644
--- a/test/cctest/test-assembler-ia32.cc
+++ b/test/cctest/test-assembler-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// 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:
@@ -93,15 +93,15 @@ TEST(AssemblerIa321) {
Label L, C;
__ mov(edx, Operand(esp, 4));
- __ xor_(eax, Operand(eax)); // clear eax
+ __ xor_(eax, eax); // clear eax
__ jmp(&C);
__ bind(&L);
- __ add(eax, Operand(edx));
- __ sub(Operand(edx), Immediate(1));
+ __ add(eax, edx);
+ __ sub(edx, Immediate(1));
__ bind(&C);
- __ test(edx, Operand(edx));
+ __ test(edx, edx);
__ j(not_zero, &L);
__ ret(0);
@@ -135,11 +135,11 @@ TEST(AssemblerIa322) {
__ jmp(&C);
__ bind(&L);
- __ imul(eax, Operand(edx));
- __ sub(Operand(edx), Immediate(1));
+ __ imul(eax, edx);
+ __ sub(edx, Immediate(1));
__ bind(&C);
- __ test(edx, Operand(edx));
+ __ test(edx, edx);
__ j(not_zero, &L);
__ ret(0);
@@ -275,10 +275,10 @@ TEST(AssemblerIa326) {
__ subsd(xmm0, xmm1);
__ divsd(xmm0, xmm1);
// Copy xmm0 to st(0) using eight bytes of stack.
- __ sub(Operand(esp), Immediate(8));
+ __ sub(esp, Immediate(8));
__ movdbl(Operand(esp, 0), xmm0);
__ fld_d(Operand(esp, 0));
- __ add(Operand(esp), Immediate(8));
+ __ add(esp, Immediate(8));
__ ret(0);
CodeDesc desc;
@@ -314,12 +314,12 @@ TEST(AssemblerIa328) {
v8::internal::byte buffer[256];
Assembler assm(Isolate::Current(), buffer, sizeof buffer);
__ mov(eax, Operand(esp, 4));
- __ cvtsi2sd(xmm0, Operand(eax));
+ __ cvtsi2sd(xmm0, eax);
// Copy xmm0 to st(0) using eight bytes of stack.
- __ sub(Operand(esp), Immediate(8));
+ __ sub(esp, Immediate(8));
__ movdbl(Operand(esp, 0), xmm0);
__ fld_d(Operand(esp, 0));
- __ add(Operand(esp), Immediate(8));
+ __ add(esp, Immediate(8));
__ ret(0);
CodeDesc desc;
assm.GetCode(&desc);
@@ -408,4 +408,72 @@ TEST(AssemblerIa3210) {
__ nop();
}
+
+TEST(AssemblerMultiByteNop) {
+ InitializeVM();
+ v8::HandleScope scope;
+ v8::internal::byte buffer[1024];
+ Assembler assm(Isolate::Current(), buffer, sizeof(buffer));
+ __ push(ebx);
+ __ push(ecx);
+ __ push(edx);
+ __ push(edi);
+ __ push(esi);
+ __ mov(eax, 1);
+ __ mov(ebx, 2);
+ __ mov(ecx, 3);
+ __ mov(edx, 4);
+ __ mov(edi, 5);
+ __ mov(esi, 6);
+ for (int i = 0; i < 16; i++) {
+ int before = assm.pc_offset();
+ __ Nop(i);
+ CHECK_EQ(assm.pc_offset() - before, i);
+ }
+
+ Label fail;
+ __ cmp(eax, 1);
+ __ j(not_equal, &fail);
+ __ cmp(ebx, 2);
+ __ j(not_equal, &fail);
+ __ cmp(ecx, 3);
+ __ j(not_equal, &fail);
+ __ cmp(edx, 4);
+ __ j(not_equal, &fail);
+ __ cmp(edi, 5);
+ __ j(not_equal, &fail);
+ __ cmp(esi, 6);
+ __ j(not_equal, &fail);
+ __ mov(eax, 42);
+ __ pop(esi);
+ __ pop(edi);
+ __ pop(edx);
+ __ pop(ecx);
+ __ pop(ebx);
+ __ ret(0);
+ __ bind(&fail);
+ __ mov(eax, 13);
+ __ pop(esi);
+ __ pop(edi);
+ __ pop(edx);
+ __ pop(ecx);
+ __ pop(ebx);
+ __ ret(0);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Code* code = Code::cast(HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked());
+ CHECK(code->IsCode());
+
+ F0 f = FUNCTION_CAST<F0>(code->entry());
+ int res = f();
+ CHECK_EQ(42, res);
+}
+
+
+
+
#undef __
diff --git a/test/cctest/test-assembler-mips.cc b/test/cctest/test-assembler-mips.cc
index a6c76f03..6985433d 100644
--- a/test/cctest/test-assembler-mips.cc
+++ b/test/cctest/test-assembler-mips.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -219,21 +219,21 @@ TEST(MIPS2) {
// Bit twiddling instructions & conditional moves.
// Uses t0-t7 as set above.
- __ clz(v0, t0); // 29
- __ clz(v1, t1); // 19
+ __ Clz(v0, t0); // 29
+ __ Clz(v1, t1); // 19
__ addu(v0, v0, v1); // 48
- __ clz(v1, t2); // 3
+ __ Clz(v1, t2); // 3
__ addu(v0, v0, v1); // 51
- __ clz(v1, t7); // 0
+ __ Clz(v1, t7); // 0
__ addu(v0, v0, v1); // 51
__ Branch(&error, ne, v0, Operand(51));
- __ movn(a0, t3, t0); // Move a0<-t3 (t0 is NOT 0).
+ __ Movn(a0, t3, t0); // Move a0<-t3 (t0 is NOT 0).
__ Ins(a0, t1, 12, 8); // 0x7ff34fff
__ Branch(&error, ne, a0, Operand(0x7ff34fff));
- __ movz(a0, t6, t7); // a0 not updated (t7 is NOT 0).
+ __ Movz(a0, t6, t7); // a0 not updated (t7 is NOT 0).
__ Ext(a1, a0, 8, 12); // 0x34f
__ Branch(&error, ne, a1, Operand(0x34f));
- __ movz(a0, t6, v1); // a0<-t6, v0 is 0, from 8 instr back.
+ __ Movz(a0, t6, v1); // a0<-t6, v0 is 0, from 8 instr back.
__ Branch(&error, ne, a0, Operand(t6));
// Everything was correctly executed. Load the expected result.
@@ -579,8 +579,13 @@ TEST(MIPS7) {
__ bind(&neither_is_nan);
- __ c(OLT, D, f6, f4, 2);
- __ bc1t(&less_than, 2);
+ if (kArchVariant == kLoongson) {
+ __ c(OLT, D, f6, f4);
+ __ bc1t(&less_than);
+ } else {
+ __ c(OLT, D, f6, f4, 2);
+ __ bc1t(&less_than, 2);
+ }
__ nop();
__ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
__ Branch(&outa_here);
@@ -774,7 +779,7 @@ TEST(MIPS10) {
Assembler assm(Isolate::Current(), NULL, 0);
Label L, C;
- if (CpuFeatures::IsSupported(FPU) && mips32r2) {
+ if (CpuFeatures::IsSupported(FPU) && kArchVariant == kMips32r2) {
CpuFeatures::Scope scope(FPU);
// Load all structure elements to registers.
diff --git a/test/cctest/test-assembler-x64.cc b/test/cctest/test-assembler-x64.cc
index 28f7c9b7..d81923fa 100644
--- a/test/cctest/test-assembler-x64.cc
+++ b/test/cctest/test-assembler-x64.cc
@@ -36,6 +36,7 @@
#include "cctest.h"
using v8::internal::Assembler;
+using v8::internal::Code;
using v8::internal::CodeDesc;
using v8::internal::FUNCTION_CAST;
using v8::internal::Immediate;
@@ -53,6 +54,7 @@ using v8::internal::r15;
using v8::internal::r8;
using v8::internal::r9;
using v8::internal::rax;
+using v8::internal::rbx;
using v8::internal::rbp;
using v8::internal::rcx;
using v8::internal::rdi;
@@ -86,8 +88,18 @@ static const v8::internal::Register arg2 = rsi;
#define __ assm.
+static v8::Persistent<v8::Context> env;
+
+
+static void InitializeVM() {
+ if (env.IsEmpty()) {
+ env = v8::Context::New();
+ }
+}
+
+
TEST(AssemblerX64ReturnOperation) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -109,7 +121,7 @@ TEST(AssemblerX64ReturnOperation) {
}
TEST(AssemblerX64StackOperations) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -141,7 +153,7 @@ TEST(AssemblerX64StackOperations) {
}
TEST(AssemblerX64ArithmeticOperations) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -163,7 +175,7 @@ TEST(AssemblerX64ArithmeticOperations) {
}
TEST(AssemblerX64ImulOperation) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -191,7 +203,7 @@ TEST(AssemblerX64ImulOperation) {
}
TEST(AssemblerX64MemoryOperands) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -225,7 +237,7 @@ TEST(AssemblerX64MemoryOperands) {
}
TEST(AssemblerX64ControlFlow) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -254,7 +266,7 @@ TEST(AssemblerX64ControlFlow) {
}
TEST(AssemblerX64LoopImmediates) {
- OS::Setup();
+ OS::SetUp();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
@@ -359,4 +371,73 @@ TEST(AssemblerX64LabelChaining) {
__ nop();
}
+
+TEST(AssemblerMultiByteNop) {
+ InitializeVM();
+ v8::HandleScope scope;
+ v8::internal::byte buffer[1024];
+ Assembler assm(Isolate::Current(), buffer, sizeof(buffer));
+ __ push(rbx);
+ __ push(rcx);
+ __ push(rdx);
+ __ push(rdi);
+ __ push(rsi);
+ __ movq(rax, Immediate(1));
+ __ movq(rbx, Immediate(2));
+ __ movq(rcx, Immediate(3));
+ __ movq(rdx, Immediate(4));
+ __ movq(rdi, Immediate(5));
+ __ movq(rsi, Immediate(6));
+ for (int i = 0; i < 16; i++) {
+ int before = assm.pc_offset();
+ __ Nop(i);
+ CHECK_EQ(assm.pc_offset() - before, i);
+ }
+
+ Label fail;
+ __ cmpq(rax, Immediate(1));
+ __ j(not_equal, &fail);
+ __ cmpq(rbx, Immediate(2));
+ __ j(not_equal, &fail);
+ __ cmpq(rcx, Immediate(3));
+ __ j(not_equal, &fail);
+ __ cmpq(rdx, Immediate(4));
+ __ j(not_equal, &fail);
+ __ cmpq(rdi, Immediate(5));
+ __ j(not_equal, &fail);
+ __ cmpq(rsi, Immediate(6));
+ __ j(not_equal, &fail);
+ __ movq(rax, Immediate(42));
+ __ pop(rsi);
+ __ pop(rdi);
+ __ pop(rdx);
+ __ pop(rcx);
+ __ pop(rbx);
+ __ ret(0);
+ __ bind(&fail);
+ __ movq(rax, Immediate(13));
+ __ pop(rsi);
+ __ pop(rdi);
+ __ pop(rdx);
+ __ pop(rcx);
+ __ pop(rbx);
+ __ ret(0);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Code* code = Code::cast(HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ v8::internal::Handle<v8::internal::Object>(
+ HEAP->undefined_value()))->ToObjectChecked());
+ CHECK(code->IsCode());
+
+ F0 f = FUNCTION_CAST<F0>(code->entry());
+ int res = f();
+ CHECK_EQ(42, res);
+}
+
+
+
+
#undef __
diff --git a/test/cctest/test-ast.cc b/test/cctest/test-ast.cc
index 2aa72078..80c7fdff 100644
--- a/test/cctest/test-ast.cc
+++ b/test/cctest/test-ast.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -40,7 +40,8 @@ TEST(List) {
CHECK_EQ(0, list->length());
ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
- AstNode* node = new(ZONE) EmptyStatement();
+ AstNodeFactory<AstNullVisitor> factory(Isolate::Current());
+ AstNode* node = factory.NewEmptyStatement();
list->Add(node);
CHECK_EQ(1, list->length());
CHECK_EQ(node, list->at(0));
diff --git a/test/cctest/test-compiler.cc b/test/cctest/test-compiler.cc
index 2d9b0120..9ca0b0a1 100644
--- a/test/cctest/test-compiler.cc
+++ b/test/cctest/test-compiler.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -270,8 +270,7 @@ TEST(UncaughtThrow) {
CHECK(!fun.is_null());
bool has_pending_exception;
Handle<JSObject> global(Isolate::Current()->context()->global());
- Handle<Object> result =
- Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ Execution::Call(fun, global, 0, NULL, &has_pending_exception);
CHECK(has_pending_exception);
CHECK_EQ(42.0, Isolate::Current()->pending_exception()->
ToObjectChecked()->Number());
@@ -305,10 +304,11 @@ TEST(C2JSFrames) {
Handle<Object> fun1(fun1_object->ToObjectChecked());
CHECK(fun1->IsJSFunction());
- Object** argv[1] = {
- Handle<Object>::cast(FACTORY->LookupAsciiSymbol("hello")).location()
- };
- Execution::Call(Handle<JSFunction>::cast(fun1), global, 1, argv,
+ Handle<Object> argv[] = { FACTORY->LookupAsciiSymbol("hello") };
+ Execution::Call(Handle<JSFunction>::cast(fun1),
+ global,
+ ARRAY_SIZE(argv),
+ argv,
&has_pending_exception);
CHECK(!has_pending_exception);
}
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index f567a0f7..b10e6889 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -216,7 +216,7 @@ TEST(TickEvents) {
TEST(CrashIfStoppingLastNonExistentProfile) {
InitializeVM();
TestSetup test_setup;
- CpuProfiler::Setup();
+ CpuProfiler::SetUp();
CpuProfiler::StartProfiling("1");
CpuProfiler::StopProfiling("2");
CpuProfiler::StartProfiling("1");
@@ -268,7 +268,7 @@ TEST(Issue1398) {
TEST(DeleteAllCpuProfiles) {
InitializeVM();
TestSetup test_setup;
- CpuProfiler::Setup();
+ CpuProfiler::SetUp();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
CpuProfiler::DeleteAllProfiles();
CHECK_EQ(0, CpuProfiler::GetProfilesCount());
diff --git a/test/cctest/test-dataflow.cc b/test/cctest/test-dataflow.cc
index ad48f550..a63008d2 100644
--- a/test/cctest/test-dataflow.cc
+++ b/test/cctest/test-dataflow.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -36,16 +36,17 @@ using namespace v8::internal;
TEST(BitVector) {
v8::internal::V8::Initialize(NULL);
- ZoneScope zone(Isolate::Current(), DELETE_ON_EXIT);
+ ZoneScope zone_scope(Isolate::Current(), DELETE_ON_EXIT);
+ Zone* zone = ZONE;
{
- BitVector v(15);
+ BitVector v(15, zone);
v.Add(1);
CHECK(v.Contains(1));
v.Remove(0);
CHECK(!v.Contains(0));
v.Add(0);
v.Add(1);
- BitVector w(15);
+ BitVector w(15, zone);
w.Add(1);
v.Intersect(w);
CHECK(!v.Contains(0));
@@ -53,7 +54,7 @@ TEST(BitVector) {
}
{
- BitVector v(64);
+ BitVector v(64, zone);
v.Add(27);
v.Add(30);
v.Add(31);
@@ -71,9 +72,9 @@ TEST(BitVector) {
}
{
- BitVector v(15);
+ BitVector v(15, zone);
v.Add(0);
- BitVector w(15);
+ BitVector w(15, zone);
w.Add(1);
v.Union(w);
CHECK(v.Contains(0));
@@ -81,13 +82,13 @@ TEST(BitVector) {
}
{
- BitVector v(15);
+ BitVector v(15, zone);
v.Add(0);
- BitVector w(15);
+ BitVector w(15, zone);
w = v;
CHECK(w.Contains(0));
w.Add(1);
- BitVector u(w);
+ BitVector u(w, zone);
CHECK(u.Contains(0));
CHECK(u.Contains(1));
v.Union(w);
@@ -96,9 +97,9 @@ TEST(BitVector) {
}
{
- BitVector v(35);
+ BitVector v(35, zone);
v.Add(0);
- BitVector w(35);
+ BitVector w(35, zone);
w.Add(33);
v.Union(w);
CHECK(v.Contains(0));
@@ -106,15 +107,15 @@ TEST(BitVector) {
}
{
- BitVector v(35);
+ BitVector v(35, zone);
v.Add(32);
v.Add(33);
- BitVector w(35);
+ BitVector w(35, zone);
w.Add(33);
v.Intersect(w);
CHECK(!v.Contains(32));
CHECK(v.Contains(33));
- BitVector r(35);
+ BitVector r(35, zone);
r.CopyFrom(v);
CHECK(!r.Contains(32));
CHECK(r.Contains(33));
diff --git a/test/cctest/test-date.cc b/test/cctest/test-date.cc
new file mode 100644
index 00000000..903a63a5
--- /dev/null
+++ b/test/cctest/test-date.cc
@@ -0,0 +1,168 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+
+#include "global-handles.h"
+#include "snapshot.h"
+#include "cctest.h"
+
+using namespace v8::internal;
+
+class DateCacheMock: public DateCache {
+ public:
+ struct Rule {
+ int year, start_month, start_day, end_month, end_day, offset_sec;
+ };
+
+ DateCacheMock(int local_offset, Rule* rules, int rules_count)
+ : local_offset_(local_offset), rules_(rules), rules_count_(rules_count) {}
+
+ protected:
+ virtual int GetDaylightSavingsOffsetFromOS(int64_t time_sec) {
+ int days = DaysFromTime(time_sec * 1000);
+ int time_in_day_sec = TimeInDay(time_sec * 1000, days) / 1000;
+ int year, month, day;
+ YearMonthDayFromDays(days, &year, &month, &day);
+ Rule* rule = FindRuleFor(year, month, day, time_in_day_sec);
+ return rule == NULL ? 0 : rule->offset_sec * 1000;
+ }
+
+
+ virtual int GetLocalOffsetFromOS() {
+ return local_offset_;
+ }
+
+ private:
+ Rule* FindRuleFor(int year, int month, int day, int time_in_day_sec) {
+ Rule* result = NULL;
+ for (int i = 0; i < rules_count_; i++)
+ if (Match(&rules_[i], year, month, day, time_in_day_sec)) {
+ result = &rules_[i];
+ }
+ return result;
+ }
+
+
+ bool Match(Rule* rule, int year, int month, int day, int time_in_day_sec) {
+ if (rule->year != 0 && rule->year != year) return false;
+ if (rule->start_month > month) return false;
+ if (rule->end_month < month) return false;
+ int start_day = ComputeRuleDay(year, rule->start_month, rule->start_day);
+ if (rule->start_month == month && start_day > day) return false;
+ if (rule->start_month == month && start_day == day &&
+ 2 * 3600 > time_in_day_sec)
+ return false;
+ int end_day = ComputeRuleDay(year, rule->end_month, rule->end_day);
+ if (rule->end_month == month && end_day < day) return false;
+ if (rule->end_month == month && end_day == day &&
+ 2 * 3600 <= time_in_day_sec)
+ return false;
+ return true;
+ }
+
+
+ int ComputeRuleDay(int year, int month, int day) {
+ if (day != 0) return day;
+ int days = DaysFromYearMonth(year, month);
+ // Find the first Sunday of the month.
+ while (Weekday(days + day) != 6) day++;
+ return day + 1;
+ }
+
+ int local_offset_;
+ Rule* rules_;
+ int rules_count_;
+};
+
+static int64_t TimeFromYearMonthDay(DateCache* date_cache,
+ int year,
+ int month,
+ int day) {
+ int64_t result = date_cache->DaysFromYearMonth(year, month);
+ return (result + day - 1) * DateCache::kMsPerDay;
+}
+
+static void CheckDST(int64_t time) {
+ Isolate* isolate = Isolate::Current();
+ DateCache* date_cache = isolate->date_cache();
+ int64_t actual = date_cache->ToLocal(time);
+ int64_t expected = time + date_cache->GetLocalOffsetFromOS() +
+ date_cache->GetDaylightSavingsOffsetFromOS(time / 1000);
+ CHECK_EQ(actual, expected);
+}
+
+
+TEST(DaylightSavingsTime) {
+ LocalContext context;
+ v8::HandleScope scope;
+ Isolate* isolate = Isolate::Current();
+ DateCacheMock::Rule rules[] = {
+ {0, 2, 0, 10, 0, 3600}, // DST from March to November in any year.
+ {2010, 2, 0, 7, 20, 3600}, // DST from March to August 20 in 2010.
+ {2010, 7, 20, 8, 10, 0}, // No DST from August 20 to September 10 in 2010.
+ {2010, 8, 10, 10, 0, 3600}, // DST from September 10 to November in 2010.
+ };
+
+ int local_offset_ms = -36000000; // -10 hours.
+
+ DateCacheMock* date_cache =
+ new DateCacheMock(local_offset_ms, rules, ARRAY_SIZE(rules));
+
+ isolate->set_date_cache(date_cache);
+
+ int64_t start_of_2010 = TimeFromYearMonthDay(date_cache, 2010, 0, 1);
+ int64_t start_of_2011 = TimeFromYearMonthDay(date_cache, 2011, 0, 1);
+ int64_t august_20 = TimeFromYearMonthDay(date_cache, 2010, 7, 20);
+ int64_t september_10 = TimeFromYearMonthDay(date_cache, 2010, 8, 10);
+ CheckDST((august_20 + september_10) / 2);
+ CheckDST(september_10);
+ CheckDST(september_10 + 2 * 3600);
+ CheckDST(september_10 + 2 * 3600 - 1000);
+ CheckDST(august_20 + 2 * 3600);
+ CheckDST(august_20 + 2 * 3600 - 1000);
+ CheckDST(august_20);
+ // Check each day of 2010.
+ for (int64_t time = start_of_2011 + 2 * 3600;
+ time >= start_of_2010;
+ time -= DateCache::kMsPerDay) {
+ CheckDST(time);
+ CheckDST(time - 1000);
+ CheckDST(time + 1000);
+ }
+ // Check one day from 2010 to 2100.
+ for (int year = 2100; year >= 2010; year--) {
+ CheckDST(TimeFromYearMonthDay(date_cache, year, 5, 5));
+ }
+ CheckDST((august_20 + september_10) / 2);
+ CheckDST(september_10);
+ CheckDST(september_10 + 2 * 3600);
+ CheckDST(september_10 + 2 * 3600 - 1000);
+ CheckDST(august_20 + 2 * 3600);
+ CheckDST(august_20 + 2 * 3600 - 1000);
+ CheckDST(august_20);
+}
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 45da6dc0..ffa84581 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -409,11 +409,8 @@ Handle<FixedArray> GetDebuggedFunctions() {
static Handle<Code> ComputeCallDebugBreak(int argc) {
- CALL_HEAP_FUNCTION(
- v8::internal::Isolate::Current(),
- v8::internal::Isolate::Current()->stub_cache()->ComputeCallDebugBreak(
- argc, Code::CALL_IC),
- Code);
+ return Isolate::Current()->stub_cache()->ComputeCallDebugBreak(argc,
+ Code::CALL_IC);
}
@@ -425,8 +422,8 @@ void CheckDebuggerUnloaded(bool check_functions) {
CHECK_EQ(NULL, Isolate::Current()->debug()->debug_info_list_);
// Collect garbage to ensure weak handles are cleared.
- HEAP->CollectAllGarbage(false);
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask);
// Iterate the head and check that there are no debugger related objects left.
HeapIterator iterator;
@@ -859,7 +856,7 @@ static void DebugEventRemoveBreakPoint(v8::DebugEvent event,
if (event == v8::Break) {
break_point_hit_count++;
- v8::Handle<v8::Function> fun = v8::Handle<v8::Function>::Cast(data);
+ CHECK(data->IsFunction());
ClearBreakPoint(debug_event_remove_break_point);
}
}
@@ -944,7 +941,7 @@ static void DebugEventBreakPointCollectGarbage(
HEAP->CollectGarbage(v8::internal::NEW_SPACE);
} else {
// Mark sweep compact.
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
}
}
}
@@ -1417,8 +1414,7 @@ TEST(GCDuringBreakPointProcessing) {
// Call the function three times with different garbage collections in between
// and make sure that the break point survives.
static void CallAndGC(v8::Local<v8::Object> recv,
- v8::Local<v8::Function> f,
- bool force_compaction) {
+ v8::Local<v8::Function> f) {
break_point_hit_count = 0;
for (int i = 0; i < 3; i++) {
@@ -1432,14 +1428,15 @@ static void CallAndGC(v8::Local<v8::Object> recv,
CHECK_EQ(2 + i * 3, break_point_hit_count);
// Mark sweep (and perhaps compact) and call function.
- HEAP->CollectAllGarbage(force_compaction);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
f->Call(recv, 0, NULL);
CHECK_EQ(3 + i * 3, break_point_hit_count);
}
}
-static void TestBreakPointSurviveGC(bool force_compaction) {
+// Test that a break point can be set at a return store location.
+TEST(BreakPointSurviveGC) {
break_point_hit_count = 0;
v8::HandleScope scope;
DebugLocalContext env;
@@ -1450,50 +1447,45 @@ static void TestBreakPointSurviveGC(bool force_compaction) {
// Test IC store break point with garbage collection.
{
- v8::Local<v8::Function> bar =
- CompileFunction(&env, "function foo(){}", "foo");
+ CompileFunction(&env, "function foo(){}", "foo");
foo = CompileFunction(&env, "function foo(){bar=0;}", "foo");
SetBreakPoint(foo, 0);
}
- CallAndGC(env->Global(), foo, force_compaction);
+ CallAndGC(env->Global(), foo);
// Test IC load break point with garbage collection.
{
- v8::Local<v8::Function> bar =
- CompileFunction(&env, "function foo(){}", "foo");
+ CompileFunction(&env, "function foo(){}", "foo");
foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo");
SetBreakPoint(foo, 0);
}
- CallAndGC(env->Global(), foo, force_compaction);
+ CallAndGC(env->Global(), foo);
// Test IC call break point with garbage collection.
{
- v8::Local<v8::Function> bar =
- CompileFunction(&env, "function foo(){}", "foo");
+ CompileFunction(&env, "function foo(){}", "foo");
foo = CompileFunction(&env,
"function bar(){};function foo(){bar();}",
"foo");
SetBreakPoint(foo, 0);
}
- CallAndGC(env->Global(), foo, force_compaction);
+ CallAndGC(env->Global(), foo);
// Test return break point with garbage collection.
{
- v8::Local<v8::Function> bar =
- CompileFunction(&env, "function foo(){}", "foo");
+ CompileFunction(&env, "function foo(){}", "foo");
foo = CompileFunction(&env, "function foo(){}", "foo");
SetBreakPoint(foo, 0);
}
- CallAndGC(env->Global(), foo, force_compaction);
+ CallAndGC(env->Global(), foo);
// Test non IC break point with garbage collection.
{
- v8::Local<v8::Function> bar =
- CompileFunction(&env, "function foo(){}", "foo");
+ CompileFunction(&env, "function foo(){}", "foo");
foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo");
SetBreakPoint(foo, 0);
}
- CallAndGC(env->Global(), foo, force_compaction);
+ CallAndGC(env->Global(), foo);
v8::Debug::SetDebugEventListener(NULL);
@@ -1501,13 +1493,6 @@ static void TestBreakPointSurviveGC(bool force_compaction) {
}
-// Test that a break point can be set at a return store location.
-TEST(BreakPointSurviveGC) {
- TestBreakPointSurviveGC(false);
- TestBreakPointSurviveGC(true);
-}
-
-
// Test that break points can be set using the global Debug object.
TEST(BreakPointThroughJavaScript) {
break_point_hit_count = 0;
@@ -2259,7 +2244,7 @@ TEST(ScriptBreakPointLineTopLevel) {
}
f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
SetScriptBreakPointByNameFromJS("test.html", 3, -1);
@@ -2753,14 +2738,14 @@ TEST(DebugStepKeyedLoadLoop) {
v8::Handle<v8::Value> args[kArgc] = { a };
foo->Call(env->Global(), kArgc, args);
- // Setup break point and step through the function.
+ // Set up break point and step through the function.
SetBreakPoint(foo, 3);
step_action = StepNext;
break_point_hit_count = 0;
foo->Call(env->Global(), kArgc, args);
// With stepping all break locations are hit.
- CHECK_EQ(33, break_point_hit_count);
+ CHECK_EQ(34, break_point_hit_count);
v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
@@ -2800,14 +2785,14 @@ TEST(DebugStepKeyedStoreLoop) {
v8::Handle<v8::Value> args[kArgc] = { a };
foo->Call(env->Global(), kArgc, args);
- // Setup break point and step through the function.
+ // Set up break point and step through the function.
SetBreakPoint(foo, 3);
step_action = StepNext;
break_point_hit_count = 0;
foo->Call(env->Global(), kArgc, args);
// With stepping all break locations are hit.
- CHECK_EQ(32, break_point_hit_count);
+ CHECK_EQ(33, break_point_hit_count);
v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
@@ -2844,14 +2829,14 @@ TEST(DebugStepNamedLoadLoop) {
// Call function without any break points to ensure inlining is in place.
foo->Call(env->Global(), 0, NULL);
- // Setup break point and step through the function.
+ // Set up break point and step through the function.
SetBreakPoint(foo, 4);
step_action = StepNext;
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
// With stepping all break locations are hit.
- CHECK_EQ(53, break_point_hit_count);
+ CHECK_EQ(54, break_point_hit_count);
v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
@@ -2879,7 +2864,7 @@ static void DoDebugStepNamedStoreLoop(int expected) {
// Call function without any break points to ensure inlining is in place.
foo->Call(env->Global(), 0, NULL);
- // Setup break point and step through the function.
+ // Set up break point and step through the function.
SetBreakPoint(foo, 3);
step_action = StepNext;
break_point_hit_count = 0;
@@ -2895,7 +2880,7 @@ static void DoDebugStepNamedStoreLoop(int expected) {
// Test of the stepping mechanism for named load in a loop.
TEST(DebugStepNamedStoreLoop) {
- DoDebugStepNamedStoreLoop(22);
+ DoDebugStepNamedStoreLoop(23);
}
@@ -3267,7 +3252,7 @@ TEST(DebugStepForContinue) {
v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) };
result = foo->Call(env->Global(), argc, argv_10);
CHECK_EQ(5, result->Int32Value());
- CHECK_EQ(50, break_point_hit_count);
+ CHECK_EQ(51, break_point_hit_count);
// Looping 100 times.
step_action = StepIn;
@@ -3275,7 +3260,7 @@ TEST(DebugStepForContinue) {
v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) };
result = foo->Call(env->Global(), argc, argv_100);
CHECK_EQ(50, result->Int32Value());
- CHECK_EQ(455, break_point_hit_count);
+ CHECK_EQ(456, break_point_hit_count);
// Get rid of the debug event listener.
v8::Debug::SetDebugEventListener(NULL);
@@ -3319,7 +3304,7 @@ TEST(DebugStepForBreak) {
v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(10) };
result = foo->Call(env->Global(), argc, argv_10);
CHECK_EQ(9, result->Int32Value());
- CHECK_EQ(53, break_point_hit_count);
+ CHECK_EQ(54, break_point_hit_count);
// Looping 100 times.
step_action = StepIn;
@@ -3327,7 +3312,7 @@ TEST(DebugStepForBreak) {
v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(100) };
result = foo->Call(env->Global(), argc, argv_100);
CHECK_EQ(99, result->Int32Value());
- CHECK_EQ(503, break_point_hit_count);
+ CHECK_EQ(504, break_point_hit_count);
// Get rid of the debug event listener.
v8::Debug::SetDebugEventListener(NULL);
@@ -3761,8 +3746,7 @@ TEST(BreakOnException) {
v8::internal::Isolate::Current()->TraceException(false);
// Create functions for testing break on exception.
- v8::Local<v8::Function> throws =
- CompileFunction(&env, "function throws(){throw 1;}", "throws");
+ CompileFunction(&env, "function throws(){throw 1;}", "throws");
v8::Local<v8::Function> caught =
CompileFunction(&env,
"function caught(){try {throws();} catch(e) {};}",
@@ -4238,9 +4222,9 @@ TEST(InterceptorPropertyMirror) {
// Get mirrors for the three objects with interceptor.
CompileRun(
- "named_mirror = debug.MakeMirror(intercepted_named);"
- "indexed_mirror = debug.MakeMirror(intercepted_indexed);"
- "both_mirror = debug.MakeMirror(intercepted_both)");
+ "var named_mirror = debug.MakeMirror(intercepted_named);"
+ "var indexed_mirror = debug.MakeMirror(intercepted_indexed);"
+ "var both_mirror = debug.MakeMirror(intercepted_both)");
CHECK(CompileRun(
"named_mirror instanceof debug.ObjectMirror")->BooleanValue());
CHECK(CompileRun(
@@ -4281,7 +4265,7 @@ TEST(InterceptorPropertyMirror) {
CHECK_EQ(5, CompileRun(source)->Int32Value());
// Get the interceptor properties for the object with only named interceptor.
- CompileRun("named_values = named_mirror.properties()");
+ CompileRun("var named_values = named_mirror.properties()");
// Check that the properties are interceptor properties.
for (int i = 0; i < 3; i++) {
@@ -4300,7 +4284,7 @@ TEST(InterceptorPropertyMirror) {
// Get the interceptor properties for the object with only indexed
// interceptor.
- CompileRun("indexed_values = indexed_mirror.properties()");
+ CompileRun("var indexed_values = indexed_mirror.properties()");
// Check that the properties are interceptor properties.
for (int i = 0; i < 2; i++) {
@@ -4312,7 +4296,7 @@ TEST(InterceptorPropertyMirror) {
// Get the interceptor properties for the object with both types of
// interceptors.
- CompileRun("both_values = both_mirror.properties()");
+ CompileRun("var both_values = both_mirror.properties()");
// Check that the properties are interceptor properties.
for (int i = 0; i < 5; i++) {
@@ -4368,10 +4352,10 @@ TEST(HiddenPrototypePropertyMirror) {
// Get mirrors for the four objects.
CompileRun(
- "o0_mirror = debug.MakeMirror(o0);"
- "o1_mirror = debug.MakeMirror(o1);"
- "o2_mirror = debug.MakeMirror(o2);"
- "o3_mirror = debug.MakeMirror(o3)");
+ "var o0_mirror = debug.MakeMirror(o0);"
+ "var o1_mirror = debug.MakeMirror(o1);"
+ "var o2_mirror = debug.MakeMirror(o2);"
+ "var o3_mirror = debug.MakeMirror(o3)");
CHECK(CompileRun("o0_mirror instanceof debug.ObjectMirror")->BooleanValue());
CHECK(CompileRun("o1_mirror instanceof debug.ObjectMirror")->BooleanValue());
CHECK(CompileRun("o2_mirror instanceof debug.ObjectMirror")->BooleanValue());
@@ -4457,11 +4441,11 @@ TEST(NativeGetterPropertyMirror) {
CHECK_EQ(10, CompileRun("instance.x")->Int32Value());
// Get mirror for the object with property getter.
- CompileRun("instance_mirror = debug.MakeMirror(instance);");
+ CompileRun("var instance_mirror = debug.MakeMirror(instance);");
CHECK(CompileRun(
"instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
- CompileRun("named_names = instance_mirror.propertyNames();");
+ CompileRun("var named_names = instance_mirror.propertyNames();");
CHECK_EQ(1, CompileRun("named_names.length")->Int32Value());
CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue());
CHECK(CompileRun(
@@ -4493,7 +4477,7 @@ TEST(NativeGetterThrowingErrorPropertyMirror) {
env->Global()->Set(v8::String::New("instance"), named->NewInstance());
// Get mirror for the object with property getter.
- CompileRun("instance_mirror = debug.MakeMirror(instance);");
+ CompileRun("var instance_mirror = debug.MakeMirror(instance);");
CHECK(CompileRun(
"instance_mirror instanceof debug.ObjectMirror")->BooleanValue());
CompileRun("named_names = instance_mirror.propertyNames();");
@@ -5557,10 +5541,8 @@ TEST(DebuggerUnload) {
v8::HandleScope scope;
// Get the test functions again.
- v8::Local<v8::Function> foo =
- v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
- v8::Local<v8::Function> bar =
- v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
+ v8::Local<v8::Function> foo(v8::Local<v8::Function>::Cast(
+ env->Global()->Get(v8::String::New("foo"))));
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
@@ -5719,7 +5701,7 @@ void HostDispatchV8Thread::Run() {
v8::HandleScope scope;
DebugLocalContext env;
- // Setup message and host dispatch handlers.
+ // Set up message and host dispatch handlers.
v8::Debug::SetMessageHandler2(HostDispatchMessageHandler);
v8::Debug::SetHostDispatchHandler(HostDispatchDispatchHandler, 10 /* ms */);
@@ -5807,7 +5789,7 @@ void DebugMessageDispatchV8Thread::Run() {
v8::HandleScope scope;
DebugLocalContext env;
- // Setup debug message dispatch handler.
+ // Set up debug message dispatch handler.
v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler);
CompileRun("var y = 1 + 2;\n");
@@ -5861,7 +5843,7 @@ TEST(DebuggerAgent) {
bool ok;
// Initialize the socket library.
- i::Socket::Setup();
+ i::Socket::SetUp();
// Test starting and stopping the agent without any client connection.
debugger->StartAgent("test", kPort1);
@@ -5959,7 +5941,7 @@ TEST(DebuggerAgentProtocolOverflowHeader) {
OS::SNPrintF(i::Vector<char>(port_str, kPortBufferLen), "%d", kPort);
// Initialize the socket library.
- i::Socket::Setup();
+ i::Socket::SetUp();
// Create a socket server to receive a debugger agent message.
DebuggerAgentProtocolServerThread* server =
@@ -6037,7 +6019,9 @@ TEST(DebugGetLoadedScripts) {
EmptyExternalStringResource source_ext_str;
v8::Local<v8::String> source = v8::String::NewExternal(&source_ext_str);
- v8::Handle<v8::Script> evil_script = v8::Script::Compile(source);
+ v8::Handle<v8::Script> evil_script(v8::Script::Compile(source));
+ // "use" evil_script to make the compiler happy.
+ (void) evil_script;
Handle<i::ExternalTwoByteString> i_source(
i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source)));
// This situation can happen if source was an external string disposed
@@ -6472,7 +6456,7 @@ TEST(ScriptCollectedEvent) {
// Do garbage collection to ensure that only the script in this test will be
// collected afterwards.
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
script_collected_count = 0;
v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent,
@@ -6484,7 +6468,7 @@ TEST(ScriptCollectedEvent) {
// Do garbage collection to collect the script above which is no longer
// referenced.
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
CHECK_EQ(2, script_collected_count);
@@ -6520,7 +6504,7 @@ TEST(ScriptCollectedEventContext) {
// Do garbage collection to ensure that only the script in this test will be
// collected afterwards.
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
v8::Debug::SetMessageHandler2(ScriptCollectedMessageHandler);
{
@@ -6531,7 +6515,7 @@ TEST(ScriptCollectedEventContext) {
// Do garbage collection to collect the script above which is no longer
// referenced.
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
CHECK_EQ(2, script_collected_message_count);
@@ -6685,7 +6669,7 @@ static void BreakMessageHandler(const v8::Debug::Message& message) {
break_point_hit_count++;
v8::HandleScope scope;
- v8::Handle<v8::String> json = message.GetJSON();
+ message.GetJSON();
SendContinueCommand();
} else if (message.IsEvent() && message.GetEvent() == v8::AfterCompile) {
@@ -6696,7 +6680,7 @@ static void BreakMessageHandler(const v8::Debug::Message& message) {
isolate->stack_guard()->DebugBreak();
// Force serialization to trigger some internal JS execution.
- v8::Handle<v8::String> json = message.GetJSON();
+ message.GetJSON();
// Restore previous state.
if (is_debug_break) {
@@ -6879,7 +6863,7 @@ TEST(DebugBreakFunctionApply) {
foo->Call(env->Global(), 0, NULL);
// When keeping the debug break several break will happen.
- CHECK_EQ(3, break_point_hit_count);
+ CHECK_GT(break_point_hit_count, 1);
v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
@@ -7224,10 +7208,10 @@ static void TestDebugBreakInLoop(const char* loop_head,
// Receive 100 breaks for each test and then terminate JavaScript execution.
static const int kBreaksPerTest = 100;
- for (int i = 0; i < 1 && loop_bodies[i] != NULL; i++) {
+ for (int i = 0; loop_bodies[i] != NULL; i++) {
// Perform a lazy deoptimization after various numbers of breaks
// have been hit.
- for (int j = 0; j < 10; j++) {
+ for (int j = 0; j < 11; j++) {
break_point_hit_count_deoptimize = j;
if (j == 10) {
break_point_hit_count_deoptimize = kBreaksPerTest;
@@ -7302,4 +7286,65 @@ TEST(DebugBreakLoop) {
}
+v8::Local<v8::Script> inline_script;
+
+static void DebugBreakInlineListener(v8::DebugEvent event,
+ v8::Handle<v8::Object> exec_state,
+ v8::Handle<v8::Object> event_data,
+ v8::Handle<v8::Value> data) {
+ if (event != v8::Break) return;
+
+ int expected_frame_count = 4;
+ int expected_line_number[] = {1, 4, 7, 12};
+
+ i::Handle<i::Object> compiled_script = v8::Utils::OpenHandle(*inline_script);
+ i::Handle<i::Script> source_script = i::Handle<i::Script>(i::Script::cast(
+ i::JSFunction::cast(*compiled_script)->shared()->script()));
+
+ int break_id = v8::internal::Isolate::Current()->debug()->break_id();
+ char script[128];
+ i::Vector<char> script_vector(script, sizeof(script));
+ OS::SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id);
+ v8::Local<v8::Value> result = CompileRun(script);
+
+ int frame_count = result->Int32Value();
+ CHECK_EQ(expected_frame_count, frame_count);
+
+ for (int i = 0; i < frame_count; i++) {
+ // The 5. element in the returned array of GetFrameDetails contains the
+ // source position of that frame.
+ OS::SNPrintF(script_vector, "%%GetFrameDetails(%d, %d)[5]", break_id, i);
+ v8::Local<v8::Value> result = CompileRun(script);
+ CHECK_EQ(expected_line_number[i],
+ i::GetScriptLineNumber(source_script, result->Int32Value()));
+ }
+ v8::Debug::SetDebugEventListener(NULL);
+ v8::V8::TerminateExecution();
+}
+
+
+TEST(DebugBreakInline) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope scope;
+ DebugLocalContext env;
+ const char* source =
+ "function debug(b) { \n"
+ " if (b) debugger; \n"
+ "} \n"
+ "function f(b) { \n"
+ " debug(b) \n"
+ "}; \n"
+ "function g(b) { \n"
+ " f(b); \n"
+ "}; \n"
+ "g(false); \n"
+ "g(false); \n"
+ "%OptimizeFunctionOnNextCall(g); \n"
+ "g(true);";
+ v8::Debug::SetDebugEventListener(DebugBreakInlineListener);
+ inline_script = v8::Script::Compile(v8::String::New(source));
+ inline_script->Run();
+}
+
+
#endif // ENABLE_DEBUGGER_SUPPORT
diff --git a/test/cctest/test-decls.cc b/test/cctest/test-decls.cc
index 61983918..aa733c70 100644
--- a/test/cctest/test-decls.cc
+++ b/test/cctest/test-decls.cc
@@ -232,7 +232,7 @@ TEST(Unknown) {
context.Check("const x; x",
1, // access
2, // declaration + initialization
- 2, // declaration + initialization
+ 1, // declaration
EXPECT_RESULT, Undefined());
}
@@ -240,7 +240,7 @@ TEST(Unknown) {
context.Check("const x = 0; x",
1, // access
2, // declaration + initialization
- 2, // declaration + initialization
+ 1, // declaration
EXPECT_RESULT, Undefined()); // SB 0 - BUG 1213579
}
}
@@ -285,18 +285,18 @@ TEST(Present) {
{ PresentPropertyContext context;
context.Check("const x; x",
- 0,
- 0,
+ 1, // access
+ 1, // initialization
1, // (re-)declaration
- EXPECT_EXCEPTION); // x has already been declared!
+ EXPECT_RESULT, Undefined());
}
{ PresentPropertyContext context;
context.Check("const x = 0; x",
- 0,
- 0,
+ 1, // access
+ 1, // initialization
1, // (re-)declaration
- EXPECT_EXCEPTION); // x has already been declared!
+ EXPECT_RESULT, Number::New(0));
}
}
@@ -341,7 +341,7 @@ TEST(Absent) {
context.Check("const x; x",
1, // access
2, // declaration + initialization
- 2, // declaration + initializetion
+ 1, // declaration
EXPECT_RESULT, Undefined());
}
@@ -349,7 +349,7 @@ TEST(Absent) {
context.Check("const x = 0; x",
1, // access
2, // declaration + initialization
- 2, // declaration + initialization
+ 1, // declaration
EXPECT_RESULT, Undefined()); // SB 0 - BUG 1213579
}
@@ -429,18 +429,20 @@ TEST(Appearing) {
{ AppearingPropertyContext context;
context.Check("const x; x",
- 0,
- 1, // declaration
+ 1, // access
2, // declaration + initialization
- EXPECT_EXCEPTION); // x has already been declared!
+ 1, // declaration
+ EXPECT_RESULT, Undefined());
}
{ AppearingPropertyContext context;
context.Check("const x = 0; x",
- 0,
- 1, // declaration
+ 1, // access
2, // declaration + initialization
- EXPECT_EXCEPTION); // x has already been declared!
+ 1, // declaration
+ EXPECT_RESULT, Undefined());
+ // Result is undefined because declaration succeeded but
+ // initialization to 0 failed (due to context behavior).
}
}
@@ -496,9 +498,9 @@ TEST(Reappearing) {
{ ReappearingPropertyContext context;
context.Check("const x; var x = 0",
0,
- 2, // var declaration + const initialization
- 4, // 2 x declaration + 2 x initialization
- EXPECT_EXCEPTION); // x has already been declared!
+ 3, // const declaration+initialization, var initialization
+ 3, // 2 x declaration + var initialization
+ EXPECT_RESULT, Undefined());
}
}
diff --git a/test/cctest/test-deoptimization.cc b/test/cctest/test-deoptimization.cc
index 056c9818..c52c5788 100644
--- a/test/cctest/test-deoptimization.cc
+++ b/test/cctest/test-deoptimization.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2010 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -97,6 +97,13 @@ class AllowNativesSyntaxNoInlining {
};
+// Abort any ongoing incremental marking to make sure that all weak global
+// handle callbacks are processed.
+static void NonIncrementalGC() {
+ HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
+}
+
+
static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
const char* property_name) {
v8::Local<v8::Function> fun =
@@ -107,9 +114,7 @@ static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
TEST(DeoptimizeSimple) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
// Test lazy deoptimization of a simple function.
{
@@ -119,9 +124,9 @@ TEST(DeoptimizeSimple) {
"function h() { %DeoptimizeFunction(f); }"
"function g() { count++; h(); }"
"function f() { g(); };"
- "f();"
- "gc(); gc()");
+ "f();");
}
+ NonIncrementalGC();
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
@@ -135,9 +140,9 @@ TEST(DeoptimizeSimple) {
"var count = 0;"
"function g() { count++; %DeoptimizeFunction(f); f(false); }"
"function f(x) { if (x) { g(); } else { return } };"
- "f(true);"
- "gc(); gc()");
+ "f(true);");
}
+ NonIncrementalGC();
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
@@ -147,9 +152,7 @@ TEST(DeoptimizeSimple) {
TEST(DeoptimizeSimpleWithArguments) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
// Test lazy deoptimization of a simple function with some arguments.
{
@@ -159,9 +162,9 @@ TEST(DeoptimizeSimpleWithArguments) {
"function h(x) { %DeoptimizeFunction(f); }"
"function g(x, y) { count++; h(x); }"
"function f(x, y, z) { g(1,x); y+z; };"
- "f(1, \"2\", false);"
- "gc(); gc()");
+ "f(1, \"2\", false);");
}
+ NonIncrementalGC();
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
@@ -176,9 +179,9 @@ TEST(DeoptimizeSimpleWithArguments) {
"var count = 0;"
"function g(x, y) { count++; %DeoptimizeFunction(f); f(false, 1, y); }"
"function f(x, y, z) { if (x) { g(x, y); } else { return y + z; } };"
- "f(true, 1, \"2\");"
- "gc(); gc()");
+ "f(true, 1, \"2\");");
}
+ NonIncrementalGC();
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
@@ -188,9 +191,7 @@ TEST(DeoptimizeSimpleWithArguments) {
TEST(DeoptimizeSimpleNested) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
// Test lazy deoptimization of a simple function. Have a nested function call
// do the deoptimization.
@@ -202,8 +203,8 @@ TEST(DeoptimizeSimpleNested) {
"function h(x, y, z) { return x + y + z; }"
"function g(z) { count++; %DeoptimizeFunction(f); return z;}"
"function f(x,y,z) { return h(x, y, g(z)); };"
- "result = f(1, 2, 3);"
- "gc(); gc()");
+ "result = f(1, 2, 3);");
+ NonIncrementalGC();
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value());
@@ -215,9 +216,7 @@ TEST(DeoptimizeSimpleNested) {
TEST(DeoptimizeRecursive) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
{
// Test lazy deoptimization of a simple function called recursively. Call
@@ -228,8 +227,9 @@ TEST(DeoptimizeRecursive) {
"var calls = 0;"
"function g() { count++; %DeoptimizeFunction(f); }"
"function f(x) { calls++; if (x > 0) { f(x - 1); } else { g(); } };"
- "f(10); gc(); gc()");
+ "f(10);");
}
+ NonIncrementalGC();
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value());
@@ -237,15 +237,13 @@ TEST(DeoptimizeRecursive) {
v8::Local<v8::Function> fun =
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
- Handle<v8::internal::JSFunction> f = v8::Utils::OpenHandle(*fun);
+ CHECK(!fun.IsEmpty());
}
TEST(DeoptimizeMultiple) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
{
AlwaysOptimizeAllowNativesSyntaxNoInlining options;
@@ -261,9 +259,9 @@ TEST(DeoptimizeMultiple) {
"function f3(x, y, z) { f4(); return x + y + z; };"
"function f2(x, y) { return x + f3(y + 1, y + 1, y + 1) + y; };"
"function f1(x) { return f2(x + 1, x + 1) + x; };"
- "result = f1(1);"
- "gc(); gc()");
+ "result = f1(1);");
}
+ NonIncrementalGC();
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value());
@@ -273,9 +271,7 @@ TEST(DeoptimizeMultiple) {
TEST(DeoptimizeConstructor) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
{
AlwaysOptimizeAllowNativesSyntaxNoInlining options;
@@ -284,9 +280,9 @@ TEST(DeoptimizeConstructor) {
"function g() { count++;"
" %DeoptimizeFunction(f); }"
"function f() { g(); };"
- "result = new f() instanceof f;"
- "gc(); gc()");
+ "result = new f() instanceof f;");
}
+ NonIncrementalGC();
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK(env->Global()->Get(v8_str("result"))->IsTrue());
@@ -301,9 +297,9 @@ TEST(DeoptimizeConstructor) {
" %DeoptimizeFunction(f); }"
"function f(x, y) { this.x = x; g(); this.y = y; };"
"result = new f(1, 2);"
- "result = result.x + result.y;"
- "gc(); gc()");
+ "result = result.x + result.y;");
}
+ NonIncrementalGC();
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value());
@@ -313,9 +309,7 @@ TEST(DeoptimizeConstructor) {
TEST(DeoptimizeConstructorMultiple) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
{
AlwaysOptimizeAllowNativesSyntaxNoInlining options;
@@ -332,9 +326,9 @@ TEST(DeoptimizeConstructorMultiple) {
"function f2(x, y) {"
" this.result = x + new f3(y + 1, y + 1, y + 1).result + y; };"
"function f1(x) { this.result = new f2(x + 1, x + 1).result + x; };"
- "result = new f1(1).result;"
- "gc(); gc()");
+ "result = new f1(1).result;");
}
+ NonIncrementalGC();
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value());
@@ -344,9 +338,7 @@ TEST(DeoptimizeConstructorMultiple) {
TEST(DeoptimizeBinaryOperationADDString) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
const char* f_source = "function f(x, y) { return x + y; };";
@@ -376,9 +368,9 @@ TEST(DeoptimizeBinaryOperationADDString) {
// Call f and force deoptimization while processing the binary operation.
CompileRun("deopt = true;"
- "var result = f('a+', new X());"
- "gc(); gc();");
+ "var result = f('a+', new X());");
}
+ NonIncrementalGC();
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
@@ -428,18 +420,15 @@ static void TestDeoptimizeBinaryOpHelper(LocalContext* env,
// Call f and force deoptimization while processing the binary operation.
CompileRun("deopt = true;"
- "var result = f(7, new X());"
- "gc(); gc();");
-
+ "var result = f(7, new X());");
+ NonIncrementalGC();
CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized());
}
TEST(DeoptimizeBinaryOperationADD) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
TestDeoptimizeBinaryOpHelper(&env, "+");
@@ -451,9 +440,7 @@ TEST(DeoptimizeBinaryOperationADD) {
TEST(DeoptimizeBinaryOperationSUB) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
TestDeoptimizeBinaryOpHelper(&env, "-");
@@ -465,9 +452,7 @@ TEST(DeoptimizeBinaryOperationSUB) {
TEST(DeoptimizeBinaryOperationMUL) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
TestDeoptimizeBinaryOpHelper(&env, "*");
@@ -479,9 +464,7 @@ TEST(DeoptimizeBinaryOperationMUL) {
TEST(DeoptimizeBinaryOperationDIV) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
TestDeoptimizeBinaryOpHelper(&env, "/");
@@ -493,9 +476,7 @@ TEST(DeoptimizeBinaryOperationDIV) {
TEST(DeoptimizeBinaryOperationMOD) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
TestDeoptimizeBinaryOpHelper(&env, "%");
@@ -507,9 +488,7 @@ TEST(DeoptimizeBinaryOperationMOD) {
TEST(DeoptimizeCompare) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
const char* f_source = "function f(x, y) { return x < y; };";
@@ -539,9 +518,9 @@ TEST(DeoptimizeCompare) {
// Call f and force deoptimization while processing the comparison.
CompileRun("deopt = true;"
- "var result = f('a', new X());"
- "gc(); gc();");
+ "var result = f('a', new X());");
}
+ NonIncrementalGC();
CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized());
CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value());
@@ -552,9 +531,7 @@ TEST(DeoptimizeCompare) {
TEST(DeoptimizeLoadICStoreIC) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
// Functions to generate load/store/keyed load/keyed store IC calls.
const char* f1_source = "function f1(x) { return x.y; };";
@@ -618,9 +595,9 @@ TEST(DeoptimizeLoadICStoreIC) {
"var result = f1(new X());"
"g1(new X());"
"f2(new X(), 'z');"
- "g2(new X(), 'z');"
- "gc(); gc();");
+ "g2(new X(), 'z');");
}
+ NonIncrementalGC();
CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized());
CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized());
@@ -634,9 +611,7 @@ TEST(DeoptimizeLoadICStoreIC) {
TEST(DeoptimizeLoadICStoreICNested) {
v8::HandleScope scope;
- const char* extension_list[] = { "v8/gc" };
- v8::ExtensionConfiguration extensions(1, extension_list);
- LocalContext env(&extensions);
+ LocalContext env;
// Functions to generate load/store/keyed load/keyed store IC calls.
const char* f1_source = "function f1(x) { return x.y; };";
@@ -701,9 +676,9 @@ TEST(DeoptimizeLoadICStoreICNested) {
// Call functions and force deoptimization while processing the ics.
CompileRun("deopt = true;"
- "var result = f1(new X());"
- "gc(); gc();");
+ "var result = f1(new X());");
}
+ NonIncrementalGC();
CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized());
CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized());
diff --git a/test/cctest/test-dictionary.cc b/test/cctest/test-dictionary.cc
index 15a854b3..793e228a 100644
--- a/test/cctest/test-dictionary.cc
+++ b/test/cctest/test-dictionary.cc
@@ -38,6 +38,7 @@
using namespace v8::internal;
+
TEST(ObjectHashTable) {
v8::HandleScope scope;
LocalContext context;
@@ -66,7 +67,8 @@ TEST(ObjectHashTable) {
CHECK_EQ(table->NumberOfDeletedElements(), 1);
CHECK_EQ(table->Lookup(*a), HEAP->undefined_value());
- // Keys should map back to their respective values.
+ // Keys should map back to their respective values and also should get
+ // an identity hash code generated.
for (int i = 0; i < 100; i++) {
Handle<JSObject> key = FACTORY->NewJSArray(7);
Handle<JSObject> value = FACTORY->NewJSArray(11);
@@ -74,12 +76,67 @@ TEST(ObjectHashTable) {
CHECK_EQ(table->NumberOfElements(), i + 1);
CHECK_NE(table->FindEntry(*key), ObjectHashTable::kNotFound);
CHECK_EQ(table->Lookup(*key), *value);
+ CHECK(key->GetIdentityHash(OMIT_CREATION)->ToObjectChecked()->IsSmi());
+ }
+
+ // Keys never added to the map which already have an identity hash
+ // code should not be found.
+ for (int i = 0; i < 100; i++) {
+ Handle<JSObject> key = FACTORY->NewJSArray(7);
+ CHECK(key->GetIdentityHash(ALLOW_CREATION)->ToObjectChecked()->IsSmi());
+ CHECK_EQ(table->FindEntry(*key), ObjectHashTable::kNotFound);
+ CHECK_EQ(table->Lookup(*key), HEAP->undefined_value());
+ CHECK(key->GetIdentityHash(OMIT_CREATION)->ToObjectChecked()->IsSmi());
}
- // Keys never added to the map should not be found.
- for (int i = 0; i < 1000; i++) {
- Handle<JSObject> o = FACTORY->NewJSArray(100);
- CHECK_EQ(table->FindEntry(*o), ObjectHashTable::kNotFound);
- CHECK_EQ(table->Lookup(*o), HEAP->undefined_value());
+ // Keys that don't have an identity hash should not be found and also
+ // should not get an identity hash code generated.
+ for (int i = 0; i < 100; i++) {
+ Handle<JSObject> key = FACTORY->NewJSArray(7);
+ CHECK_EQ(table->Lookup(*key), HEAP->undefined_value());
+ CHECK_EQ(key->GetIdentityHash(OMIT_CREATION), HEAP->undefined_value());
}
}
+
+
+#ifdef DEBUG
+TEST(ObjectHashSetCausesGC) {
+ v8::HandleScope scope;
+ LocalContext context;
+ Handle<ObjectHashSet> table = FACTORY->NewObjectHashSet(1);
+ Handle<JSObject> key = FACTORY->NewJSArray(0);
+
+ // Simulate a full heap so that generating an identity hash code
+ // in subsequent calls will request GC.
+ FLAG_gc_interval = 0;
+
+ // Calling Contains() should not cause GC ever.
+ CHECK(!table->Contains(*key));
+
+ // Calling Remove() should not cause GC ever.
+ CHECK(!table->Remove(*key)->IsFailure());
+
+ // Calling Add() should request GC by returning a failure.
+ CHECK(table->Add(*key)->IsRetryAfterGC());
+}
+#endif
+
+
+#ifdef DEBUG
+TEST(ObjectHashTableCausesGC) {
+ v8::HandleScope scope;
+ LocalContext context;
+ Handle<ObjectHashTable> table = FACTORY->NewObjectHashTable(1);
+ Handle<JSObject> key = FACTORY->NewJSArray(0);
+
+ // Simulate a full heap so that generating an identity hash code
+ // in subsequent calls will request GC.
+ FLAG_gc_interval = 0;
+
+ // Calling Lookup() should not cause GC ever.
+ CHECK(table->Lookup(*key)->IsUndefined());
+
+ // Calling Put() should request GC by returning a failure.
+ CHECK(table->Put(*key, *key)->IsRetryAfterGC());
+}
+#endif
diff --git a/test/cctest/test-disasm-arm.cc b/test/cctest/test-disasm-arm.cc
index 032e6bc0..0e9432d9 100644
--- a/test/cctest/test-disasm-arm.cc
+++ b/test/cctest/test-disasm-arm.cc
@@ -69,10 +69,10 @@ bool DisassembleAndCompare(byte* pc, const char* compare_string) {
}
-// Setup V8 to a state where we can at least run the assembler and
+// Set up V8 to a state where we can at least run the assembler and
// disassembler. Declare the variables and allocate the data structures used
// in the rest of the macros.
-#define SETUP() \
+#define SET_UP() \
InitializeVM(); \
v8::HandleScope scope; \
byte *buffer = reinterpret_cast<byte*>(malloc(4*1024)); \
@@ -102,7 +102,7 @@ if (failure) { \
TEST(Type0) {
- SETUP();
+ SET_UP();
COMPARE(and_(r0, r1, Operand(r2)),
"e0010002 and r0, r1, r2");
@@ -329,7 +329,7 @@ TEST(Type0) {
TEST(Type1) {
- SETUP();
+ SET_UP();
COMPARE(and_(r0, r1, Operand(0x00000000)),
"e2010000 and r0, r1, #0");
@@ -358,7 +358,7 @@ TEST(Type1) {
TEST(Type3) {
- SETUP();
+ SET_UP();
if (CpuFeatures::IsSupported(ARMv7)) {
COMPARE(ubfx(r0, r1, 5, 10),
@@ -413,7 +413,7 @@ TEST(Type3) {
TEST(Vfp) {
- SETUP();
+ SET_UP();
if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3);
@@ -546,7 +546,7 @@ TEST(Vfp) {
TEST(LoadStore) {
- SETUP();
+ SET_UP();
COMPARE(ldrb(r0, MemOperand(r1)),
"e5d10000 ldrb r0, [r1, #+0]");
diff --git a/test/cctest/test-disasm-ia32.cc b/test/cctest/test-disasm-ia32.cc
index 9f7d0bb6..da095054 100644
--- a/test/cctest/test-disasm-ia32.cc
+++ b/test/cctest/test-disasm-ia32.cc
@@ -1,4 +1,4 @@
-// Copyright 2007-2008 the V8 project authors. All rights reserved.
+// 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:
@@ -63,9 +63,9 @@ TEST(DisasmIa320) {
// Short immediate instructions
__ adc(eax, 12345678);
- __ add(Operand(eax), Immediate(12345678));
+ __ add(eax, Immediate(12345678));
__ or_(eax, 12345678);
- __ sub(Operand(eax), Immediate(12345678));
+ __ sub(eax, Immediate(12345678));
__ xor_(eax, 12345678);
__ and_(eax, 12345678);
Handle<FixedArray> foo = FACTORY->NewFixedArray(10, TENURED);
@@ -75,7 +75,7 @@ TEST(DisasmIa320) {
__ mov(ebx, Operand(esp, ecx, times_2, 0)); // [esp+ecx*4]
// ---- All instructions that I can think of
- __ add(edx, Operand(ebx));
+ __ add(edx, ebx);
__ add(edx, Operand(12, RelocInfo::NONE));
__ add(edx, Operand(ebx, 0));
__ add(edx, Operand(ebx, 16));
@@ -89,7 +89,7 @@ TEST(DisasmIa320) {
__ add(Operand(ebp, ecx, times_4, 12), Immediate(12));
__ nop();
- __ add(Operand(ebx), Immediate(12));
+ __ add(ebx, Immediate(12));
__ nop();
__ adc(ecx, 12);
__ adc(ecx, 1000);
@@ -116,16 +116,16 @@ TEST(DisasmIa320) {
CpuFeatures::Scope fscope(RDTSC);
__ rdtsc();
}
- __ movsx_b(edx, Operand(ecx));
- __ movsx_w(edx, Operand(ecx));
- __ movzx_b(edx, Operand(ecx));
- __ movzx_w(edx, Operand(ecx));
+ __ movsx_b(edx, ecx);
+ __ movsx_w(edx, ecx);
+ __ movzx_b(edx, ecx);
+ __ movzx_w(edx, ecx);
__ nop();
- __ imul(edx, Operand(ecx));
- __ shld(edx, Operand(ecx));
- __ shrd(edx, Operand(ecx));
- __ bts(Operand(edx), ecx);
+ __ imul(edx, ecx);
+ __ shld(edx, ecx);
+ __ shrd(edx, ecx);
+ __ bts(edx, ecx);
__ bts(Operand(ebx, ecx, times_4, 0), ecx);
__ nop();
__ pushad();
@@ -146,9 +146,9 @@ TEST(DisasmIa320) {
__ nop();
__ add(edx, Operand(esp, 16));
- __ add(edx, Operand(ecx));
- __ mov_b(edx, Operand(ecx));
- __ mov_b(Operand(ecx), 6);
+ __ add(edx, ecx);
+ __ mov_b(edx, ecx);
+ __ mov_b(ecx, 6);
__ mov_b(Operand(ebx, ecx, times_4, 10000), 6);
__ mov_b(Operand(esp, 16), edx);
__ mov_w(edx, Operand(esp, 16));
@@ -216,22 +216,20 @@ TEST(DisasmIa320) {
__ adc(edx, 12345);
- __ add(Operand(ebx), Immediate(12));
+ __ add(ebx, Immediate(12));
__ add(Operand(edx, ecx, times_4, 10000), Immediate(12));
__ and_(ebx, 12345);
__ cmp(ebx, 12345);
- __ cmp(Operand(ebx), Immediate(12));
+ __ cmp(ebx, Immediate(12));
__ cmp(Operand(edx, ecx, times_4, 10000), Immediate(12));
+ __ cmpb(eax, 100);
__ or_(ebx, 12345);
- __ sub(Operand(ebx), Immediate(12));
+ __ sub(ebx, Immediate(12));
__ sub(Operand(edx, ecx, times_4, 10000), Immediate(12));
- __ subb(Operand(edx, ecx, times_4, 10000), 100);
- __ subb(Operand(eax), 100);
- __ subb(eax, Operand(edx, ecx, times_4, 10000));
__ xor_(ebx, 12345);
@@ -244,7 +242,7 @@ TEST(DisasmIa320) {
__ stos();
__ sub(edx, Operand(ebx, ecx, times_4, 10000));
- __ sub(edx, Operand(ebx));
+ __ sub(edx, ebx);
__ test(edx, Immediate(12345));
__ test(edx, Operand(ebx, ecx, times_8, 10000));
@@ -446,11 +444,16 @@ TEST(DisasmIa320) {
{
if (CpuFeatures::IsSupported(SSE4_1)) {
CpuFeatures::Scope scope(SSE4_1);
- __ pextrd(Operand(eax), xmm0, 1);
- __ pinsrd(xmm1, Operand(eax), 0);
+ __ pextrd(eax, xmm0, 1);
+ __ pinsrd(xmm1, eax, 0);
}
}
+ // Nop instructions
+ for (int i = 0; i < 16; i++) {
+ __ Nop(i);
+ }
+
__ ret(0);
CodeDesc desc;
diff --git a/test/cctest/test-disasm-mips.cc b/test/cctest/test-disasm-mips.cc
index 5ad99d7a..1f874245 100644
--- a/test/cctest/test-disasm-mips.cc
+++ b/test/cctest/test-disasm-mips.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -71,10 +71,10 @@ bool DisassembleAndCompare(byte* pc, const char* compare_string) {
}
-// Setup V8 to a state where we can at least run the assembler and
+// Set up V8 to a state where we can at least run the assembler and
// disassembler. Declare the variables and allocate the data structures used
// in the rest of the macros.
-#define SETUP() \
+#define SET_UP() \
InitializeVM(); \
v8::HandleScope scope; \
byte *buffer = reinterpret_cast<byte*>(malloc(4*1024)); \
@@ -104,7 +104,7 @@ if (failure) { \
TEST(Type0) {
- SETUP();
+ SET_UP();
COMPARE(addu(a0, a1, a2),
"00a62021 addu a0, a1, a2");
@@ -148,12 +148,14 @@ TEST(Type0) {
COMPARE(divu(v0, v1),
"0043001b divu v0, v1");
- COMPARE(mul(a0, a1, a2),
- "70a62002 mul a0, a1, a2");
- COMPARE(mul(t2, t3, t4),
- "716c5002 mul t2, t3, t4");
- COMPARE(mul(v0, v1, s0),
- "70701002 mul v0, v1, s0");
+ if (kArchVariant != kLoongson) {
+ COMPARE(mul(a0, a1, a2),
+ "70a62002 mul a0, a1, a2");
+ COMPARE(mul(t2, t3, t4),
+ "716c5002 mul t2, t3, t4");
+ COMPARE(mul(v0, v1, s0),
+ "70701002 mul v0, v1, s0");
+ }
COMPARE(addiu(a0, a1, 0x0),
"24a40000 addiu a0, a1, 0");
@@ -274,7 +276,7 @@ TEST(Type0) {
COMPARE(srav(v0, v1, fp),
"03c31007 srav v0, v1, fp");
- if (mips32r2) {
+ if (kArchVariant == kMips32r2) {
COMPARE(rotr(a0, a1, 0),
"00252002 rotr a0, a1, 0");
COMPARE(rotr(s0, s1, 8),
@@ -377,48 +379,50 @@ TEST(Type0) {
COMPARE(sltiu(v0, v1, -1),
"2c62ffff sltiu v0, v1, -1");
- COMPARE(movz(a0, a1, a2),
- "00a6200a movz a0, a1, a2");
- COMPARE(movz(s0, s1, s2),
- "0232800a movz s0, s1, s2");
- COMPARE(movz(t2, t3, t4),
- "016c500a movz t2, t3, t4");
- COMPARE(movz(v0, v1, a2),
- "0066100a movz v0, v1, a2");
- COMPARE(movn(a0, a1, a2),
- "00a6200b movn a0, a1, a2");
- COMPARE(movn(s0, s1, s2),
- "0232800b movn s0, s1, s2");
- COMPARE(movn(t2, t3, t4),
- "016c500b movn t2, t3, t4");
- COMPARE(movn(v0, v1, a2),
- "0066100b movn v0, v1, a2");
-
- COMPARE(movt(a0, a1, 1),
- "00a52001 movt a0, a1, 1");
- COMPARE(movt(s0, s1, 2),
- "02298001 movt s0, s1, 2");
- COMPARE(movt(t2, t3, 3),
- "016d5001 movt t2, t3, 3");
- COMPARE(movt(v0, v1, 7),
- "007d1001 movt v0, v1, 7");
- COMPARE(movf(a0, a1, 0),
- "00a02001 movf a0, a1, 0");
- COMPARE(movf(s0, s1, 4),
- "02308001 movf s0, s1, 4");
- COMPARE(movf(t2, t3, 5),
- "01745001 movf t2, t3, 5");
- COMPARE(movf(v0, v1, 6),
- "00781001 movf v0, v1, 6");
-
- COMPARE(clz(a0, a1),
- "70a42020 clz a0, a1");
- COMPARE(clz(s6, s7),
- "72f6b020 clz s6, s7");
- COMPARE(clz(v0, v1),
- "70621020 clz v0, v1");
-
- if (mips32r2) {
+ if (kArchVariant != kLoongson) {
+ COMPARE(movz(a0, a1, a2),
+ "00a6200a movz a0, a1, a2");
+ COMPARE(movz(s0, s1, s2),
+ "0232800a movz s0, s1, s2");
+ COMPARE(movz(t2, t3, t4),
+ "016c500a movz t2, t3, t4");
+ COMPARE(movz(v0, v1, a2),
+ "0066100a movz v0, v1, a2");
+ COMPARE(movn(a0, a1, a2),
+ "00a6200b movn a0, a1, a2");
+ COMPARE(movn(s0, s1, s2),
+ "0232800b movn s0, s1, s2");
+ COMPARE(movn(t2, t3, t4),
+ "016c500b movn t2, t3, t4");
+ COMPARE(movn(v0, v1, a2),
+ "0066100b movn v0, v1, a2");
+
+ COMPARE(movt(a0, a1, 1),
+ "00a52001 movt a0, a1, 1");
+ COMPARE(movt(s0, s1, 2),
+ "02298001 movt s0, s1, 2");
+ COMPARE(movt(t2, t3, 3),
+ "016d5001 movt t2, t3, 3");
+ COMPARE(movt(v0, v1, 7),
+ "007d1001 movt v0, v1, 7");
+ COMPARE(movf(a0, a1, 0),
+ "00a02001 movf a0, a1, 0");
+ COMPARE(movf(s0, s1, 4),
+ "02308001 movf s0, s1, 4");
+ COMPARE(movf(t2, t3, 5),
+ "01745001 movf t2, t3, 5");
+ COMPARE(movf(v0, v1, 6),
+ "00781001 movf v0, v1, 6");
+
+ COMPARE(clz(a0, a1),
+ "70a42020 clz a0, a1");
+ COMPARE(clz(s6, s7),
+ "72f6b020 clz s6, s7");
+ COMPARE(clz(v0, v1),
+ "70621020 clz v0, v1");
+ }
+
+ if (kArchVariant == kMips32r2) {
COMPARE(ins_(a0, a1, 31, 1),
"7ca4ffc4 ins a0, a1, 31, 1");
COMPARE(ins_(s6, s7, 30, 2),
diff --git a/test/cctest/test-disasm-x64.cc b/test/cctest/test-disasm-x64.cc
new file mode 100644
index 00000000..da85eb93
--- /dev/null
+++ b/test/cctest/test-disasm-x64.cc
@@ -0,0 +1,429 @@
+// 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.
+
+#include <stdlib.h>
+
+#include "v8.h"
+
+#include "debug.h"
+#include "disasm.h"
+#include "disassembler.h"
+#include "macro-assembler.h"
+#include "serialize.h"
+#include "cctest.h"
+
+using namespace v8::internal;
+
+static v8::Persistent<v8::Context> env;
+
+static void InitializeVM() {
+ if (env.IsEmpty()) {
+ env = v8::Context::New();
+ }
+}
+
+
+#define __ assm.
+
+
+static void DummyStaticFunction(Object* result) {
+}
+
+
+TEST(DisasmX64) {
+ InitializeVM();
+ v8::HandleScope scope;
+ v8::internal::byte buffer[2048];
+ Assembler assm(Isolate::Current(), buffer, sizeof buffer);
+ DummyStaticFunction(NULL); // just bloody use it (DELETE; debugging)
+
+ // Short immediate instructions
+ __ addq(rax, Immediate(12345678));
+ __ or_(rax, Immediate(12345678));
+ __ subq(rax, Immediate(12345678));
+ __ xor_(rax, Immediate(12345678));
+ __ and_(rax, Immediate(12345678));
+
+ // ---- This one caused crash
+ __ movq(rbx, Operand(rsp, rcx, times_2, 0)); // [rsp+rcx*4]
+
+ // ---- All instructions that I can think of
+ __ addq(rdx, rbx);
+ __ addq(rdx, Operand(rbx, 0));
+ __ addq(rdx, Operand(rbx, 16));
+ __ addq(rdx, Operand(rbx, 1999));
+ __ addq(rdx, Operand(rsp, 0));
+ __ addq(rdx, Operand(rsp, 16));
+ __ addq(rdx, Operand(rsp, 1999));
+ __ nop();
+ __ addq(rdi, Operand(rbp, rcx, times_4, 0));
+ __ addq(rdi, Operand(rbp, rcx, times_4, 12));
+ __ addq(Operand(rbp, rcx, times_4, 12), Immediate(12));
+
+ __ nop();
+ __ addq(rbx, Immediate(12));
+ __ nop();
+ __ nop();
+ __ and_(rdx, Immediate(3));
+ __ and_(rdx, Operand(rsp, 4));
+ __ cmpq(rdx, Immediate(3));
+ __ cmpq(rdx, Operand(rsp, 4));
+ __ cmpq(Operand(rbp, rcx, times_4, 0), Immediate(1000));
+ __ cmpb(rbx, Operand(rbp, rcx, times_2, 0));
+ __ cmpb(Operand(rbp, rcx, times_2, 0), rbx);
+ __ or_(rdx, Immediate(3));
+ __ xor_(rdx, Immediate(3));
+ __ nop();
+ {
+ CHECK(CpuFeatures::IsSupported(CPUID));
+ CpuFeatures::Scope fscope(CPUID);
+ __ cpuid();
+ }
+ {
+ CHECK(CpuFeatures::IsSupported(RDTSC));
+ CpuFeatures::Scope fscope(RDTSC);
+ __ rdtsc();
+ }
+ __ movsxbq(rdx, Operand(rcx, 0));
+ __ movsxwq(rdx, Operand(rcx, 0));
+ __ movzxbl(rdx, Operand(rcx, 0));
+ __ movzxwl(rdx, Operand(rcx, 0));
+ __ movzxbq(rdx, Operand(rcx, 0));
+ __ movzxwq(rdx, Operand(rcx, 0));
+
+ __ nop();
+ __ imul(rdx, rcx);
+ __ shld(rdx, rcx);
+ __ shrd(rdx, rcx);
+ __ bts(Operand(rdx, 0), rcx);
+ __ bts(Operand(rbx, rcx, times_4, 0), rcx);
+ __ nop();
+ __ push(Immediate(12));
+ __ push(Immediate(23456));
+ __ push(rcx);
+ __ push(rsi);
+ __ push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
+ __ push(Operand(rbx, rcx, times_4, 0));
+ __ push(Operand(rbx, rcx, times_4, 0));
+ __ push(Operand(rbx, rcx, times_4, 10000));
+ __ pop(rdx);
+ __ pop(rax);
+ __ pop(Operand(rbx, rcx, times_4, 0));
+ __ nop();
+
+ __ addq(rdx, Operand(rsp, 16));
+ __ addq(rdx, rcx);
+ __ movb(rdx, Operand(rcx, 0));
+ __ movb(rcx, Immediate(6));
+ __ movb(Operand(rsp, 16), rdx);
+ __ movw(Operand(rsp, 16), rdx);
+ __ nop();
+ __ movsxwq(rdx, Operand(rsp, 12));
+ __ movsxbq(rdx, Operand(rsp, 12));
+ __ movsxlq(rdx, Operand(rsp, 12));
+ __ movzxwq(rdx, Operand(rsp, 12));
+ __ movzxbq(rdx, Operand(rsp, 12));
+ __ nop();
+ __ movq(rdx, Immediate(1234567));
+ __ movq(rdx, Operand(rsp, 12));
+ __ movq(Operand(rbx, rcx, times_4, 10000), Immediate(12345));
+ __ movq(Operand(rbx, rcx, times_4, 10000), rdx);
+ __ nop();
+ __ decb(rdx);
+ __ decb(Operand(rax, 10));
+ __ decb(Operand(rbx, rcx, times_4, 10000));
+ __ decq(rdx);
+ __ cdq();
+
+ __ nop();
+ __ idivq(rdx);
+ __ mul(rdx);
+ __ neg(rdx);
+ __ not_(rdx);
+ __ testq(Operand(rbx, rcx, times_4, 10000), rdx);
+
+ __ imul(rdx, Operand(rbx, rcx, times_4, 10000));
+ __ imul(rdx, rcx, Immediate(12));
+ __ imul(rdx, rcx, Immediate(1000));
+
+ __ incq(rdx);
+ __ incq(Operand(rbx, rcx, times_4, 10000));
+ __ push(Operand(rbx, rcx, times_4, 10000));
+ __ pop(Operand(rbx, rcx, times_4, 10000));
+ __ jmp(Operand(rbx, rcx, times_4, 10000));
+
+ __ lea(rdx, Operand(rbx, rcx, times_4, 10000));
+ __ or_(rdx, Immediate(12345));
+ __ or_(rdx, Operand(rbx, rcx, times_4, 10000));
+
+ __ nop();
+
+ __ rcl(rdx, Immediate(1));
+ __ rcl(rdx, Immediate(7));
+ __ rcr(rdx, Immediate(1));
+ __ rcr(rdx, Immediate(7));
+ __ sar(rdx, Immediate(1));
+ __ sar(rdx, Immediate(6));
+ __ sar_cl(rdx);
+ __ sbbq(rdx, rbx);
+ __ shld(rdx, rbx);
+ __ shl(rdx, Immediate(1));
+ __ shl(rdx, Immediate(6));
+ __ shl_cl(rdx);
+ __ shrd(rdx, rbx);
+ __ shr(rdx, Immediate(1));
+ __ shr(rdx, Immediate(7));
+ __ shr_cl(rdx);
+
+
+ // Immediates
+
+ __ addq(rbx, Immediate(12));
+ __ addq(Operand(rdx, rcx, times_4, 10000), Immediate(12));
+
+ __ and_(rbx, Immediate(12345));
+
+ __ cmpq(rbx, Immediate(12345));
+ __ cmpq(rbx, Immediate(12));
+ __ cmpq(Operand(rdx, rcx, times_4, 10000), Immediate(12));
+ __ cmpb(rax, Immediate(100));
+
+ __ or_(rbx, Immediate(12345));
+
+ __ subq(rbx, Immediate(12));
+ __ subq(Operand(rdx, rcx, times_4, 10000), Immediate(12));
+
+ __ xor_(rbx, Immediate(12345));
+
+ __ imul(rdx, rcx, Immediate(12));
+ __ imul(rdx, rcx, Immediate(1000));
+
+ __ cld();
+
+ __ subq(rdx, Operand(rbx, rcx, times_4, 10000));
+ __ subq(rdx, rbx);
+
+ __ testq(rdx, Immediate(12345));
+ __ testq(Operand(rbx, rcx, times_8, 10000), rdx);
+ __ testb(Operand(rcx, rbx, times_2, 1000), rdx);
+ __ testb(Operand(rax, -20), Immediate(0x9A));
+ __ nop();
+
+ __ xor_(rdx, Immediate(12345));
+ __ xor_(rdx, Operand(rbx, rcx, times_8, 10000));
+ __ bts(Operand(rbx, rcx, times_8, 10000), rdx);
+ __ hlt();
+ __ int3();
+ __ ret(0);
+ __ ret(8);
+
+ // Calls
+
+ Label L1, L2;
+ __ bind(&L1);
+ __ nop();
+ __ call(&L1);
+ __ call(&L2);
+ __ nop();
+ __ bind(&L2);
+ __ call(Operand(rbx, rcx, times_4, 10000));
+ __ nop();
+ Handle<Code> ic(Isolate::Current()->builtins()->builtin(
+ Builtins::kLoadIC_Initialize));
+ __ call(ic, RelocInfo::CODE_TARGET);
+ __ nop();
+ __ nop();
+
+ __ jmp(&L1);
+ __ jmp(Operand(rbx, rcx, times_4, 10000));
+#ifdef ENABLE_DEBUGGER_SUPPORT
+ ExternalReference after_break_target =
+ ExternalReference(Debug_Address::AfterBreakTarget(),
+ assm.isolate());
+#endif // ENABLE_DEBUGGER_SUPPORT
+ __ jmp(ic, RelocInfo::CODE_TARGET);
+ __ nop();
+
+
+ Label Ljcc;
+ __ nop();
+ // long jumps
+ __ j(overflow, &Ljcc);
+ __ j(no_overflow, &Ljcc);
+ __ j(below, &Ljcc);
+ __ j(above_equal, &Ljcc);
+ __ j(equal, &Ljcc);
+ __ j(not_equal, &Ljcc);
+ __ j(below_equal, &Ljcc);
+ __ j(above, &Ljcc);
+ __ j(sign, &Ljcc);
+ __ j(not_sign, &Ljcc);
+ __ j(parity_even, &Ljcc);
+ __ j(parity_odd, &Ljcc);
+ __ j(less, &Ljcc);
+ __ j(greater_equal, &Ljcc);
+ __ j(less_equal, &Ljcc);
+ __ j(greater, &Ljcc);
+ __ nop();
+ __ bind(&Ljcc);
+ // short jumps
+ __ j(overflow, &Ljcc);
+ __ j(no_overflow, &Ljcc);
+ __ j(below, &Ljcc);
+ __ j(above_equal, &Ljcc);
+ __ j(equal, &Ljcc);
+ __ j(not_equal, &Ljcc);
+ __ j(below_equal, &Ljcc);
+ __ j(above, &Ljcc);
+ __ j(sign, &Ljcc);
+ __ j(not_sign, &Ljcc);
+ __ j(parity_even, &Ljcc);
+ __ j(parity_odd, &Ljcc);
+ __ j(less, &Ljcc);
+ __ j(greater_equal, &Ljcc);
+ __ j(less_equal, &Ljcc);
+ __ j(greater, &Ljcc);
+
+ // 0xD9 instructions
+ __ nop();
+
+ __ fld(1);
+ __ fld1();
+ __ fldz();
+ __ fldpi();
+ __ fabs();
+ __ fchs();
+ __ fprem();
+ __ fprem1();
+ __ fincstp();
+ __ ftst();
+ __ fxch(3);
+ __ fld_s(Operand(rbx, rcx, times_4, 10000));
+ __ fstp_s(Operand(rbx, rcx, times_4, 10000));
+ __ ffree(3);
+ __ fld_d(Operand(rbx, rcx, times_4, 10000));
+ __ fstp_d(Operand(rbx, rcx, times_4, 10000));
+ __ nop();
+
+ __ fild_s(Operand(rbx, rcx, times_4, 10000));
+ __ fistp_s(Operand(rbx, rcx, times_4, 10000));
+ __ fild_d(Operand(rbx, rcx, times_4, 10000));
+ __ fistp_d(Operand(rbx, rcx, times_4, 10000));
+ __ fnstsw_ax();
+ __ nop();
+ __ fadd(3);
+ __ fsub(3);
+ __ fmul(3);
+ __ fdiv(3);
+
+ __ faddp(3);
+ __ fsubp(3);
+ __ fmulp(3);
+ __ fdivp(3);
+ __ fcompp();
+ __ fwait();
+ __ nop();
+ {
+ if (CpuFeatures::IsSupported(SSE2)) {
+ CpuFeatures::Scope fscope(SSE2);
+ __ cvttss2si(rdx, Operand(rbx, rcx, times_4, 10000));
+ __ cvttss2si(rdx, xmm1);
+ __ cvttsd2si(rdx, Operand(rbx, rcx, times_4, 10000));
+ __ cvttsd2si(rdx, xmm1);
+ __ cvttsd2siq(rdx, xmm1);
+ __ addsd(xmm1, xmm0);
+ __ mulsd(xmm1, xmm0);
+ __ subsd(xmm1, xmm0);
+ __ divsd(xmm1, xmm0);
+ __ movsd(xmm1, Operand(rbx, rcx, times_4, 10000));
+ __ movsd(Operand(rbx, rcx, times_4, 10000), xmm1);
+ __ ucomisd(xmm0, xmm1);
+
+ // 128 bit move instructions.
+ __ movdqa(xmm0, Operand(rbx, rcx, times_4, 10000));
+ __ movdqa(Operand(rbx, rcx, times_4, 10000), xmm0);
+ }
+ }
+
+ // cmov.
+ {
+ if (CpuFeatures::IsSupported(CMOV)) {
+ CpuFeatures::Scope use_cmov(CMOV);
+ __ cmovq(overflow, rax, Operand(rax, 0));
+ __ cmovq(no_overflow, rax, Operand(rax, 1));
+ __ cmovq(below, rax, Operand(rax, 2));
+ __ cmovq(above_equal, rax, Operand(rax, 3));
+ __ cmovq(equal, rax, Operand(rbx, 0));
+ __ cmovq(not_equal, rax, Operand(rbx, 1));
+ __ cmovq(below_equal, rax, Operand(rbx, 2));
+ __ cmovq(above, rax, Operand(rbx, 3));
+ __ cmovq(sign, rax, Operand(rcx, 0));
+ __ cmovq(not_sign, rax, Operand(rcx, 1));
+ __ cmovq(parity_even, rax, Operand(rcx, 2));
+ __ cmovq(parity_odd, rax, Operand(rcx, 3));
+ __ cmovq(less, rax, Operand(rdx, 0));
+ __ cmovq(greater_equal, rax, Operand(rdx, 1));
+ __ cmovq(less_equal, rax, Operand(rdx, 2));
+ __ cmovq(greater, rax, Operand(rdx, 3));
+ }
+ }
+
+ // andpd, etc.
+ {
+ if (CpuFeatures::IsSupported(SSE2)) {
+ CpuFeatures::Scope fscope(SSE2);
+ __ andpd(xmm0, xmm1);
+ __ andpd(xmm1, xmm2);
+
+ __ movaps(xmm0, xmm1);
+ __ movaps(xmm1, xmm2);
+ }
+ }
+
+ // Nop instructions
+ for (int i = 0; i < 16; i++) {
+ __ Nop(i);
+ }
+
+ __ ret(0);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Object* code = HEAP->CreateCode(
+ desc,
+ Code::ComputeFlags(Code::STUB),
+ Handle<Object>(HEAP->undefined_value()))->ToObjectChecked();
+ CHECK(code->IsCode());
+#ifdef OBJECT_PRINT
+ Code::cast(code)->Print();
+ byte* begin = Code::cast(code)->instruction_start();
+ byte* end = begin + Code::cast(code)->instruction_size();
+ disasm::Disassembler::Disassemble(stdout, begin, end);
+#endif
+}
+
+#undef __
diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc
index 6c2afd47..a56f250c 100644
--- a/test/cctest/test-heap-profiler.cc
+++ b/test/cctest/test-heap-profiler.cc
@@ -18,14 +18,30 @@ class NamedEntriesDetector {
: has_A2(false), has_B2(false), has_C2(false) {
}
- void Apply(i::HeapEntry** entry_ptr) {
- if (IsReachableNodeWithName(*entry_ptr, "A2")) has_A2 = true;
- if (IsReachableNodeWithName(*entry_ptr, "B2")) has_B2 = true;
- if (IsReachableNodeWithName(*entry_ptr, "C2")) has_C2 = true;
+ void CheckEntry(i::HeapEntry* entry) {
+ if (strcmp(entry->name(), "A2") == 0) has_A2 = true;
+ if (strcmp(entry->name(), "B2") == 0) has_B2 = true;
+ if (strcmp(entry->name(), "C2") == 0) has_C2 = true;
}
- static bool IsReachableNodeWithName(i::HeapEntry* entry, const char* name) {
- return strcmp(name, entry->name()) == 0 && entry->painted_reachable();
+ void CheckAllReachables(i::HeapEntry* root) {
+ i::List<i::HeapEntry*> list(10);
+ list.Add(root);
+ root->paint();
+ CheckEntry(root);
+ while (!list.is_empty()) {
+ i::HeapEntry* entry = list.RemoveLast();
+ i::Vector<i::HeapGraphEdge> children = entry->children();
+ for (int i = 0; i < children.length(); ++i) {
+ if (children[i].type() == i::HeapGraphEdge::kShortcut) continue;
+ i::HeapEntry* child = children[i].to();
+ if (!child->painted()) {
+ list.Add(child);
+ child->paint();
+ CheckEntry(child);
+ }
+ }
+ }
}
bool has_A2;
@@ -90,10 +106,6 @@ TEST(HeapSnapshot) {
const_cast<i::HeapSnapshot*>(
reinterpret_cast<const i::HeapSnapshot*>(snapshot_env2));
const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2);
- // Paint all nodes reachable from global object.
- i_snapshot_env2->ClearPaint();
- const_cast<i::HeapEntry*>(
- reinterpret_cast<const i::HeapEntry*>(global_env2))->PaintAllReachable();
// Verify, that JS global object of env2 has '..2' properties.
const v8::HeapGraphNode* a2_node =
@@ -105,8 +117,11 @@ TEST(HeapSnapshot) {
NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_2"));
CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "c2"));
+ // Paint all nodes reachable from global object.
NamedEntriesDetector det;
- i_snapshot_env2->IterateEntries(&det);
+ i_snapshot_env2->ClearPaint();
+ det.CheckAllReachables(const_cast<i::HeapEntry*>(
+ reinterpret_cast<const i::HeapEntry*>(global_env2)));
CHECK(det.has_A2);
CHECK(det.has_B2);
CHECK(det.has_C2);
@@ -136,14 +151,47 @@ TEST(HeapSnapshotObjectSizes) {
GetProperty(x, v8::HeapGraphEdge::kProperty, "b");
CHECK_NE(NULL, x2);
- // Test approximate sizes.
- CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize(false));
- CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize(false));
- CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize(false));
- // Test exact sizes.
- CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize(true));
- CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize(true));
- CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize(true));
+ // Test sizes.
+ CHECK_EQ(x->GetSelfSize() * 3, x->GetRetainedSize());
+ CHECK_EQ(x1->GetSelfSize(), x1->GetRetainedSize());
+ CHECK_EQ(x2->GetSelfSize(), x2->GetRetainedSize());
+}
+
+
+TEST(BoundFunctionInSnapshot) {
+ v8::HandleScope scope;
+ LocalContext env;
+ CompileRun(
+ "function myFunction(a, b) { this.a = a; this.b = b; }\n"
+ "function AAAAA() {}\n"
+ "boundFunction = myFunction.bind(new AAAAA(), 20, new Number(12)); \n");
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8_str("sizes"));
+ const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+ const v8::HeapGraphNode* f =
+ GetProperty(global, v8::HeapGraphEdge::kShortcut, "boundFunction");
+ CHECK(f);
+ CHECK_EQ(v8::String::New("native_bind"), f->GetName());
+ const v8::HeapGraphNode* bindings =
+ GetProperty(f, v8::HeapGraphEdge::kInternal, "bindings");
+ CHECK_NE(NULL, bindings);
+ CHECK_EQ(v8::HeapGraphNode::kArray, bindings->GetType());
+ CHECK_EQ(4, bindings->GetChildrenCount());
+
+ const v8::HeapGraphNode* bound_this = GetProperty(
+ f, v8::HeapGraphEdge::kShortcut, "bound_this");
+ CHECK(bound_this);
+ CHECK_EQ(v8::HeapGraphNode::kObject, bound_this->GetType());
+
+ const v8::HeapGraphNode* bound_function = GetProperty(
+ f, v8::HeapGraphEdge::kShortcut, "bound_function");
+ CHECK(bound_function);
+ CHECK_EQ(v8::HeapGraphNode::kClosure, bound_function->GetType());
+
+ const v8::HeapGraphNode* bound_argument = GetProperty(
+ f, v8::HeapGraphEdge::kShortcut, "bound_argument_1");
+ CHECK(bound_argument);
+ CHECK_EQ(v8::HeapGraphNode::kObject, bound_argument->GetType());
}
@@ -252,6 +300,28 @@ TEST(HeapSnapshotHeapNumbers) {
CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType());
}
+TEST(HeapSnapshotSlicedString) {
+ v8::HandleScope scope;
+ LocalContext env;
+ CompileRun(
+ "parent_string = \"123456789.123456789.123456789.123456789.123456789."
+ "123456789.123456789.123456789.123456789.123456789."
+ "123456789.123456789.123456789.123456789.123456789."
+ "123456789.123456789.123456789.123456789.123456789.\";"
+ "child_string = parent_string.slice(100);");
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8_str("strings"));
+ const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+ const v8::HeapGraphNode* parent_string =
+ GetProperty(global, v8::HeapGraphEdge::kShortcut, "parent_string");
+ CHECK_NE(NULL, parent_string);
+ const v8::HeapGraphNode* child_string =
+ GetProperty(global, v8::HeapGraphEdge::kShortcut, "child_string");
+ CHECK_NE(NULL, child_string);
+ const v8::HeapGraphNode* parent =
+ GetProperty(child_string, v8::HeapGraphEdge::kInternal, "parent");
+ CHECK_EQ(parent_string, parent);
+}
TEST(HeapSnapshotInternalReferences) {
v8::HandleScope scope;
@@ -282,6 +352,59 @@ TEST(HeapSnapshotInternalReferences) {
#define CHECK_NE_UINT64_T(a, b) \
CHECK((a) != (b)) // NOLINT
+TEST(HeapEntryIdsAndArrayShift) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CompileRun(
+ "function AnObject() {\n"
+ " this.first = 'first';\n"
+ " this.second = 'second';\n"
+ "}\n"
+ "var a = new Array();\n"
+ "for (var i = 0; i < 10; ++i)\n"
+ " a.push(new AnObject());\n");
+ const v8::HeapSnapshot* snapshot1 =
+ v8::HeapProfiler::TakeSnapshot(v8_str("s1"));
+
+ CompileRun(
+ "for (var i = 0; i < 1; ++i)\n"
+ " a.shift();\n");
+
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
+
+ const v8::HeapSnapshot* snapshot2 =
+ v8::HeapProfiler::TakeSnapshot(v8_str("s2"));
+
+ const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1);
+ const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2);
+ CHECK_NE_UINT64_T(0, global1->GetId());
+ CHECK_EQ_UINT64_T(global1->GetId(), global2->GetId());
+
+ const v8::HeapGraphNode* a1 =
+ GetProperty(global1, v8::HeapGraphEdge::kProperty, "a");
+ CHECK_NE(NULL, a1);
+ const v8::HeapGraphNode* e1 =
+ GetProperty(a1, v8::HeapGraphEdge::kHidden, "1");
+ CHECK_NE(NULL, e1);
+ const v8::HeapGraphNode* k1 =
+ GetProperty(e1, v8::HeapGraphEdge::kInternal, "elements");
+ CHECK_NE(NULL, k1);
+ const v8::HeapGraphNode* a2 =
+ GetProperty(global2, v8::HeapGraphEdge::kProperty, "a");
+ CHECK_NE(NULL, a2);
+ const v8::HeapGraphNode* e2 =
+ GetProperty(a2, v8::HeapGraphEdge::kHidden, "1");
+ CHECK_NE(NULL, e2);
+ const v8::HeapGraphNode* k2 =
+ GetProperty(e2, v8::HeapGraphEdge::kInternal, "elements");
+ CHECK_NE(NULL, k2);
+
+ CHECK_EQ_UINT64_T(a1->GetId(), a2->GetId());
+ CHECK_EQ_UINT64_T(e1->GetId(), e2->GetId());
+ CHECK_EQ_UINT64_T(k1->GetId(), k2->GetId());
+}
+
TEST(HeapEntryIdsAndGC) {
v8::HandleScope scope;
LocalContext env;
@@ -294,7 +417,7 @@ TEST(HeapEntryIdsAndGC) {
const v8::HeapSnapshot* snapshot1 =
v8::HeapProfiler::TakeSnapshot(v8_str("s1"));
- HEAP->CollectAllGarbage(true); // Enforce compaction.
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
const v8::HeapSnapshot* snapshot2 =
v8::HeapProfiler::TakeSnapshot(v8_str("s2"));
@@ -563,6 +686,22 @@ TEST(HeapSnapshotJSONSerializationAborting) {
}
+static void CheckChildrenIds(const v8::HeapSnapshot* snapshot,
+ const v8::HeapGraphNode* node,
+ int level, int max_level) {
+ if (level > max_level) return;
+ CHECK_EQ(node, snapshot->GetNodeById(node->GetId()));
+ for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
+ const v8::HeapGraphEdge* prop = node->GetChild(i);
+ const v8::HeapGraphNode* child =
+ snapshot->GetNodeById(prop->GetToNode()->GetId());
+ CHECK_EQ_UINT64_T(prop->GetToNode()->GetId(), child->GetId());
+ CHECK_EQ(prop->GetToNode(), child);
+ CheckChildrenIds(snapshot, child, level + 1, max_level);
+ }
+}
+
+
TEST(HeapSnapshotGetNodeById) {
v8::HandleScope scope;
LocalContext env;
@@ -570,12 +709,7 @@ TEST(HeapSnapshotGetNodeById) {
const v8::HeapSnapshot* snapshot =
v8::HeapProfiler::TakeSnapshot(v8_str("id"));
const v8::HeapGraphNode* root = snapshot->GetRoot();
- CHECK_EQ(root, snapshot->GetNodeById(root->GetId()));
- for (int i = 0, count = root->GetChildrenCount(); i < count; ++i) {
- const v8::HeapGraphEdge* prop = root->GetChild(i);
- CHECK_EQ(
- prop->GetToNode(), snapshot->GetNodeById(prop->GetToNode()->GetId()));
- }
+ CheckChildrenIds(snapshot, root, 0, 3);
// Check a big id, which should not exist yet.
CHECK_EQ(NULL, snapshot->GetNodeById(0x1000000UL));
}
@@ -607,7 +741,7 @@ TEST(TakeHeapSnapshotAborting) {
LocalContext env;
const int snapshots_count = v8::HeapProfiler::GetSnapshotsCount();
- TestActivityControl aborting_control(3);
+ TestActivityControl aborting_control(1);
const v8::HeapSnapshot* no_snapshot =
v8::HeapProfiler::TakeSnapshot(v8_str("abort"),
v8::HeapSnapshot::kFull,
@@ -633,11 +767,13 @@ namespace {
class TestRetainedObjectInfo : public v8::RetainedObjectInfo {
public:
TestRetainedObjectInfo(int hash,
+ const char* group_label,
const char* label,
intptr_t element_count = -1,
intptr_t size = -1)
: disposed_(false),
hash_(hash),
+ group_label_(group_label),
label_(label),
element_count_(element_count),
size_(size) {
@@ -652,6 +788,7 @@ class TestRetainedObjectInfo : public v8::RetainedObjectInfo {
return GetHash() == other->GetHash();
}
virtual intptr_t GetHash() { return hash_; }
+ virtual const char* GetGroupLabel() { return group_label_; }
virtual const char* GetLabel() { return label_; }
virtual intptr_t GetElementCount() { return element_count_; }
virtual intptr_t GetSizeInBytes() { return size_; }
@@ -663,15 +800,15 @@ class TestRetainedObjectInfo : public v8::RetainedObjectInfo {
if (wrapper->IsString()) {
v8::String::AsciiValue ascii(wrapper);
if (strcmp(*ascii, "AAA") == 0)
- return new TestRetainedObjectInfo(1, "aaa", 100);
+ return new TestRetainedObjectInfo(1, "aaa-group", "aaa", 100);
else if (strcmp(*ascii, "BBB") == 0)
- return new TestRetainedObjectInfo(1, "aaa", 100);
+ return new TestRetainedObjectInfo(1, "aaa-group", "aaa", 100);
}
} else if (class_id == 2) {
if (wrapper->IsString()) {
v8::String::AsciiValue ascii(wrapper);
if (strcmp(*ascii, "CCC") == 0)
- return new TestRetainedObjectInfo(2, "ccc");
+ return new TestRetainedObjectInfo(2, "ccc-group", "ccc");
}
}
CHECK(false);
@@ -684,6 +821,7 @@ class TestRetainedObjectInfo : public v8::RetainedObjectInfo {
bool disposed_;
int category_;
int hash_;
+ const char* group_label_;
const char* label_;
intptr_t element_count_;
intptr_t size_;
@@ -736,18 +874,21 @@ TEST(HeapSnapshotRetainedObjectInfo) {
delete TestRetainedObjectInfo::instances[i];
}
- const v8::HeapGraphNode* natives = GetNode(
- snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(Native objects)");
- CHECK_NE(NULL, natives);
- CHECK_EQ(2, natives->GetChildrenCount());
+ const v8::HeapGraphNode* native_group_aaa = GetNode(
+ snapshot->GetRoot(), v8::HeapGraphNode::kSynthetic, "aaa-group");
+ CHECK_NE(NULL, native_group_aaa);
+ CHECK_EQ(1, native_group_aaa->GetChildrenCount());
const v8::HeapGraphNode* aaa = GetNode(
- natives, v8::HeapGraphNode::kNative, "aaa / 100 entries");
+ native_group_aaa, v8::HeapGraphNode::kNative, "aaa / 100 entries");
CHECK_NE(NULL, aaa);
+ CHECK_EQ(2, aaa->GetChildrenCount());
+
+ const v8::HeapGraphNode* native_group_ccc = GetNode(
+ snapshot->GetRoot(), v8::HeapGraphNode::kSynthetic, "ccc-group");
const v8::HeapGraphNode* ccc = GetNode(
- natives, v8::HeapGraphNode::kNative, "ccc");
+ native_group_ccc, v8::HeapGraphNode::kNative, "ccc");
CHECK_NE(NULL, ccc);
- CHECK_EQ(2, aaa->GetChildrenCount());
const v8::HeapGraphNode* n_AAA = GetNode(
aaa, v8::HeapGraphNode::kString, "AAA");
CHECK_NE(NULL, n_AAA);
@@ -765,6 +906,75 @@ TEST(HeapSnapshotRetainedObjectInfo) {
}
+class GraphWithImplicitRefs {
+ public:
+ static const int kObjectsCount = 4;
+ explicit GraphWithImplicitRefs(LocalContext* env) {
+ CHECK_EQ(NULL, instance_);
+ instance_ = this;
+ for (int i = 0; i < kObjectsCount; i++) {
+ objects_[i] = v8::Persistent<v8::Object>::New(v8::Object::New());
+ }
+ (*env)->Global()->Set(v8_str("root_object"), objects_[0]);
+ }
+ ~GraphWithImplicitRefs() {
+ instance_ = NULL;
+ }
+
+ static void gcPrologue() {
+ instance_->AddImplicitReferences();
+ }
+
+ private:
+ void AddImplicitReferences() {
+ // 0 -> 1
+ v8::V8::AddImplicitReferences(
+ v8::Persistent<v8::Object>::Cast(objects_[0]), &objects_[1], 1);
+ // Adding two more references(note length=2 in params): 1 -> 2, 1 -> 3
+ v8::V8::AddImplicitReferences(
+ v8::Persistent<v8::Object>::Cast(objects_[1]), &objects_[2], 2);
+ }
+
+ v8::Persistent<v8::Value> objects_[kObjectsCount];
+ static GraphWithImplicitRefs* instance_;
+};
+
+GraphWithImplicitRefs* GraphWithImplicitRefs::instance_ = NULL;
+
+
+TEST(HeapSnapshotImplicitReferences) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ GraphWithImplicitRefs graph(&env);
+ v8::V8::SetGlobalGCPrologueCallback(&GraphWithImplicitRefs::gcPrologue);
+
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8_str("implicit_refs"));
+
+ const v8::HeapGraphNode* global_object = GetGlobalObject(snapshot);
+ // Use kShortcut type to skip intermediate JSGlobalPropertyCell
+ const v8::HeapGraphNode* obj0 = GetProperty(
+ global_object, v8::HeapGraphEdge::kShortcut, "root_object");
+ CHECK(obj0);
+ CHECK_EQ(v8::HeapGraphNode::kObject, obj0->GetType());
+ const v8::HeapGraphNode* obj1 = GetProperty(
+ obj0, v8::HeapGraphEdge::kInternal, "native");
+ CHECK(obj1);
+ int implicit_targets_count = 0;
+ for (int i = 0, count = obj1->GetChildrenCount(); i < count; ++i) {
+ const v8::HeapGraphEdge* prop = obj1->GetChild(i);
+ v8::String::AsciiValue prop_name(prop->GetName());
+ if (prop->GetType() == v8::HeapGraphEdge::kInternal &&
+ strcmp("native", *prop_name) == 0) {
+ ++implicit_targets_count;
+ }
+ }
+ CHECK_EQ(2, implicit_targets_count);
+ v8::V8::SetGlobalGCPrologueCallback(NULL);
+}
+
+
TEST(DeleteAllHeapSnapshots) {
v8::HandleScope scope;
LocalContext env;
@@ -873,6 +1083,20 @@ TEST(DocumentURLWithException) {
}
+TEST(NoHandleLeaks) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CompileRun("document = { URL:\"abcdefgh\" };");
+
+ v8::Handle<v8::String> name(v8_str("leakz"));
+ int count_before = i::HandleScope::NumberOfHandles();
+ v8::HeapProfiler::TakeSnapshot(name);
+ int count_after = i::HandleScope::NumberOfHandles();
+ CHECK_EQ(count_before, count_after);
+}
+
+
TEST(NodesIteration) {
v8::HandleScope scope;
LocalContext env;
@@ -1001,3 +1225,144 @@ TEST(GetConstructorName) {
CHECK_EQ(0, StringCmp(
"Object", i::V8HeapExplorer::GetConstructorName(*js_obj6)));
}
+
+
+TEST(FastCaseGetter) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CompileRun("var obj1 = {};\n"
+ "obj1.__defineGetter__('propWithGetter', function Y() {\n"
+ " return 42;\n"
+ "});\n"
+ "obj1.__defineSetter__('propWithSetter', function Z(value) {\n"
+ " return this.value_ = value;\n"
+ "});\n");
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8_str("fastCaseGetter"));
+
+ const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+ CHECK_NE(NULL, global);
+ const v8::HeapGraphNode* obj1 =
+ GetProperty(global, v8::HeapGraphEdge::kShortcut, "obj1");
+ CHECK_NE(NULL, obj1);
+ const v8::HeapGraphNode* getterFunction =
+ GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get-propWithGetter");
+ CHECK_NE(NULL, getterFunction);
+ const v8::HeapGraphNode* setterFunction =
+ GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set-propWithSetter");
+ CHECK_NE(NULL, setterFunction);
+}
+
+
+bool HasWeakEdge(const v8::HeapGraphNode* node) {
+ for (int i = 0; i < node->GetChildrenCount(); ++i) {
+ const v8::HeapGraphEdge* handle_edge = node->GetChild(i);
+ if (handle_edge->GetType() == v8::HeapGraphEdge::kWeak) return true;
+ }
+ return false;
+}
+
+
+bool HasWeakGlobalHandle() {
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8_str("weaks"));
+ const v8::HeapGraphNode* gc_roots = GetNode(
+ snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(GC roots)");
+ CHECK_NE(NULL, gc_roots);
+ const v8::HeapGraphNode* global_handles = GetNode(
+ gc_roots, v8::HeapGraphNode::kObject, "(Global handles)");
+ CHECK_NE(NULL, global_handles);
+ return HasWeakEdge(global_handles);
+}
+
+
+static void PersistentHandleCallback(v8::Persistent<v8::Value> handle, void*) {
+ handle.Dispose();
+}
+
+
+TEST(WeakGlobalHandle) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CHECK(!HasWeakGlobalHandle());
+
+ v8::Persistent<v8::Object> handle =
+ v8::Persistent<v8::Object>::New(v8::Object::New());
+ handle.MakeWeak(NULL, PersistentHandleCallback);
+
+ CHECK(HasWeakGlobalHandle());
+}
+
+
+TEST(WeakGlobalContextRefs) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8_str("weaks"));
+ const v8::HeapGraphNode* gc_roots = GetNode(
+ snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(GC roots)");
+ CHECK_NE(NULL, gc_roots);
+ const v8::HeapGraphNode* global_handles = GetNode(
+ gc_roots, v8::HeapGraphNode::kObject, "(Global handles)");
+ CHECK_NE(NULL, global_handles);
+ const v8::HeapGraphNode* global_context = GetNode(
+ global_handles, v8::HeapGraphNode::kHidden, "system / GlobalContext");
+ CHECK_NE(NULL, global_context);
+ CHECK(HasWeakEdge(global_context));
+}
+
+
+TEST(SfiAndJsFunctionWeakRefs) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CompileRun(
+ "fun = (function (x) { return function () { return x + 1; } })(1);");
+ const v8::HeapSnapshot* snapshot =
+ v8::HeapProfiler::TakeSnapshot(v8_str("fun"));
+ const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+ CHECK_NE(NULL, global);
+ const v8::HeapGraphNode* fun =
+ GetProperty(global, v8::HeapGraphEdge::kShortcut, "fun");
+ CHECK(HasWeakEdge(fun));
+ const v8::HeapGraphNode* shared =
+ GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared");
+ CHECK(HasWeakEdge(shared));
+}
+
+
+TEST(PersistentHandleCount) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ // V8 also uses global handles internally, so we can't test for an absolute
+ // number.
+ int global_handle_count = v8::HeapProfiler::GetPersistentHandleCount();
+
+ // Create some persistent handles.
+ v8::Persistent<v8::String> p_AAA =
+ v8::Persistent<v8::String>::New(v8_str("AAA"));
+ CHECK_EQ(global_handle_count + 1,
+ v8::HeapProfiler::GetPersistentHandleCount());
+ v8::Persistent<v8::String> p_BBB =
+ v8::Persistent<v8::String>::New(v8_str("BBB"));
+ CHECK_EQ(global_handle_count + 2,
+ v8::HeapProfiler::GetPersistentHandleCount());
+ v8::Persistent<v8::String> p_CCC =
+ v8::Persistent<v8::String>::New(v8_str("CCC"));
+ CHECK_EQ(global_handle_count + 3,
+ v8::HeapProfiler::GetPersistentHandleCount());
+
+ // Dipose the persistent handles in a different order.
+ p_AAA.Dispose();
+ CHECK_EQ(global_handle_count + 2,
+ v8::HeapProfiler::GetPersistentHandleCount());
+ p_CCC.Dispose();
+ CHECK_EQ(global_handle_count + 1,
+ v8::HeapProfiler::GetPersistentHandleCount());
+ p_BBB.Dispose();
+ CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount());
+}
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 11b88130..999e2c66 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
#include <stdlib.h>
@@ -612,7 +612,7 @@ TEST(ObjectProperties) {
CHECK(!obj->HasLocalProperty(*second));
// check string and symbol match
- static const char* string1 = "fisk";
+ const char* string1 = "fisk";
Handle<String> s1 = FACTORY->NewStringFromAscii(CStrVector(string1));
obj->SetProperty(
*s1, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
@@ -620,7 +620,7 @@ TEST(ObjectProperties) {
CHECK(obj->HasLocalProperty(*s1_symbol));
// check symbol and string match
- static const char* string2 = "fugl";
+ const char* string2 = "fugl";
Handle<String> s2_symbol = FACTORY->LookupAsciiSymbol(string2);
obj->SetProperty(
*s2_symbol, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
@@ -667,22 +667,23 @@ TEST(JSArray) {
Handle<JSObject> object = FACTORY->NewJSObject(function);
Handle<JSArray> array = Handle<JSArray>::cast(object);
// We just initialized the VM, no heap allocation failure yet.
- Object* ok = array->Initialize(0)->ToObjectChecked();
+ array->Initialize(0)->ToObjectChecked();
// Set array length to 0.
- ok = array->SetElementsLength(Smi::FromInt(0))->ToObjectChecked();
+ array->SetElementsLength(Smi::FromInt(0))->ToObjectChecked();
CHECK_EQ(Smi::FromInt(0), array->length());
- CHECK(array->HasFastElements()); // Must be in fast mode.
+ // Must be in fast mode.
+ CHECK(array->HasFastTypeElements());
// array[length] = name.
- ok = array->SetElement(0, *name, kNonStrictMode, true)->ToObjectChecked();
+ array->SetElement(0, *name, NONE, kNonStrictMode)->ToObjectChecked();
CHECK_EQ(Smi::FromInt(1), array->length());
CHECK_EQ(array->GetElement(0), *name);
// Set array length with larger than smi value.
Handle<Object> length =
FACTORY->NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1);
- ok = array->SetElementsLength(*length)->ToObjectChecked();
+ array->SetElementsLength(*length)->ToObjectChecked();
uint32_t int_length = 0;
CHECK(length->ToArrayIndex(&int_length));
@@ -690,8 +691,7 @@ TEST(JSArray) {
CHECK(array->HasDictionaryElements()); // Must be in slow mode.
// array[length] = name.
- ok = array->SetElement(
- int_length, *name, kNonStrictMode, true)->ToObjectChecked();
+ array->SetElement(int_length, *name, NONE, kNonStrictMode)->ToObjectChecked();
uint32_t new_int_length = 0;
CHECK(array->length()->ToArrayIndex(&new_int_length));
CHECK_EQ(static_cast<double>(int_length), new_int_length - 1);
@@ -718,10 +718,8 @@ TEST(JSObjectCopy) {
obj->SetProperty(
*second, Smi::FromInt(2), NONE, kNonStrictMode)->ToObjectChecked();
- Object* ok =
- obj->SetElement(0, *first, kNonStrictMode, true)->ToObjectChecked();
-
- ok = obj->SetElement(1, *second, kNonStrictMode, true)->ToObjectChecked();
+ obj->SetElement(0, *first, NONE, kNonStrictMode)->ToObjectChecked();
+ obj->SetElement(1, *second, NONE, kNonStrictMode)->ToObjectChecked();
// Make the clone.
Handle<JSObject> clone = Copy(obj);
@@ -739,8 +737,8 @@ TEST(JSObjectCopy) {
clone->SetProperty(
*second, Smi::FromInt(1), NONE, kNonStrictMode)->ToObjectChecked();
- ok = clone->SetElement(0, *second, kNonStrictMode, true)->ToObjectChecked();
- ok = clone->SetElement(1, *first, kNonStrictMode, true)->ToObjectChecked();
+ clone->SetElement(0, *second, NONE, kNonStrictMode)->ToObjectChecked();
+ clone->SetElement(1, *first, NONE, kNonStrictMode)->ToObjectChecked();
CHECK_EQ(obj->GetElement(1), clone->GetElement(0));
CHECK_EQ(obj->GetElement(0), clone->GetElement(1));
@@ -813,7 +811,7 @@ TEST(Iteration) {
// Allocate a JS array to OLD_POINTER_SPACE and NEW_SPACE
objs[next_objs_index++] = FACTORY->NewJSArray(10);
- objs[next_objs_index++] = FACTORY->NewJSArray(10, TENURED);
+ objs[next_objs_index++] = FACTORY->NewJSArray(10, FAST_ELEMENTS, TENURED);
// Allocate a small string to OLD_DATA_SPACE and NEW_SPACE
objs[next_objs_index++] =
@@ -822,7 +820,7 @@ TEST(Iteration) {
FACTORY->NewStringFromAscii(CStrVector("abcdefghij"), TENURED);
// Allocate a large string (for large object space).
- int large_size = HEAP->MaxObjectSizeInPagedSpace() + 1;
+ int large_size = Page::kMaxNonCodeHeapObjectSize + 1;
char* str = new char[large_size];
for (int i = 0; i < large_size - 1; ++i) str[i] = 'a';
str[large_size - 1] = '\0';
@@ -838,49 +836,6 @@ TEST(Iteration) {
}
-TEST(LargeObjectSpaceContains) {
- InitializeVM();
-
- HEAP->CollectGarbage(NEW_SPACE);
-
- Address current_top = HEAP->new_space()->top();
- Page* page = Page::FromAddress(current_top);
- Address current_page = page->address();
- Address next_page = current_page + Page::kPageSize;
- int bytes_to_page = static_cast<int>(next_page - current_top);
- if (bytes_to_page <= FixedArray::kHeaderSize) {
- // Alas, need to cross another page to be able to
- // put desired value.
- next_page += Page::kPageSize;
- bytes_to_page = static_cast<int>(next_page - current_top);
- }
- CHECK(bytes_to_page > FixedArray::kHeaderSize);
-
- intptr_t* flags_ptr = &Page::FromAddress(next_page)->flags_;
- Address flags_addr = reinterpret_cast<Address>(flags_ptr);
-
- int bytes_to_allocate =
- static_cast<int>(flags_addr - current_top) + kPointerSize;
-
- int n_elements = (bytes_to_allocate - FixedArray::kHeaderSize) /
- kPointerSize;
- CHECK_EQ(bytes_to_allocate, FixedArray::SizeFor(n_elements));
- FixedArray* array = FixedArray::cast(
- HEAP->AllocateFixedArray(n_elements)->ToObjectChecked());
-
- int index = n_elements - 1;
- CHECK_EQ(flags_ptr,
- HeapObject::RawField(array, FixedArray::OffsetOfElementAt(index)));
- array->set(index, Smi::FromInt(0));
- // This chould have turned next page into LargeObjectPage:
- // CHECK(Page::FromAddress(next_page)->IsLargeObjectPage());
-
- HeapObject* addr = HeapObject::FromAddress(next_page + 2 * kPointerSize);
- CHECK(HEAP->new_space()->Contains(addr));
- CHECK(!HEAP->lo_space()->Contains(addr));
-}
-
-
TEST(EmptyHandleEscapeFrom) {
InitializeVM();
@@ -907,8 +862,7 @@ TEST(Regression39128) {
InitializeVM();
// Increase the chance of 'bump-the-pointer' allocation in old space.
- bool force_compaction = true;
- HEAP->CollectAllGarbage(force_compaction);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
v8::HandleScope scope;
@@ -975,12 +929,6 @@ TEST(Regression39128) {
return;
}
CHECK(HEAP->old_pointer_space()->Contains(clone->address()));
-
- // Step 5: verify validity of region dirty marks.
- Address clone_addr = clone->address();
- Page* page = Page::FromAddress(clone_addr);
- // Check that region covering inobject property 1 is marked dirty.
- CHECK(page->IsRegionDirty(clone_addr + (object_size - kPointerSize)));
}
@@ -1010,17 +958,18 @@ TEST(TestCodeFlushing) {
Handle<JSFunction> function(JSFunction::cast(func_value));
CHECK(function->shared()->is_compiled());
- HEAP->CollectAllGarbage(true);
- HEAP->CollectAllGarbage(true);
+ // TODO(1609) Currently incremental marker does not support code flushing.
+ HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+ HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
CHECK(function->shared()->is_compiled());
- HEAP->CollectAllGarbage(true);
- HEAP->CollectAllGarbage(true);
- HEAP->CollectAllGarbage(true);
- HEAP->CollectAllGarbage(true);
- HEAP->CollectAllGarbage(true);
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+ HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+ HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+ HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+ HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+ HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
// foo should no longer be in the compilation cache
CHECK(!function->shared()->is_compiled() || function->IsOptimized());
@@ -1109,7 +1058,7 @@ TEST(TestInternalWeakLists) {
}
// Mark compact handles the weak references.
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
// Get rid of f3 and f5 in the same way.
@@ -1118,21 +1067,21 @@ TEST(TestInternalWeakLists) {
HEAP->PerformScavenge();
CHECK_EQ(opt ? 4 : 0, CountOptimizedUserFunctions(ctx[i]));
}
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
CompileRun("f5=null");
for (int j = 0; j < 10; j++) {
HEAP->PerformScavenge();
CHECK_EQ(opt ? 3 : 0, CountOptimizedUserFunctions(ctx[i]));
}
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
CHECK_EQ(opt ? 2 : 0, CountOptimizedUserFunctions(ctx[i]));
ctx[i]->Exit();
}
// Force compilation cache cleanup.
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
// Dispose the global contexts one by one.
for (int i = 0; i < kNumTestContexts; i++) {
@@ -1146,7 +1095,7 @@ TEST(TestInternalWeakLists) {
}
// Mark compact handles the weak references.
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
CHECK_EQ(kNumTestContexts - i - 1, CountGlobalContexts());
}
@@ -1161,7 +1110,7 @@ static int CountGlobalContextsWithGC(int n) {
Handle<Object> object(HEAP->global_contexts_list());
while (!object->IsUndefined()) {
count++;
- if (count == n) HEAP->CollectAllGarbage(true);
+ if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags);
object =
Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK));
}
@@ -1180,7 +1129,7 @@ static int CountOptimizedUserFunctionsWithGC(v8::Handle<v8::Context> context,
while (object->IsJSFunction() &&
!Handle<JSFunction>::cast(object)->IsBuiltin()) {
count++;
- if (count == n) HEAP->CollectAllGarbage(true);
+ if (count == n) HEAP->CollectAllGarbage(Heap::kNoGCFlags);
object = Handle<Object>(
Object::cast(JSFunction::cast(*object)->next_function_link()));
}
@@ -1238,92 +1187,413 @@ TEST(TestInternalWeakListsTraverseWithGC) {
}
+TEST(TestSizeOfObjects) {
+ v8::V8::Initialize();
+
+ // Get initial heap size after several full GCs, which will stabilize
+ // the heap size and return with sweeping finished completely.
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ CHECK(HEAP->old_pointer_space()->IsSweepingComplete());
+ int initial_size = static_cast<int>(HEAP->SizeOfObjects());
+
+ {
+ // Allocate objects on several different old-space pages so that
+ // lazy sweeping kicks in for subsequent GC runs.
+ AlwaysAllocateScope always_allocate;
+ int filler_size = static_cast<int>(FixedArray::SizeFor(8192));
+ for (int i = 1; i <= 100; i++) {
+ HEAP->AllocateFixedArray(8192, TENURED)->ToObjectChecked();
+ CHECK_EQ(initial_size + i * filler_size,
+ static_cast<int>(HEAP->SizeOfObjects()));
+ }
+ }
+
+ // The heap size should go back to initial size after a full GC, even
+ // though sweeping didn't finish yet.
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ CHECK(!HEAP->old_pointer_space()->IsSweepingComplete());
+ CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects()));
+
+ // Advancing the sweeper step-wise should not change the heap size.
+ while (!HEAP->old_pointer_space()->IsSweepingComplete()) {
+ HEAP->old_pointer_space()->AdvanceSweeper(KB);
+ CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects()));
+ }
+}
+
+
TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
InitializeVM();
+ HEAP->EnsureHeapIsIterable();
intptr_t size_of_objects_1 = HEAP->SizeOfObjects();
- HeapIterator iterator(HeapIterator::kFilterFreeListNodes);
+ HeapIterator iterator;
intptr_t size_of_objects_2 = 0;
for (HeapObject* obj = iterator.next();
obj != NULL;
obj = iterator.next()) {
size_of_objects_2 += obj->Size();
}
- // Delta must be within 1% of the larger result.
+ // Delta must be within 5% of the larger result.
+ // TODO(gc): Tighten this up by distinguishing between byte
+ // arrays that are real and those that merely mark free space
+ // on the heap.
if (size_of_objects_1 > size_of_objects_2) {
intptr_t delta = size_of_objects_1 - size_of_objects_2;
PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, "
"Iterator: %" V8_PTR_PREFIX "d, "
"delta: %" V8_PTR_PREFIX "d\n",
size_of_objects_1, size_of_objects_2, delta);
- CHECK_GT(size_of_objects_1 / 100, delta);
+ CHECK_GT(size_of_objects_1 / 20, delta);
} else {
intptr_t delta = size_of_objects_2 - size_of_objects_1;
PrintF("Heap::SizeOfObjects: %" V8_PTR_PREFIX "d, "
"Iterator: %" V8_PTR_PREFIX "d, "
"delta: %" V8_PTR_PREFIX "d\n",
size_of_objects_1, size_of_objects_2, delta);
- CHECK_GT(size_of_objects_2 / 100, delta);
+ CHECK_GT(size_of_objects_2 / 20, delta);
}
}
-class HeapIteratorTestHelper {
- public:
- HeapIteratorTestHelper(Object* a, Object* b)
- : a_(a), b_(b), a_found_(false), b_found_(false) {}
- bool a_found() { return a_found_; }
- bool b_found() { return b_found_; }
- void IterateHeap(HeapIterator::HeapObjectsFiltering mode) {
- HeapIterator iterator(mode);
- for (HeapObject* obj = iterator.next();
- obj != NULL;
- obj = iterator.next()) {
- if (obj == a_)
- a_found_ = true;
- else if (obj == b_)
- b_found_ = true;
- }
+static void FillUpNewSpace(NewSpace* new_space) {
+ // Fill up new space to the point that it is completely full. Make sure
+ // that the scavenger does not undo the filling.
+ v8::HandleScope scope;
+ AlwaysAllocateScope always_allocate;
+ intptr_t available = new_space->EffectiveCapacity() - new_space->Size();
+ intptr_t number_of_fillers = (available / FixedArray::SizeFor(1000)) - 10;
+ for (intptr_t i = 0; i < number_of_fillers; i++) {
+ CHECK(HEAP->InNewSpace(*FACTORY->NewFixedArray(1000, NOT_TENURED)));
}
- private:
- Object* a_;
- Object* b_;
- bool a_found_;
- bool b_found_;
-};
+}
-TEST(HeapIteratorFilterUnreachable) {
+
+TEST(GrowAndShrinkNewSpace) {
+ InitializeVM();
+ NewSpace* new_space = HEAP->new_space();
+
+ // Explicitly growing should double the space capacity.
+ intptr_t old_capacity, new_capacity;
+ old_capacity = new_space->Capacity();
+ new_space->Grow();
+ new_capacity = new_space->Capacity();
+ CHECK(2 * old_capacity == new_capacity);
+
+ old_capacity = new_space->Capacity();
+ FillUpNewSpace(new_space);
+ new_capacity = new_space->Capacity();
+ CHECK(old_capacity == new_capacity);
+
+ // Explicitly shrinking should not affect space capacity.
+ old_capacity = new_space->Capacity();
+ new_space->Shrink();
+ new_capacity = new_space->Capacity();
+ CHECK(old_capacity == new_capacity);
+
+ // Let the scavenger empty the new space.
+ HEAP->CollectGarbage(NEW_SPACE);
+ CHECK_LE(new_space->Size(), old_capacity);
+
+ // Explicitly shrinking should halve the space capacity.
+ old_capacity = new_space->Capacity();
+ new_space->Shrink();
+ new_capacity = new_space->Capacity();
+ CHECK(old_capacity == 2 * new_capacity);
+
+ // Consecutive shrinking should not affect space capacity.
+ old_capacity = new_space->Capacity();
+ new_space->Shrink();
+ new_space->Shrink();
+ new_space->Shrink();
+ new_capacity = new_space->Capacity();
+ CHECK(old_capacity == new_capacity);
+}
+
+
+TEST(CollectingAllAvailableGarbageShrinksNewSpace) {
InitializeVM();
v8::HandleScope scope;
- CompileRun("a = {}; b = {};");
- v8::Handle<Object> a(ISOLATE->context()->global()->GetProperty(
- *FACTORY->LookupAsciiSymbol("a"))->ToObjectChecked());
- v8::Handle<Object> b(ISOLATE->context()->global()->GetProperty(
- *FACTORY->LookupAsciiSymbol("b"))->ToObjectChecked());
- CHECK_NE(*a, *b);
+ NewSpace* new_space = HEAP->new_space();
+ intptr_t old_capacity, new_capacity;
+ old_capacity = new_space->Capacity();
+ new_space->Grow();
+ new_capacity = new_space->Capacity();
+ CHECK(2 * old_capacity == new_capacity);
+ FillUpNewSpace(new_space);
+ HEAP->CollectAllAvailableGarbage();
+ new_capacity = new_space->Capacity();
+ CHECK(old_capacity == new_capacity);
+}
+
+
+static int NumberOfGlobalObjects() {
+ int count = 0;
+ HeapIterator iterator;
+ for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
+ if (obj->IsGlobalObject()) count++;
+ }
+ return count;
+}
+
+
+// Test that we don't embed maps from foreign contexts into
+// optimized code.
+TEST(LeakGlobalContextViaMap) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope outer_scope;
+ v8::Persistent<v8::Context> ctx1 = v8::Context::New();
+ v8::Persistent<v8::Context> ctx2 = v8::Context::New();
+ ctx1->Enter();
+
+ HEAP->CollectAllAvailableGarbage();
+ CHECK_EQ(4, NumberOfGlobalObjects());
+
{
- HeapIteratorTestHelper helper(*a, *b);
- helper.IterateHeap(HeapIterator::kFilterUnreachable);
- CHECK(helper.a_found());
- CHECK(helper.b_found());
+ v8::HandleScope inner_scope;
+ CompileRun("var v = {x: 42}");
+ v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v"));
+ ctx2->Enter();
+ ctx2->Global()->Set(v8_str("o"), v);
+ v8::Local<v8::Value> res = CompileRun(
+ "function f() { return o.x; }"
+ "for (var i = 0; i < 10; ++i) f();"
+ "%OptimizeFunctionOnNextCall(f);"
+ "f();");
+ CHECK_EQ(42, res->Int32Value());
+ ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
+ ctx2->Exit();
+ ctx1->Exit();
+ ctx1.Dispose();
}
- CHECK(ISOLATE->context()->global()->DeleteProperty(
- *FACTORY->LookupAsciiSymbol("a"), JSObject::FORCE_DELETION));
- // We ensure that GC will not happen, so our raw pointer stays valid.
- AssertNoAllocation no_alloc;
- Object* a_saved = *a;
- a.Clear();
- // Verify that "a" object still resides in the heap...
+ HEAP->CollectAllAvailableGarbage();
+ CHECK_EQ(2, NumberOfGlobalObjects());
+ ctx2.Dispose();
+ HEAP->CollectAllAvailableGarbage();
+ CHECK_EQ(0, NumberOfGlobalObjects());
+}
+
+
+// Test that we don't embed functions from foreign contexts into
+// optimized code.
+TEST(LeakGlobalContextViaFunction) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope outer_scope;
+ v8::Persistent<v8::Context> ctx1 = v8::Context::New();
+ v8::Persistent<v8::Context> ctx2 = v8::Context::New();
+ ctx1->Enter();
+
+ HEAP->CollectAllAvailableGarbage();
+ CHECK_EQ(4, NumberOfGlobalObjects());
+
{
- HeapIteratorTestHelper helper(a_saved, *b);
- helper.IterateHeap(HeapIterator::kNoFiltering);
- CHECK(helper.a_found());
- CHECK(helper.b_found());
+ v8::HandleScope inner_scope;
+ CompileRun("var v = function() { return 42; }");
+ v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v"));
+ ctx2->Enter();
+ ctx2->Global()->Set(v8_str("o"), v);
+ v8::Local<v8::Value> res = CompileRun(
+ "function f(x) { return x(); }"
+ "for (var i = 0; i < 10; ++i) f(o);"
+ "%OptimizeFunctionOnNextCall(f);"
+ "f(o);");
+ CHECK_EQ(42, res->Int32Value());
+ ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
+ ctx2->Exit();
+ ctx1->Exit();
+ ctx1.Dispose();
}
- // ...but is now unreachable.
+ HEAP->CollectAllAvailableGarbage();
+ CHECK_EQ(2, NumberOfGlobalObjects());
+ ctx2.Dispose();
+ HEAP->CollectAllAvailableGarbage();
+ CHECK_EQ(0, NumberOfGlobalObjects());
+}
+
+
+TEST(LeakGlobalContextViaMapKeyed) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope outer_scope;
+ v8::Persistent<v8::Context> ctx1 = v8::Context::New();
+ v8::Persistent<v8::Context> ctx2 = v8::Context::New();
+ ctx1->Enter();
+
+ HEAP->CollectAllAvailableGarbage();
+ CHECK_EQ(4, NumberOfGlobalObjects());
+
{
- HeapIteratorTestHelper helper(a_saved, *b);
- helper.IterateHeap(HeapIterator::kFilterUnreachable);
- CHECK(!helper.a_found());
- CHECK(helper.b_found());
+ v8::HandleScope inner_scope;
+ CompileRun("var v = [42, 43]");
+ v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v"));
+ ctx2->Enter();
+ ctx2->Global()->Set(v8_str("o"), v);
+ v8::Local<v8::Value> res = CompileRun(
+ "function f() { return o[0]; }"
+ "for (var i = 0; i < 10; ++i) f();"
+ "%OptimizeFunctionOnNextCall(f);"
+ "f();");
+ CHECK_EQ(42, res->Int32Value());
+ ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
+ ctx2->Exit();
+ ctx1->Exit();
+ ctx1.Dispose();
}
+ HEAP->CollectAllAvailableGarbage();
+ CHECK_EQ(2, NumberOfGlobalObjects());
+ ctx2.Dispose();
+ HEAP->CollectAllAvailableGarbage();
+ CHECK_EQ(0, NumberOfGlobalObjects());
+}
+
+
+TEST(LeakGlobalContextViaMapProto) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::HandleScope outer_scope;
+ v8::Persistent<v8::Context> ctx1 = v8::Context::New();
+ v8::Persistent<v8::Context> ctx2 = v8::Context::New();
+ ctx1->Enter();
+
+ HEAP->CollectAllAvailableGarbage();
+ CHECK_EQ(4, NumberOfGlobalObjects());
+
+ {
+ v8::HandleScope inner_scope;
+ CompileRun("var v = { y: 42}");
+ v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v"));
+ ctx2->Enter();
+ ctx2->Global()->Set(v8_str("o"), v);
+ v8::Local<v8::Value> res = CompileRun(
+ "function f() {"
+ " var p = {x: 42};"
+ " p.__proto__ = o;"
+ " return p.x;"
+ "}"
+ "for (var i = 0; i < 10; ++i) f();"
+ "%OptimizeFunctionOnNextCall(f);"
+ "f();");
+ CHECK_EQ(42, res->Int32Value());
+ ctx2->Global()->Set(v8_str("o"), v8::Int32::New(0));
+ ctx2->Exit();
+ ctx1->Exit();
+ ctx1.Dispose();
+ }
+ HEAP->CollectAllAvailableGarbage();
+ CHECK_EQ(2, NumberOfGlobalObjects());
+ ctx2.Dispose();
+ HEAP->CollectAllAvailableGarbage();
+ CHECK_EQ(0, NumberOfGlobalObjects());
+}
+
+
+TEST(InstanceOfStubWriteBarrier) {
+ i::FLAG_allow_natives_syntax = true;
+#ifdef DEBUG
+ i::FLAG_verify_heap = true;
+#endif
+ InitializeVM();
+ if (!i::V8::UseCrankshaft()) return;
+ v8::HandleScope outer_scope;
+
+ {
+ v8::HandleScope scope;
+ CompileRun(
+ "function foo () { }"
+ "function mkbar () { return new (new Function(\"\")) (); }"
+ "function f (x) { return (x instanceof foo); }"
+ "function g () { f(mkbar()); }"
+ "f(new foo()); f(new foo());"
+ "%OptimizeFunctionOnNextCall(f);"
+ "f(new foo()); g();");
+ }
+
+ IncrementalMarking* marking = HEAP->incremental_marking();
+ marking->Abort();
+ marking->Start();
+
+ Handle<JSFunction> f =
+ v8::Utils::OpenHandle(
+ *v8::Handle<v8::Function>::Cast(
+ v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
+
+ CHECK(f->IsOptimized());
+
+ while (!Marking::IsBlack(Marking::MarkBitFrom(f->code())) &&
+ !marking->IsStopped()) {
+ marking->Step(MB);
+ }
+
+ CHECK(marking->IsMarking());
+
+ // Discard any pending GC requests otherwise we will get GC when we enter
+ // code below.
+ if (ISOLATE->stack_guard()->IsGCRequest()) {
+ ISOLATE->stack_guard()->Continue(GC_REQUEST);
+ }
+
+ {
+ v8::HandleScope scope;
+ v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global();
+ v8::Handle<v8::Function> g =
+ v8::Handle<v8::Function>::Cast(global->Get(v8_str("g")));
+ g->Call(global, 0, NULL);
+ }
+
+ HEAP->incremental_marking()->set_should_hurry(true);
+ HEAP->CollectGarbage(OLD_POINTER_SPACE);
+}
+
+
+TEST(PrototypeTransitionClearing) {
+ InitializeVM();
+ v8::HandleScope scope;
+
+ CompileRun(
+ "var base = {};"
+ "var live = [];"
+ "for (var i = 0; i < 10; i++) {"
+ " var object = {};"
+ " var prototype = {};"
+ " object.__proto__ = prototype;"
+ " if (i >= 3) live.push(object, prototype);"
+ "}");
+
+ Handle<JSObject> baseObject =
+ v8::Utils::OpenHandle(
+ *v8::Handle<v8::Object>::Cast(
+ v8::Context::GetCurrent()->Global()->Get(v8_str("base"))));
+
+ // Verify that only dead prototype transitions are cleared.
+ CHECK_EQ(10, baseObject->map()->NumberOfProtoTransitions());
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ CHECK_EQ(10 - 3, baseObject->map()->NumberOfProtoTransitions());
+
+ // Verify that prototype transitions array was compacted.
+ FixedArray* trans = baseObject->map()->prototype_transitions();
+ for (int i = 0; i < 10 - 3; i++) {
+ int j = Map::kProtoTransitionHeaderSize +
+ i * Map::kProtoTransitionElementsPerEntry;
+ CHECK(trans->get(j + Map::kProtoTransitionMapOffset)->IsMap());
+ CHECK(trans->get(j + Map::kProtoTransitionPrototypeOffset)->IsJSObject());
+ }
+
+ // Make sure next prototype is placed on an old-space evacuation candidate.
+ Handle<JSObject> prototype;
+ PagedSpace* space = HEAP->old_pointer_space();
+ do {
+ prototype = FACTORY->NewJSArray(32 * KB, FAST_ELEMENTS, TENURED);
+ } while (space->FirstPage() == space->LastPage() ||
+ !space->LastPage()->Contains(prototype->address()));
+
+ // Add a prototype on an evacuation candidate and verify that transition
+ // clearing correctly records slots in prototype transition array.
+ i::FLAG_always_compact = true;
+ Handle<Map> map(baseObject->map());
+ CHECK(!space->LastPage()->Contains(map->prototype_transitions()->address()));
+ CHECK(space->LastPage()->Contains(prototype->address()));
+ baseObject->SetPrototype(*prototype, false)->ToObjectChecked();
+ CHECK(map->GetPrototypeTransition(*prototype)->IsMap());
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ CHECK(map->GetPrototypeTransition(*prototype)->IsMap());
}
diff --git a/test/cctest/test-lockers.cc b/test/cctest/test-lockers.cc
index 7360da52..5035f876 100644
--- a/test/cctest/test-lockers.cc
+++ b/test/cctest/test-lockers.cc
@@ -204,7 +204,11 @@ static void StartJoinAndDeleteThreads(const i::List<JoinableThread*>& threads) {
// Run many threads all locking on the same isolate
TEST(IsolateLockingStress) {
+#ifdef V8_TARGET_ARCH_MIPS
+ const int kNThreads = 50;
+#else
const int kNThreads = 100;
+#endif
i::List<JoinableThread*> threads(kNThreads);
v8::Isolate* isolate = v8::Isolate::New();
for (int i = 0; i < kNThreads; i++) {
@@ -237,7 +241,7 @@ class IsolateNonlockingThread : public JoinableThread {
// Run many threads each accessing its own isolate without locking
TEST(MultithreadedParallelIsolates) {
-#ifdef V8_TARGET_ARCH_ARM
+#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
const int kNThreads = 10;
#else
const int kNThreads = 50;
@@ -275,7 +279,11 @@ class IsolateNestedLockingThread : public JoinableThread {
// Run many threads with nested locks
TEST(IsolateNestedLocking) {
+#ifdef V8_TARGET_ARCH_MIPS
+ const int kNThreads = 50;
+#else
const int kNThreads = 100;
+#endif
v8::Isolate* isolate = v8::Isolate::New();
i::List<JoinableThread*> threads(kNThreads);
for (int i = 0; i < kNThreads; i++) {
@@ -311,7 +319,7 @@ class SeparateIsolatesLocksNonexclusiveThread : public JoinableThread {
// Run parallel threads that lock and access different isolates in parallel
TEST(SeparateIsolatesLocksNonexclusive) {
-#ifdef V8_TARGET_ARCH_ARM
+#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
const int kNThreads = 50;
#else
const int kNThreads = 100;
@@ -385,7 +393,7 @@ class LockerUnlockerThread : public JoinableThread {
// Use unlocker inside of a Locker, multiple threads.
TEST(LockerUnlocker) {
-#ifdef V8_TARGET_ARCH_ARM
+#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
const int kNThreads = 50;
#else
const int kNThreads = 100;
@@ -438,7 +446,7 @@ class LockTwiceAndUnlockThread : public JoinableThread {
// Use Unlocker inside two Lockers.
TEST(LockTwiceAndUnlock) {
-#ifdef V8_TARGET_ARCH_ARM
+#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
const int kNThreads = 50;
#else
const int kNThreads = 100;
@@ -559,7 +567,11 @@ class LockUnlockLockThread : public JoinableThread {
// Locker inside an Unlocker inside a Locker.
TEST(LockUnlockLockMultithreaded) {
+#ifdef V8_TARGET_ARCH_MIPS
+ const int kNThreads = 50;
+#else
const int kNThreads = 100;
+#endif
v8::Isolate* isolate = v8::Isolate::New();
Persistent<v8::Context> context;
{
@@ -606,7 +618,11 @@ class LockUnlockLockDefaultIsolateThread : public JoinableThread {
// Locker inside an Unlocker inside a Locker for default isolate.
TEST(LockUnlockLockDefaultIsolateMultithreaded) {
+#ifdef V8_TARGET_ARCH_MIPS
+ const int kNThreads = 50;
+#else
const int kNThreads = 100;
+#endif
Persistent<v8::Context> context;
{
v8::Locker locker_;
@@ -639,3 +655,68 @@ TEST(Regress1433) {
isolate->Dispose();
}
}
+
+
+static const char* kSimpleExtensionSource =
+ "(function Foo() {"
+ " return 4;"
+ "})() ";
+
+class IsolateGenesisThread : public JoinableThread {
+ public:
+ IsolateGenesisThread(int count, const char* extension_names[])
+ : JoinableThread("IsolateGenesisThread"),
+ count_(count),
+ extension_names_(extension_names)
+ {}
+
+ virtual void Run() {
+ v8::Isolate* isolate = v8::Isolate::New();
+ {
+ v8::Isolate::Scope isolate_scope(isolate);
+ CHECK(!i::Isolate::Current()->has_installed_extensions());
+ v8::ExtensionConfiguration extensions(count_, extension_names_);
+ v8::Persistent<v8::Context> context = v8::Context::New(&extensions);
+ CHECK(i::Isolate::Current()->has_installed_extensions());
+ context.Dispose();
+ }
+ isolate->Dispose();
+ }
+ private:
+ int count_;
+ const char** extension_names_;
+};
+
+// Test installing extensions in separate isolates concurrently.
+// http://code.google.com/p/v8/issues/detail?id=1821
+TEST(ExtensionsRegistration) {
+#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
+ const int kNThreads = 10;
+#else
+ const int kNThreads = 40;
+#endif
+ v8::RegisterExtension(new v8::Extension("test0",
+ kSimpleExtensionSource));
+ v8::RegisterExtension(new v8::Extension("test1",
+ kSimpleExtensionSource));
+ v8::RegisterExtension(new v8::Extension("test2",
+ kSimpleExtensionSource));
+ v8::RegisterExtension(new v8::Extension("test3",
+ kSimpleExtensionSource));
+ v8::RegisterExtension(new v8::Extension("test4",
+ kSimpleExtensionSource));
+ v8::RegisterExtension(new v8::Extension("test5",
+ kSimpleExtensionSource));
+ v8::RegisterExtension(new v8::Extension("test6",
+ kSimpleExtensionSource));
+ v8::RegisterExtension(new v8::Extension("test7",
+ kSimpleExtensionSource));
+ const char* extension_names[] = { "test0", "test1",
+ "test2", "test3", "test4",
+ "test5", "test6", "test7" };
+ i::List<JoinableThread*> threads(kNThreads);
+ for (int i = 0; i < kNThreads; i++) {
+ threads.Add(new IsolateGenesisThread(8, extension_names));
+ }
+ StartJoinAndDeleteThreads(threads);
+}
diff --git a/test/cctest/test-log-stack-tracer.cc b/test/cctest/test-log-stack-tracer.cc
index f536e6b1..6847ef7e 100644
--- a/test/cctest/test-log-stack-tracer.cc
+++ b/test/cctest/test-log-stack-tracer.cc
@@ -307,6 +307,7 @@ TEST(CFromJSStackTrace) {
// Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace"
int base = 0;
CHECK_GT(sample.frames_count, base + 1);
+
CHECK(IsAddressWithinFuncCode("JSFuncDoTrace", sample.stack[base + 0]));
CHECK(IsAddressWithinFuncCode("JSTrace", sample.stack[base + 1]));
}
diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc
index 72e663c4..6f2324db 100644
--- a/test/cctest/test-log.cc
+++ b/test/cctest/test-log.cc
@@ -494,7 +494,7 @@ TEST(EquivalenceOfLoggingAndTraversal) {
" (function a(j) { return function b() { return j; } })(100);\n"
"})(this);");
v8::V8::PauseProfiler();
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask);
LOGGER->StringEvent("test-logging-done", "");
// Iterate heap to find compiled functions, will write to log.
diff --git a/test/cctest/test-mark-compact.cc b/test/cctest/test-mark-compact.cc
index dcb51a0b..973af196 100644
--- a/test/cctest/test-mark-compact.cc
+++ b/test/cctest/test-mark-compact.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -27,6 +27,14 @@
#include <stdlib.h>
+#ifdef __linux__
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#endif
+
#include "v8.h"
#include "global-handles.h"
@@ -44,21 +52,21 @@ static void InitializeVM() {
}
-TEST(MarkingStack) {
+TEST(MarkingDeque) {
int mem_size = 20 * kPointerSize;
byte* mem = NewArray<byte>(20*kPointerSize);
Address low = reinterpret_cast<Address>(mem);
Address high = low + mem_size;
- MarkingStack s;
+ MarkingDeque s;
s.Initialize(low, high);
Address address = NULL;
- while (!s.is_full()) {
- s.Push(HeapObject::FromAddress(address));
+ while (!s.IsFull()) {
+ s.PushBlack(HeapObject::FromAddress(address));
address += kPointerSize;
}
- while (!s.is_empty()) {
+ while (!s.IsEmpty()) {
Address value = s.Pop()->address();
address -= kPointerSize;
CHECK_EQ(address, value);
@@ -78,7 +86,7 @@ TEST(Promotion) {
// from new space.
FLAG_gc_global = true;
FLAG_always_compact = true;
- HEAP->ConfigureHeap(2*256*KB, 4*MB, 4*MB);
+ HEAP->ConfigureHeap(2*256*KB, 8*MB, 8*MB);
InitializeVM();
@@ -86,7 +94,7 @@ TEST(Promotion) {
// Allocate a fixed array in the new space.
int array_size =
- (HEAP->MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) /
+ (Page::kMaxNonCodeHeapObjectSize - FixedArray::kHeaderSize) /
(kPointerSize * 4);
Object* obj = HEAP->AllocateFixedArray(array_size)->ToObjectChecked();
@@ -104,7 +112,7 @@ TEST(Promotion) {
TEST(NoPromotion) {
- HEAP->ConfigureHeap(2*256*KB, 4*MB, 4*MB);
+ HEAP->ConfigureHeap(2*256*KB, 8*MB, 8*MB);
// Test the situation that some objects in new space are promoted to
// the old space
@@ -116,9 +124,12 @@ TEST(NoPromotion) {
HEAP->CollectGarbage(OLD_POINTER_SPACE);
// Allocate a big Fixed array in the new space.
- int size = (HEAP->MaxObjectSizeInPagedSpace() - FixedArray::kHeaderSize) /
- kPointerSize;
- Object* obj = HEAP->AllocateFixedArray(size)->ToObjectChecked();
+ int max_size =
+ Min(Page::kMaxNonCodeHeapObjectSize, HEAP->MaxObjectSizeInNewSpace());
+
+ int length = (max_size - FixedArray::kHeaderSize) / (2*kPointerSize);
+ Object* obj = i::Isolate::Current()->heap()->AllocateFixedArray(length)->
+ ToObjectChecked();
Handle<FixedArray> array(FixedArray::cast(obj));
@@ -139,9 +150,6 @@ TEST(NoPromotion) {
// Call mark compact GC, and it should pass.
HEAP->CollectGarbage(OLD_POINTER_SPACE);
-
- // array should not be promoted because the old space is full.
- CHECK(HEAP->InSpace(*array, NEW_SPACE));
}
@@ -228,6 +236,8 @@ TEST(MarkCompactCollector) {
}
+// TODO(1600): compaction of map space is temporary removed from GC.
+#if 0
static Handle<Map> CreateMap() {
return FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
}
@@ -252,11 +262,11 @@ TEST(MapCompact) {
// be able to trigger map compaction.
// To give an additional chance to fail, try to force compaction which
// should be impossible right now.
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(Heap::kForceCompactionMask);
// And now map pointers should be encodable again.
CHECK(HEAP->map_space()->MapPointersEncodable());
}
-
+#endif
static int gc_starts = 0;
static int gc_ends = 0;
@@ -442,3 +452,100 @@ TEST(EmptyObjectGroups) {
global_handles->AddImplicitReferences(
Handle<HeapObject>::cast(object).location(), NULL, 0);
}
+
+
+// Here is a memory use test that uses /proc, and is therefore Linux-only. We
+// do not care how much memory the simulator uses, since it is only there for
+// debugging purposes.
+#if defined(__linux__) && !defined(USE_SIMULATOR)
+
+
+static uintptr_t ReadLong(char* buffer, intptr_t* position, int base) {
+ char* end_address = buffer + *position;
+ uintptr_t result = strtoul(buffer + *position, &end_address, base);
+ CHECK(result != ULONG_MAX || errno != ERANGE);
+ CHECK(end_address > buffer + *position);
+ *position = end_address - buffer;
+ return result;
+}
+
+
+static intptr_t MemoryInUse() {
+ intptr_t memory_use = 0;
+
+ int fd = open("/proc/self/maps", O_RDONLY);
+ if (fd < 0) return -1;
+
+ const int kBufSize = 10000;
+ char buffer[kBufSize];
+ int length = read(fd, buffer, kBufSize);
+ intptr_t line_start = 0;
+ CHECK_LT(length, kBufSize); // Make the buffer bigger.
+ CHECK_GT(length, 0); // We have to find some data in the file.
+ while (line_start < length) {
+ if (buffer[line_start] == '\n') {
+ line_start++;
+ continue;
+ }
+ intptr_t position = line_start;
+ uintptr_t start = ReadLong(buffer, &position, 16);
+ CHECK_EQ(buffer[position++], '-');
+ uintptr_t end = ReadLong(buffer, &position, 16);
+ CHECK_EQ(buffer[position++], ' ');
+ CHECK(buffer[position] == '-' || buffer[position] == 'r');
+ bool read_permission = (buffer[position++] == 'r');
+ CHECK(buffer[position] == '-' || buffer[position] == 'w');
+ bool write_permission = (buffer[position++] == 'w');
+ CHECK(buffer[position] == '-' || buffer[position] == 'x');
+ bool execute_permission = (buffer[position++] == 'x');
+ CHECK(buffer[position] == '-' || buffer[position] == 'p');
+ bool private_mapping = (buffer[position++] == 'p');
+ CHECK_EQ(buffer[position++], ' ');
+ uintptr_t offset = ReadLong(buffer, &position, 16);
+ USE(offset);
+ CHECK_EQ(buffer[position++], ' ');
+ uintptr_t major = ReadLong(buffer, &position, 16);
+ USE(major);
+ CHECK_EQ(buffer[position++], ':');
+ uintptr_t minor = ReadLong(buffer, &position, 16);
+ USE(minor);
+ CHECK_EQ(buffer[position++], ' ');
+ uintptr_t inode = ReadLong(buffer, &position, 10);
+ while (position < length && buffer[position] != '\n') position++;
+ if ((read_permission || write_permission || execute_permission) &&
+ private_mapping && inode == 0) {
+ memory_use += (end - start);
+ }
+
+ line_start = position;
+ }
+ close(fd);
+ return memory_use;
+}
+
+
+TEST(BootUpMemoryUse) {
+ intptr_t initial_memory = MemoryInUse();
+ FLAG_crankshaft = false; // Avoid flakiness.
+ // Only Linux has the proc filesystem and only if it is mapped. If it's not
+ // there we just skip the test.
+ if (initial_memory >= 0) {
+ InitializeVM();
+ intptr_t booted_memory = MemoryInUse();
+ if (sizeof(initial_memory) == 8) {
+ if (v8::internal::Snapshot::IsEnabled()) {
+ CHECK_LE(booted_memory - initial_memory, 6686 * 1024); // 6476.
+ } else {
+ CHECK_LE(booted_memory - initial_memory, 6809 * 1024); // 6628.
+ }
+ } else {
+ if (v8::internal::Snapshot::IsEnabled()) {
+ CHECK_LE(booted_memory - initial_memory, 6532 * 1024); // 6388.
+ } else {
+ CHECK_LE(booted_memory - initial_memory, 6940 * 1024); // 6456
+ }
+ }
+ }
+}
+
+#endif // __linux__ and !USE_SIMULATOR
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index d98b6753..6bcae7c3 100755
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -32,6 +32,7 @@
#include "v8.h"
#include "cctest.h"
+#include "compiler.h"
#include "execution.h"
#include "isolate.h"
#include "parser.h"
@@ -62,18 +63,19 @@ TEST(ScanKeywords) {
int length = i::StrLength(key_token.keyword);
CHECK(static_cast<int>(sizeof(buffer)) >= length);
{
- i::Utf8ToUC16CharacterStream stream(keyword, length);
- i::JavaScriptScanner scanner(&unicode_cache);
- // The scanner should parse 'let' as Token::LET for this test.
- scanner.SetHarmonyBlockScoping(true);
+ i::Utf8ToUtf16CharacterStream stream(keyword, length);
+ i::Scanner scanner(&unicode_cache);
+ // The scanner should parse Harmony keywords for this test.
+ scanner.SetHarmonyScoping(true);
+ scanner.SetHarmonyModules(true);
scanner.Initialize(&stream);
CHECK_EQ(key_token.token, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next());
}
// Removing characters will make keyword matching fail.
{
- i::Utf8ToUC16CharacterStream stream(keyword, length - 1);
- i::JavaScriptScanner scanner(&unicode_cache);
+ i::Utf8ToUtf16CharacterStream stream(keyword, length - 1);
+ i::Scanner scanner(&unicode_cache);
scanner.Initialize(&stream);
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next());
@@ -83,8 +85,8 @@ TEST(ScanKeywords) {
for (int j = 0; j < static_cast<int>(ARRAY_SIZE(chars_to_append)); ++j) {
memmove(buffer, keyword, length);
buffer[length] = chars_to_append[j];
- i::Utf8ToUC16CharacterStream stream(buffer, length + 1);
- i::JavaScriptScanner scanner(&unicode_cache);
+ i::Utf8ToUtf16CharacterStream stream(buffer, length + 1);
+ i::Scanner scanner(&unicode_cache);
scanner.Initialize(&stream);
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next());
@@ -93,8 +95,8 @@ TEST(ScanKeywords) {
{
memmove(buffer, keyword, length);
buffer[length - 1] = '_';
- i::Utf8ToUC16CharacterStream stream(buffer, length);
- i::JavaScriptScanner scanner(&unicode_cache);
+ i::Utf8ToUtf16CharacterStream stream(buffer, length);
+ i::Scanner scanner(&unicode_cache);
scanner.Initialize(&stream);
CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next());
@@ -229,7 +231,7 @@ TEST(Preparsing) {
CHECK_EQ(11, error_location.end_pos);
// Should not crash.
const char* message = pre_impl->BuildMessage();
- i::Vector<const char*> args = pre_impl->BuildArgs();
+ pre_impl->BuildArgs();
CHECK_GT(strlen(message), 0);
}
@@ -253,17 +255,18 @@ TEST(StandAlonePreParser) {
uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
for (int i = 0; programs[i]; i++) {
const char* program = programs[i];
- i::Utf8ToUC16CharacterStream stream(
+ i::Utf8ToUtf16CharacterStream stream(
reinterpret_cast<const i::byte*>(program),
static_cast<unsigned>(strlen(program)));
i::CompleteParserRecorder log;
- i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
+ i::Scanner scanner(i::Isolate::Current()->unicode_cache());
scanner.Initialize(&stream);
+ int flags = i::kAllowLazy | i::kAllowNativesSyntax;
v8::preparser::PreParser::PreParseResult result =
v8::preparser::PreParser::PreParseProgram(&scanner,
&log,
- true,
+ flags,
stack_limit);
CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result);
i::ScriptDataImpl data(log.ExtractData());
@@ -272,6 +275,43 @@ TEST(StandAlonePreParser) {
}
+TEST(StandAlonePreParserNoNatives) {
+ v8::V8::Initialize();
+
+ int marker;
+ i::Isolate::Current()->stack_guard()->SetStackLimit(
+ reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+
+ const char* programs[] = {
+ "%ArgleBargle(glop);",
+ "var x = %_IsSmi(42);",
+ NULL
+ };
+
+ uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
+ for (int i = 0; programs[i]; i++) {
+ const char* program = programs[i];
+ i::Utf8ToUtf16CharacterStream stream(
+ reinterpret_cast<const i::byte*>(program),
+ static_cast<unsigned>(strlen(program)));
+ i::CompleteParserRecorder log;
+ i::Scanner scanner(i::Isolate::Current()->unicode_cache());
+ scanner.Initialize(&stream);
+
+ // Flags don't allow natives syntax.
+ v8::preparser::PreParser::PreParseResult result =
+ v8::preparser::PreParser::PreParseProgram(&scanner,
+ &log,
+ i::kAllowLazy,
+ stack_limit);
+ CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result);
+ i::ScriptDataImpl data(log.ExtractData());
+ // Data contains syntax error.
+ CHECK(data.has_error());
+ }
+}
+
+
TEST(RegressChromium62639) {
v8::V8::Initialize();
@@ -286,8 +326,9 @@ TEST(RegressChromium62639) {
// and then used the invalid currently scanned literal. This always
// failed in debug mode, and sometimes crashed in release mode.
- i::Utf8ToUC16CharacterStream stream(reinterpret_cast<const i::byte*>(program),
- static_cast<unsigned>(strlen(program)));
+ i::Utf8ToUtf16CharacterStream stream(
+ reinterpret_cast<const i::byte*>(program),
+ static_cast<unsigned>(strlen(program)));
i::ScriptDataImpl* data =
i::ParserApi::PreParse(&stream, NULL, false);
CHECK(data->HasError());
@@ -310,17 +351,17 @@ TEST(Regress928) {
"try { } catch (e) { var foo = function () { /* first */ } }"
"var bar = function () { /* second */ }";
- i::Utf8ToUC16CharacterStream stream(reinterpret_cast<const i::byte*>(program),
- static_cast<unsigned>(strlen(program)));
- i::ScriptDataImpl* data =
- i::ParserApi::PartialPreParse(&stream, NULL, false);
+ v8::HandleScope handles;
+ i::Handle<i::String> source(
+ FACTORY->NewStringFromAscii(i::CStrVector(program)));
+ i::ScriptDataImpl* data = i::ParserApi::PartialPreParse(source, NULL, false);
CHECK(!data->HasError());
data->Initialize();
int first_function =
static_cast<int>(strstr(program, "function") - program);
- int first_lbrace = first_function + static_cast<int>(strlen("function () "));
+ int first_lbrace = first_function + i::StrLength("function () ");
CHECK_EQ('{', program[first_lbrace]);
i::FunctionEntry entry1 = data->GetFunctionEntry(first_lbrace);
CHECK(!entry1.is_valid());
@@ -328,7 +369,7 @@ TEST(Regress928) {
int second_function =
static_cast<int>(strstr(program + first_lbrace, "function") - program);
int second_lbrace =
- second_function + static_cast<int>(strlen("function () "));
+ second_function + i::StrLength("function () ");
CHECK_EQ('{', program[second_lbrace]);
i::FunctionEntry entry2 = data->GetFunctionEntry(second_lbrace);
CHECK(entry2.is_valid());
@@ -352,11 +393,11 @@ TEST(PreParseOverflow) {
uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
- i::Utf8ToUC16CharacterStream stream(
+ i::Utf8ToUtf16CharacterStream stream(
reinterpret_cast<const i::byte*>(*program),
static_cast<unsigned>(kProgramSize));
i::CompleteParserRecorder log;
- i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
+ i::Scanner scanner(i::Isolate::Current()->unicode_cache());
scanner.Initialize(&stream);
@@ -409,10 +450,10 @@ void TestCharacterStream(const char* ascii_source,
i::Handle<i::String> uc16_string(
FACTORY->NewExternalStringFromTwoByte(&resource));
- i::ExternalTwoByteStringUC16CharacterStream uc16_stream(
+ i::ExternalTwoByteStringUtf16CharacterStream uc16_stream(
i::Handle<i::ExternalTwoByteString>::cast(uc16_string), start, end);
- i::GenericStringUC16CharacterStream string_stream(ascii_string, start, end);
- i::Utf8ToUC16CharacterStream utf8_stream(
+ i::GenericStringUtf16CharacterStream string_stream(ascii_string, start, end);
+ i::Utf8ToUtf16CharacterStream utf8_stream(
reinterpret_cast<const i::byte*>(ascii_source), end);
utf8_stream.SeekForward(start);
@@ -535,12 +576,14 @@ TEST(Utf8CharacterStream) {
char buffer[kAllUtf8CharsSizeU];
unsigned cursor = 0;
for (int i = 0; i <= kMaxUC16Char; i++) {
- cursor += unibrow::Utf8::Encode(buffer + cursor, i);
+ cursor += unibrow::Utf8::Encode(buffer + cursor,
+ i,
+ unibrow::Utf16::kNoPreviousCharacter);
}
ASSERT(cursor == kAllUtf8CharsSizeU);
- i::Utf8ToUC16CharacterStream stream(reinterpret_cast<const i::byte*>(buffer),
- kAllUtf8CharsSizeU);
+ i::Utf8ToUtf16CharacterStream stream(reinterpret_cast<const i::byte*>(buffer),
+ kAllUtf8CharsSizeU);
for (int i = 0; i <= kMaxUC16Char; i++) {
CHECK_EQU(i, stream.pos());
int32_t c = stream.Advance();
@@ -570,11 +613,11 @@ TEST(Utf8CharacterStream) {
#undef CHECK_EQU
-void TestStreamScanner(i::UC16CharacterStream* stream,
+void TestStreamScanner(i::Utf16CharacterStream* stream,
i::Token::Value* expected_tokens,
int skip_pos = 0, // Zero means not skipping.
int skip_to = 0) {
- i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
+ i::Scanner scanner(i::Isolate::Current()->unicode_cache());
scanner.Initialize(stream);
int i = 0;
@@ -593,8 +636,8 @@ TEST(StreamScanner) {
v8::V8::Initialize();
const char* str1 = "{ foo get for : */ <- \n\n /*foo*/ bib";
- i::Utf8ToUC16CharacterStream stream1(reinterpret_cast<const i::byte*>(str1),
- static_cast<unsigned>(strlen(str1)));
+ i::Utf8ToUtf16CharacterStream stream1(reinterpret_cast<const i::byte*>(str1),
+ static_cast<unsigned>(strlen(str1)));
i::Token::Value expectations1[] = {
i::Token::LBRACE,
i::Token::IDENTIFIER,
@@ -612,8 +655,8 @@ TEST(StreamScanner) {
TestStreamScanner(&stream1, expectations1, 0, 0);
const char* str2 = "case default const {THIS\nPART\nSKIPPED} do";
- i::Utf8ToUC16CharacterStream stream2(reinterpret_cast<const i::byte*>(str2),
- static_cast<unsigned>(strlen(str2)));
+ i::Utf8ToUtf16CharacterStream stream2(reinterpret_cast<const i::byte*>(str2),
+ static_cast<unsigned>(strlen(str2)));
i::Token::Value expectations2[] = {
i::Token::CASE,
i::Token::DEFAULT,
@@ -643,7 +686,7 @@ TEST(StreamScanner) {
for (int i = 0; i <= 4; i++) {
expectations3[6 - i] = i::Token::ILLEGAL;
expectations3[5 - i] = i::Token::EOS;
- i::Utf8ToUC16CharacterStream stream3(
+ i::Utf8ToUtf16CharacterStream stream3(
reinterpret_cast<const i::byte*>(str3),
static_cast<unsigned>(strlen(str3)));
TestStreamScanner(&stream3, expectations3, 1, 1 + i);
@@ -652,10 +695,10 @@ TEST(StreamScanner) {
void TestScanRegExp(const char* re_source, const char* expected) {
- i::Utf8ToUC16CharacterStream stream(
+ i::Utf8ToUtf16CharacterStream stream(
reinterpret_cast<const i::byte*>(re_source),
static_cast<unsigned>(strlen(re_source)));
- i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
+ i::Scanner scanner(i::Isolate::Current()->unicode_cache());
scanner.Initialize(&stream);
i::Token::Value start = scanner.peek();
@@ -708,25 +751,320 @@ TEST(RegExpScanning) {
}
-void TestParserSync(i::Handle<i::String> source, bool allow_lazy) {
+static int Utf8LengthHelper(const char* s) {
+ int len = i::StrLength(s);
+ int character_length = len;
+ for (int i = 0; i < len; i++) {
+ unsigned char c = s[i];
+ int input_offset = 0;
+ int output_adjust = 0;
+ if (c > 0x7f) {
+ if (c < 0xc0) continue;
+ if (c >= 0xf0) {
+ if (c >= 0xf8) {
+ // 5 and 6 byte UTF-8 sequences turn into a kBadChar for each UTF-8
+ // byte.
+ continue; // Handle first UTF-8 byte.
+ }
+ if ((c & 7) == 0 && ((s[i + 1] & 0x30) == 0)) {
+ // This 4 byte sequence could have been coded as a 3 byte sequence.
+ // Record a single kBadChar for the first byte and continue.
+ continue;
+ }
+ input_offset = 3;
+ // 4 bytes of UTF-8 turn into 2 UTF-16 code units.
+ character_length -= 2;
+ } else if (c >= 0xe0) {
+ if ((c & 0xf) == 0 && ((s[i + 1] & 0x20) == 0)) {
+ // This 3 byte sequence could have been coded as a 2 byte sequence.
+ // Record a single kBadChar for the first byte and continue.
+ continue;
+ }
+ input_offset = 2;
+ // 3 bytes of UTF-8 turn into 1 UTF-16 code unit.
+ output_adjust = 2;
+ } else {
+ if ((c & 0x1e) == 0) {
+ // This 2 byte sequence could have been coded as a 1 byte sequence.
+ // Record a single kBadChar for the first byte and continue.
+ continue;
+ }
+ input_offset = 1;
+ // 2 bytes of UTF-8 turn into 1 UTF-16 code unit.
+ output_adjust = 1;
+ }
+ bool bad = false;
+ for (int j = 1; j <= input_offset; j++) {
+ if ((s[i + j] & 0xc0) != 0x80) {
+ // Bad UTF-8 sequence turns the first in the sequence into kBadChar,
+ // which is a single UTF-16 code unit.
+ bad = true;
+ break;
+ }
+ }
+ if (!bad) {
+ i += input_offset;
+ character_length -= output_adjust;
+ }
+ }
+ }
+ return character_length;
+}
+
+
+TEST(ScopePositions) {
+ // Test the parser for correctly setting the start and end positions
+ // of a scope. We check the scope positions of exactly one scope
+ // nested in the global scope of a program. 'inner source' is the
+ // source code that determines the part of the source belonging
+ // to the nested scope. 'outer_prefix' and 'outer_suffix' are
+ // parts of the source that belong to the global scope.
+ struct SourceData {
+ const char* outer_prefix;
+ const char* inner_source;
+ const char* outer_suffix;
+ i::ScopeType scope_type;
+ i::LanguageMode language_mode;
+ };
+
+ const SourceData source_data[] = {
+ { " with ({}) ", "{ block; }", " more;", i::WITH_SCOPE, i::CLASSIC_MODE },
+ { " with ({}) ", "{ block; }", "; more;", i::WITH_SCOPE, i::CLASSIC_MODE },
+ { " with ({}) ", "{\n"
+ " block;\n"
+ " }", "\n"
+ " more;", i::WITH_SCOPE, i::CLASSIC_MODE },
+ { " with ({}) ", "statement;", " more;", i::WITH_SCOPE, i::CLASSIC_MODE },
+ { " with ({}) ", "statement", "\n"
+ " more;", i::WITH_SCOPE, i::CLASSIC_MODE },
+ { " with ({})\n"
+ " ", "statement;", "\n"
+ " more;", i::WITH_SCOPE, i::CLASSIC_MODE },
+ { " try {} catch ", "(e) { block; }", " more;",
+ i::CATCH_SCOPE, i::CLASSIC_MODE },
+ { " try {} catch ", "(e) { block; }", "; more;",
+ i::CATCH_SCOPE, i::CLASSIC_MODE },
+ { " try {} catch ", "(e) {\n"
+ " block;\n"
+ " }", "\n"
+ " more;", i::CATCH_SCOPE, i::CLASSIC_MODE },
+ { " try {} catch ", "(e) { block; }", " finally { block; } more;",
+ i::CATCH_SCOPE, i::CLASSIC_MODE },
+ { " start;\n"
+ " ", "{ let block; }", " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " start;\n"
+ " ", "{ let block; }", "; more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " start;\n"
+ " ", "{\n"
+ " let block;\n"
+ " }", "\n"
+ " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " start;\n"
+ " function fun", "(a,b) { infunction; }", " more;",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ { " start;\n"
+ " function fun", "(a,b) {\n"
+ " infunction;\n"
+ " }", "\n"
+ " more;", i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ { " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;",
+ i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;",
+ i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " for ", "(let x = 1 ; x < 10; ++ x) {\n"
+ " block;\n"
+ " }", "\n"
+ " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;",
+ i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " for ", "(let x = 1 ; x < 10; ++ x) statement", "\n"
+ " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " for ", "(let x = 1 ; x < 10; ++ x)\n"
+ " statement;", "\n"
+ " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " for ", "(let x in {}) { block; }", " more;",
+ i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " for ", "(let x in {}) { block; }", "; more;",
+ i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " for ", "(let x in {}) {\n"
+ " block;\n"
+ " }", "\n"
+ " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " for ", "(let x in {}) statement;", " more;",
+ i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " for ", "(let x in {}) statement", "\n"
+ " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ { " for ", "(let x in {})\n"
+ " statement;", "\n"
+ " more;", i::BLOCK_SCOPE, i::EXTENDED_MODE },
+ // Check that 6-byte and 4-byte encodings of UTF-8 strings do not throw
+ // the preparser off in terms of byte offsets.
+ // 6 byte encoding.
+ { " 'foo\355\240\201\355\260\211';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // 4 byte encoding.
+ { " 'foo\360\220\220\212';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // 3 byte encoding of \u0fff.
+ { " 'foo\340\277\277';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Broken 6 byte encoding with missing last byte.
+ { " 'foo\355\240\201\355\211';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Broken 3 byte encoding of \u0fff with missing last byte.
+ { " 'foo\340\277';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Broken 3 byte encoding of \u0fff with missing 2 last bytes.
+ { " 'foo\340';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Broken 3 byte encoding of \u00ff should be a 2 byte encoding.
+ { " 'foo\340\203\277';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Broken 3 byte encoding of \u007f should be a 2 byte encoding.
+ { " 'foo\340\201\277';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Unpaired lead surrogate.
+ { " 'foo\355\240\201';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Unpaired lead surrogate where following code point is a 3 byte sequence.
+ { " 'foo\355\240\201\340\277\277';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Unpaired lead surrogate where following code point is a 4 byte encoding
+ // of a trail surrogate.
+ { " 'foo\355\240\201\360\215\260\211';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Unpaired trail surrogate.
+ { " 'foo\355\260\211';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // 2 byte encoding of \u00ff.
+ { " 'foo\303\277';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Broken 2 byte encoding of \u00ff with missing last byte.
+ { " 'foo\303';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Broken 2 byte encoding of \u007f should be a 1 byte encoding.
+ { " 'foo\301\277';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Illegal 5 byte encoding.
+ { " 'foo\370\277\277\277\277';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Illegal 6 byte encoding.
+ { " 'foo\374\277\277\277\277\277';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Illegal 0xfe byte
+ { " 'foo\376\277\277\277\277\277\277';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ // Illegal 0xff byte
+ { " 'foo\377\277\277\277\277\277\277\277';\n"
+ " (function fun", "(a,b) { infunction; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ { " 'foo';\n"
+ " (function fun", "(a,b) { 'bar\355\240\201\355\260\213'; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ { " 'foo';\n"
+ " (function fun", "(a,b) { 'bar\360\220\220\214'; }", ")();",
+ i::FUNCTION_SCOPE, i::CLASSIC_MODE },
+ { NULL, NULL, NULL, i::EVAL_SCOPE, i::CLASSIC_MODE }
+ };
+
+ v8::HandleScope handles;
+ v8::Persistent<v8::Context> context = v8::Context::New();
+ v8::Context::Scope context_scope(context);
+
+ int marker;
+ i::Isolate::Current()->stack_guard()->SetStackLimit(
+ reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
+ i::FLAG_harmony_scoping = true;
+
+ for (int i = 0; source_data[i].outer_prefix; i++) {
+ int kPrefixLen = Utf8LengthHelper(source_data[i].outer_prefix);
+ int kInnerLen = Utf8LengthHelper(source_data[i].inner_source);
+ int kSuffixLen = Utf8LengthHelper(source_data[i].outer_suffix);
+ int kPrefixByteLen = i::StrLength(source_data[i].outer_prefix);
+ int kInnerByteLen = i::StrLength(source_data[i].inner_source);
+ int kSuffixByteLen = i::StrLength(source_data[i].outer_suffix);
+ int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen;
+ int kProgramByteSize = kPrefixByteLen + kInnerByteLen + kSuffixByteLen;
+ i::Vector<char> program = i::Vector<char>::New(kProgramByteSize + 1);
+ i::OS::SNPrintF(program, "%s%s%s",
+ source_data[i].outer_prefix,
+ source_data[i].inner_source,
+ source_data[i].outer_suffix);
+
+ // Parse program source.
+ i::Handle<i::String> source(
+ FACTORY->NewStringFromUtf8(i::CStrVector(program.start())));
+ CHECK_EQ(source->length(), kProgramSize);
+ i::Handle<i::Script> script = FACTORY->NewScript(source);
+ i::Parser parser(script, i::kAllowLazy | i::EXTENDED_MODE, NULL, NULL);
+ i::CompilationInfo info(script);
+ info.MarkAsGlobal();
+ info.SetLanguageMode(source_data[i].language_mode);
+ i::FunctionLiteral* function = parser.ParseProgram(&info);
+ CHECK(function != NULL);
+
+ // Check scope types and positions.
+ i::Scope* scope = function->scope();
+ CHECK(scope->is_global_scope());
+ CHECK_EQ(scope->start_position(), 0);
+ CHECK_EQ(scope->end_position(), kProgramSize);
+ CHECK_EQ(scope->inner_scopes()->length(), 1);
+
+ i::Scope* inner_scope = scope->inner_scopes()->at(0);
+ CHECK_EQ(inner_scope->type(), source_data[i].scope_type);
+ CHECK_EQ(inner_scope->start_position(), kPrefixLen);
+ // The end position of a token is one position after the last
+ // character belonging to that token.
+ CHECK_EQ(inner_scope->end_position(), kPrefixLen + kInnerLen);
+ }
+}
+
+
+void TestParserSync(i::Handle<i::String> source, int flags) {
uintptr_t stack_limit = i::Isolate::Current()->stack_guard()->real_climit();
+ bool harmony_scoping = ((i::kLanguageModeMask & flags) == i::EXTENDED_MODE);
// Preparse the data.
i::CompleteParserRecorder log;
- i::JavaScriptScanner scanner(i::Isolate::Current()->unicode_cache());
- i::GenericStringUC16CharacterStream stream(source, 0, source->length());
+ i::Scanner scanner(i::Isolate::Current()->unicode_cache());
+ i::GenericStringUtf16CharacterStream stream(source, 0, source->length());
+ scanner.SetHarmonyScoping(harmony_scoping);
scanner.Initialize(&stream);
v8::preparser::PreParser::PreParseResult result =
v8::preparser::PreParser::PreParseProgram(
- &scanner, &log, allow_lazy, stack_limit);
+ &scanner, &log, flags, stack_limit);
CHECK_EQ(v8::preparser::PreParser::kPreParseSuccess, result);
i::ScriptDataImpl data(log.ExtractData());
// Parse the data
i::Handle<i::Script> script = FACTORY->NewScript(source);
- i::Parser parser(script, false, NULL, NULL);
- i::FunctionLiteral* function =
- parser.ParseProgram(source, true, i::kNonStrictMode);
+ bool save_harmony_scoping = i::FLAG_harmony_scoping;
+ i::FLAG_harmony_scoping = harmony_scoping;
+ i::Parser parser(script, flags, NULL, NULL);
+ i::CompilationInfo info(script);
+ info.MarkAsGlobal();
+ i::FunctionLiteral* function = parser.ParseProgram(&info);
+ i::FLAG_harmony_scoping = save_harmony_scoping;
i::String* type_string = NULL;
if (function == NULL) {
@@ -779,6 +1117,23 @@ void TestParserSync(i::Handle<i::String> source, bool allow_lazy) {
}
+void TestParserSyncWithFlags(i::Handle<i::String> source) {
+ static const int kFlagsCount = 6;
+ const int flags[kFlagsCount] = {
+ i::kNoParsingFlags | i::CLASSIC_MODE,
+ i::kNoParsingFlags | i::STRICT_MODE,
+ i::kNoParsingFlags | i::EXTENDED_MODE,
+ i::kAllowLazy | i::CLASSIC_MODE,
+ i::kAllowLazy | i::STRICT_MODE,
+ i::kAllowLazy | i::EXTENDED_MODE
+ };
+
+ for (int k = 0; k < kFlagsCount; ++k) {
+ TestParserSync(source, flags[k]);
+ }
+}
+
+
TEST(ParserSync) {
const char* context_data[][2] = {
{ "", "" },
@@ -876,8 +1231,7 @@ TEST(ParserSync) {
CHECK(length == kProgramSize);
i::Handle<i::String> source =
FACTORY->NewStringFromAscii(i::CStrVector(program.start()));
- TestParserSync(source, true);
- TestParserSync(source, false);
+ TestParserSyncWithFlags(source);
}
}
}
diff --git a/test/cctest/test-platform-linux.cc b/test/cctest/test-platform-linux.cc
index 756b9473..2a8d4978 100644
--- a/test/cctest/test-platform-linux.cc
+++ b/test/cctest/test-platform-linux.cc
@@ -67,7 +67,7 @@ TEST(BusyLock) {
TEST(VirtualMemory) {
- OS::Setup();
+ OS::SetUp();
VirtualMemory* vm = new VirtualMemory(1 * MB);
CHECK(vm->IsReserved());
void* block_addr = vm->address();
diff --git a/test/cctest/test-platform-win32.cc b/test/cctest/test-platform-win32.cc
index 9bd0014c..36b30aac 100644
--- a/test/cctest/test-platform-win32.cc
+++ b/test/cctest/test-platform-win32.cc
@@ -13,7 +13,7 @@ using namespace ::v8::internal;
TEST(VirtualMemory) {
- OS::Setup();
+ OS::SetUp();
VirtualMemory* vm = new VirtualMemory(1 * MB);
CHECK(vm->IsReserved());
void* block_addr = vm->address();
diff --git a/test/cctest/test-profile-generator.cc b/test/cctest/test-profile-generator.cc
index 76fd244e..def829c2 100644
--- a/test/cctest/test-profile-generator.cc
+++ b/test/cctest/test-profile-generator.cc
@@ -52,7 +52,7 @@ TEST(TokenEnumerator) {
CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
}
CHECK(!i::TokenEnumeratorTester::token_removed(&te)->at(2));
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK(i::TokenEnumeratorTester::token_removed(&te)->at(2));
CHECK_EQ(1, te.GetTokenId(*v8::Utils::OpenHandle(*token2)));
CHECK_EQ(0, te.GetTokenId(*v8::Utils::OpenHandle(*token1)));
diff --git a/test/cctest/test-random.cc b/test/cctest/test-random.cc
new file mode 100644
index 00000000..a1f49318
--- /dev/null
+++ b/test/cctest/test-random.cc
@@ -0,0 +1,109 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+#include "v8.h"
+
+#include "cctest.h"
+#include "compiler.h"
+#include "execution.h"
+#include "isolate.h"
+
+
+using namespace v8::internal;
+
+static v8::Persistent<v8::Context> env;
+
+
+void SetSeeds(Handle<ByteArray> seeds, uint32_t state0, uint32_t state1) {
+ for (int i = 0; i < 4; i++) {
+ seeds->set(i, static_cast<byte>(state0 >> (i * kBitsPerByte)));
+ seeds->set(i + 4, static_cast<byte>(state1 >> (i * kBitsPerByte)));
+ }
+}
+
+
+void TestSeeds(Handle<JSFunction> fun,
+ Handle<Context> context,
+ uint32_t state0,
+ uint32_t state1) {
+ bool has_pending_exception;
+ Handle<JSObject> global(context->global());
+ Handle<ByteArray> seeds(context->random_seed());
+
+ SetSeeds(seeds, state0, state1);
+ Handle<Object> value =
+ Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ CHECK(value->IsHeapNumber());
+ CHECK(fun->IsOptimized());
+ double crankshaft_value = HeapNumber::cast(*value)->value();
+
+ SetSeeds(seeds, state0, state1);
+ V8::FillHeapNumberWithRandom(*value, *context);
+ double runtime_value = HeapNumber::cast(*value)->value();
+ CHECK_EQ(runtime_value, crankshaft_value);
+}
+
+
+TEST(CrankshaftRandom) {
+ if (env.IsEmpty()) env = v8::Context::New();
+ // Skip test if crankshaft is disabled.
+ if (!V8::UseCrankshaft()) return;
+ v8::HandleScope scope;
+ env->Enter();
+
+ Handle<Context> context(Isolate::Current()->context());
+ Handle<JSObject> global(context->global());
+ Handle<ByteArray> seeds(context->random_seed());
+ bool has_pending_exception;
+
+ CompileRun("function f() { return Math.random(); }");
+
+ Object* symbol = FACTORY->LookupAsciiSymbol("f")->ToObjectChecked();
+ MaybeObject* fun_object =
+ context->global()->GetProperty(String::cast(symbol));
+ Handle<JSFunction> fun(JSFunction::cast(fun_object->ToObjectChecked()));
+
+ // Optimize function.
+ Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ if (!fun->IsOptimized()) fun->MarkForLazyRecompilation();
+
+ // Test with some random values.
+ TestSeeds(fun, context, 0xC0C0AFFE, 0x31415926);
+ TestSeeds(fun, context, 0x01020304, 0xFFFFFFFF);
+ TestSeeds(fun, context, 0x00000001, 0x00000000);
+
+ // Test that we bail out to runtime when seeds are uninitialized (zeros).
+ SetSeeds(seeds, 0, 0);
+ Handle<Object> value =
+ Execution::Call(fun, global, 0, NULL, &has_pending_exception);
+ CHECK(value->IsHeapNumber());
+ CHECK(fun->IsOptimized());
+ double crankshaft_value = HeapNumber::cast(*value)->value();
+ CHECK_NE(0.0, crankshaft_value);
+}
diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index 89a91127..d941d0f7 100644
--- a/test/cctest/test-regexp.cc
+++ b/test/cctest/test-regexp.cc
@@ -449,6 +449,7 @@ static bool IsWhiteSpace(uc16 c) {
case 0xA0:
case 0x2028:
case 0x2029:
+ case 0xFEFF:
return true;
default:
return unibrow::Space::Is(c);
@@ -530,7 +531,7 @@ class TestConfig {
typedef int Key;
typedef int Value;
static const int kNoKey;
- static const int kNoValue;
+ static int NoValue() { return 0; }
static inline int Compare(int a, int b) {
if (a < b)
return -1;
@@ -543,7 +544,6 @@ class TestConfig {
const int TestConfig::kNoKey = 0;
-const int TestConfig::kNoValue = 0;
static unsigned PseudoRandom(int i, int j) {
@@ -837,7 +837,8 @@ TEST(MacroAssemblerNativeSimpleUC16) {
Handle<Code> code = Handle<Code>::cast(code_object);
int captures[4] = {42, 37, 87, 117};
- const uc16 input_data[6] = {'f', 'o', 'o', 'f', 'o', '\xa0'};
+ const uc16 input_data[6] = {'f', 'o', 'o', 'f', 'o',
+ static_cast<uc16>('\xa0')};
Handle<String> input =
factory->NewStringFromTwoByte(Vector<const uc16>(input_data, 6));
Handle<SeqTwoByteString> seq_input = Handle<SeqTwoByteString>::cast(input);
@@ -857,7 +858,8 @@ TEST(MacroAssemblerNativeSimpleUC16) {
CHECK_EQ(-1, captures[2]);
CHECK_EQ(-1, captures[3]);
- const uc16 input_data2[9] = {'b', 'a', 'r', 'b', 'a', 'r', 'b', 'a', '\xa0'};
+ const uc16 input_data2[9] = {'b', 'a', 'r', 'b', 'a', 'r', 'b', 'a',
+ static_cast<uc16>('\xa0')};
input = factory->NewStringFromTwoByte(Vector<const uc16>(input_data2, 9));
seq_input = Handle<SeqTwoByteString>::cast(input);
start_adr = seq_input->GetCharsAddress();
diff --git a/test/cctest/test-reloc-info.cc b/test/cctest/test-reloc-info.cc
index 5bdc4c3e..e638201d 100644
--- a/test/cctest/test-reloc-info.cc
+++ b/test/cctest/test-reloc-info.cc
@@ -34,7 +34,7 @@ namespace internal {
static void WriteRinfo(RelocInfoWriter* writer,
byte* pc, RelocInfo::Mode mode, intptr_t data) {
- RelocInfo rinfo(pc, mode, data);
+ RelocInfo rinfo(pc, mode, data, NULL);
writer->Write(&rinfo);
}
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index 8e85444e..e426e7bd 100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -114,10 +114,6 @@ TEST(ExternalReferenceEncoder) {
ExternalReference(isolate->counters()->keyed_load_function_prototype());
CHECK_EQ(make_code(STATS_COUNTER, Counters::k_keyed_load_function_prototype),
encoder.Encode(keyed_load_function_prototype.address()));
- ExternalReference the_hole_value_location =
- ExternalReference::the_hole_value_location(isolate);
- CHECK_EQ(make_code(UNCLASSIFIED, 2),
- encoder.Encode(the_hole_value_location.address()));
ExternalReference stack_limit_address =
ExternalReference::address_of_stack_limit(isolate);
CHECK_EQ(make_code(UNCLASSIFIED, 4),
@@ -127,14 +123,15 @@ TEST(ExternalReferenceEncoder) {
CHECK_EQ(make_code(UNCLASSIFIED, 5),
encoder.Encode(real_stack_limit_address.address()));
#ifdef ENABLE_DEBUGGER_SUPPORT
- CHECK_EQ(make_code(UNCLASSIFIED, 15),
+ CHECK_EQ(make_code(UNCLASSIFIED, 16),
encoder.Encode(ExternalReference::debug_break(isolate).address()));
#endif // ENABLE_DEBUGGER_SUPPORT
CHECK_EQ(make_code(UNCLASSIFIED, 10),
encoder.Encode(
ExternalReference::new_space_start(isolate).address()));
CHECK_EQ(make_code(UNCLASSIFIED, 3),
- encoder.Encode(ExternalReference::roots_address(isolate).address()));
+ encoder.Encode(
+ ExternalReference::roots_array_start(isolate).address()));
}
@@ -157,15 +154,13 @@ TEST(ExternalReferenceDecoder) {
decoder.Decode(
make_code(STATS_COUNTER,
Counters::k_keyed_load_function_prototype)));
- CHECK_EQ(ExternalReference::the_hole_value_location(isolate).address(),
- decoder.Decode(make_code(UNCLASSIFIED, 2)));
CHECK_EQ(ExternalReference::address_of_stack_limit(isolate).address(),
decoder.Decode(make_code(UNCLASSIFIED, 4)));
CHECK_EQ(ExternalReference::address_of_real_stack_limit(isolate).address(),
decoder.Decode(make_code(UNCLASSIFIED, 5)));
#ifdef ENABLE_DEBUGGER_SUPPORT
CHECK_EQ(ExternalReference::debug_break(isolate).address(),
- decoder.Decode(make_code(UNCLASSIFIED, 15)));
+ decoder.Decode(make_code(UNCLASSIFIED, 16)));
#endif // ENABLE_DEBUGGER_SUPPORT
CHECK_EQ(ExternalReference::new_space_start(isolate).address(),
decoder.Decode(make_code(UNCLASSIFIED, 10)));
@@ -365,8 +360,8 @@ TEST(PartialSerialization) {
Isolate::Current()->bootstrapper()->NativesSourceLookup(i);
}
}
- HEAP->CollectAllGarbage(true);
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
Object* raw_foo;
{
@@ -490,7 +485,7 @@ TEST(ContextSerialization) {
}
// If we don't do this then we end up with a stray root pointing at the
// context even after we have disposed of env.
- HEAP->CollectAllGarbage(true);
+ HEAP->CollectAllGarbage(Heap::kNoGCFlags);
int file_name_length = StrLength(FLAG_testing_serialization_file) + 10;
Vector<char> startup_name = Vector<char>::New(file_name_length + 1);
@@ -563,16 +558,20 @@ DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
TEST(LinearAllocation) {
v8::V8::Initialize();
int new_space_max = 512 * KB;
+ int paged_space_max = Page::kMaxNonCodeHeapObjectSize;
+ int code_space_max = HEAP->code_space()->AreaSize();
for (int size = 1000; size < 5 * MB; size += size >> 1) {
+ size &= ~8; // Round.
int new_space_size = (size < new_space_max) ? size : new_space_max;
+ int paged_space_size = (size < paged_space_max) ? size : paged_space_max;
HEAP->ReserveSpace(
new_space_size,
- size, // Old pointer space.
- size, // Old data space.
- size, // Code space.
- size, // Map space.
- size, // Cell space.
+ paged_space_size, // Old pointer space.
+ paged_space_size, // Old data space.
+ HEAP->code_space()->RoundSizeDownToObjectAlignment(code_space_max),
+ HEAP->map_space()->RoundSizeDownToObjectAlignment(paged_space_size),
+ HEAP->cell_space()->RoundSizeDownToObjectAlignment(paged_space_size),
size); // Large object space.
LinearAllocationScope linear_allocation_scope;
const int kSmallFixedArrayLength = 4;
@@ -599,14 +598,14 @@ TEST(LinearAllocation) {
Object* pointer_last = NULL;
for (int i = 0;
- i + kSmallFixedArraySize <= size;
+ i + kSmallFixedArraySize <= paged_space_size;
i += kSmallFixedArraySize) {
Object* obj = HEAP->AllocateFixedArray(kSmallFixedArrayLength,
TENURED)->ToObjectChecked();
int old_page_fullness = i % Page::kPageSize;
int page_fullness = (i + kSmallFixedArraySize) % Page::kPageSize;
if (page_fullness < old_page_fullness ||
- page_fullness > Page::kObjectAreaSize) {
+ page_fullness > HEAP->old_pointer_space()->AreaSize()) {
i = RoundUp(i, Page::kPageSize);
pointer_last = NULL;
}
@@ -618,13 +617,15 @@ TEST(LinearAllocation) {
}
Object* data_last = NULL;
- for (int i = 0; i + kSmallStringSize <= size; i += kSmallStringSize) {
+ for (int i = 0;
+ i + kSmallStringSize <= paged_space_size;
+ i += kSmallStringSize) {
Object* obj = HEAP->AllocateRawAsciiString(kSmallStringLength,
TENURED)->ToObjectChecked();
int old_page_fullness = i % Page::kPageSize;
int page_fullness = (i + kSmallStringSize) % Page::kPageSize;
if (page_fullness < old_page_fullness ||
- page_fullness > Page::kObjectAreaSize) {
+ page_fullness > HEAP->old_data_space()->AreaSize()) {
i = RoundUp(i, Page::kPageSize);
data_last = NULL;
}
@@ -636,13 +637,13 @@ TEST(LinearAllocation) {
}
Object* map_last = NULL;
- for (int i = 0; i + kMapSize <= size; i += kMapSize) {
+ for (int i = 0; i + kMapSize <= paged_space_size; i += kMapSize) {
Object* obj = HEAP->AllocateMap(JS_OBJECT_TYPE,
42 * kPointerSize)->ToObjectChecked();
int old_page_fullness = i % Page::kPageSize;
int page_fullness = (i + kMapSize) % Page::kPageSize;
if (page_fullness < old_page_fullness ||
- page_fullness > Page::kObjectAreaSize) {
+ page_fullness > HEAP->map_space()->AreaSize()) {
i = RoundUp(i, Page::kPageSize);
map_last = NULL;
}
@@ -653,7 +654,7 @@ TEST(LinearAllocation) {
map_last = obj;
}
- if (size > Page::kObjectAreaSize) {
+ if (size > Page::kMaxNonCodeHeapObjectSize) {
// Support for reserving space in large object space is not there yet,
// but using an always-allocate scope is fine for now.
AlwaysAllocateScope always;
diff --git a/test/cctest/test-sockets.cc b/test/cctest/test-sockets.cc
index 4af55dbe..ad735400 100644
--- a/test/cctest/test-sockets.cc
+++ b/test/cctest/test-sockets.cc
@@ -129,7 +129,7 @@ TEST(Socket) {
bool ok;
// Initialize socket support.
- ok = Socket::Setup();
+ ok = Socket::SetUp();
CHECK(ok);
// Send and receive some data.
diff --git a/test/cctest/test-spaces.cc b/test/cctest/test-spaces.cc
index 0f22ce1a..92de2a60 100644
--- a/test/cctest/test-spaces.cc
+++ b/test/cctest/test-spaces.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// 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:
@@ -32,7 +32,9 @@
using namespace v8::internal;
+#if 0
static void VerifyRegionMarking(Address page_start) {
+#ifdef ENABLE_CARDMARKING_WRITE_BARRIER
Page* p = Page::FromAddress(page_start);
p->SetRegionMarks(Page::kAllRegionsCleanMarks);
@@ -54,9 +56,13 @@ static void VerifyRegionMarking(Address page_start) {
addr += kPointerSize) {
CHECK(Page::FromAddress(addr)->IsRegionDirty(addr));
}
+#endif
}
+#endif
+// TODO(gc) you can no longer allocate pages like this. Details are hidden.
+#if 0
TEST(Page) {
byte* mem = NewArray<byte>(2*Page::kPageSize);
CHECK(mem != NULL);
@@ -89,6 +95,7 @@ TEST(Page) {
DeleteArray(mem);
}
+#endif
namespace v8 {
@@ -118,95 +125,76 @@ class TestMemoryAllocatorScope {
TEST(MemoryAllocator) {
- OS::Setup();
+ OS::SetUp();
Isolate* isolate = Isolate::Current();
isolate->InitializeLoggingAndCounters();
Heap* heap = isolate->heap();
- CHECK(heap->ConfigureHeapDefault());
+ CHECK(isolate->heap()->ConfigureHeapDefault());
+
MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
- CHECK(memory_allocator->Setup(heap->MaxReserved(),
+ CHECK(memory_allocator->SetUp(heap->MaxReserved(),
heap->MaxExecutableSize()));
- TestMemoryAllocatorScope test_scope(isolate, memory_allocator);
+ int total_pages = 0;
OldSpace faked_space(heap,
heap->MaxReserved(),
OLD_POINTER_SPACE,
NOT_EXECUTABLE);
- int total_pages = 0;
- int requested = MemoryAllocator::kPagesPerChunk;
- int allocated;
- // If we request n pages, we should get n or n - 1.
- Page* first_page = memory_allocator->AllocatePages(
- requested, &allocated, &faked_space);
+ Page* first_page =
+ memory_allocator->AllocatePage(&faked_space, NOT_EXECUTABLE);
+
+ first_page->InsertAfter(faked_space.anchor()->prev_page());
CHECK(first_page->is_valid());
- CHECK(allocated == requested || allocated == requested - 1);
- total_pages += allocated;
+ CHECK(first_page->next_page() == faked_space.anchor());
+ total_pages++;
- Page* last_page = first_page;
- for (Page* p = first_page; p->is_valid(); p = p->next_page()) {
- CHECK(memory_allocator->IsPageInSpace(p, &faked_space));
- last_page = p;
+ for (Page* p = first_page; p != faked_space.anchor(); p = p->next_page()) {
+ CHECK(p->owner() == &faked_space);
}
// Again, we should get n or n - 1 pages.
- Page* others = memory_allocator->AllocatePages(
- requested, &allocated, &faked_space);
- CHECK(others->is_valid());
- CHECK(allocated == requested || allocated == requested - 1);
- total_pages += allocated;
-
- memory_allocator->SetNextPage(last_page, others);
+ Page* other =
+ memory_allocator->AllocatePage(&faked_space, NOT_EXECUTABLE);
+ CHECK(other->is_valid());
+ total_pages++;
+ other->InsertAfter(first_page);
int page_count = 0;
- for (Page* p = first_page; p->is_valid(); p = p->next_page()) {
- CHECK(memory_allocator->IsPageInSpace(p, &faked_space));
+ for (Page* p = first_page; p != faked_space.anchor(); p = p->next_page()) {
+ CHECK(p->owner() == &faked_space);
page_count++;
}
CHECK(total_pages == page_count);
Page* second_page = first_page->next_page();
CHECK(second_page->is_valid());
-
- // Freeing pages at the first chunk starting at or after the second page
- // should free the entire second chunk. It will return the page it was passed
- // (since the second page was in the first chunk).
- Page* free_return = memory_allocator->FreePages(second_page);
- CHECK(free_return == second_page);
- memory_allocator->SetNextPage(first_page, free_return);
-
- // Freeing pages in the first chunk starting at the first page should free
- // the first chunk and return an invalid page.
- Page* invalid_page = memory_allocator->FreePages(first_page);
- CHECK(!invalid_page->is_valid());
-
+ memory_allocator->Free(first_page);
+ memory_allocator->Free(second_page);
memory_allocator->TearDown();
delete memory_allocator;
}
TEST(NewSpace) {
- OS::Setup();
+ OS::SetUp();
Isolate* isolate = Isolate::Current();
isolate->InitializeLoggingAndCounters();
Heap* heap = isolate->heap();
CHECK(heap->ConfigureHeapDefault());
MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
- CHECK(memory_allocator->Setup(heap->MaxReserved(),
+ CHECK(memory_allocator->SetUp(heap->MaxReserved(),
heap->MaxExecutableSize()));
TestMemoryAllocatorScope test_scope(isolate, memory_allocator);
NewSpace new_space(heap);
- void* chunk =
- memory_allocator->ReserveInitialChunk(4 * heap->ReservedSemiSpaceSize());
- CHECK(chunk != NULL);
- Address start = RoundUp(static_cast<Address>(chunk),
- 2 * heap->ReservedSemiSpaceSize());
- CHECK(new_space.Setup(start, 2 * heap->ReservedSemiSpaceSize()));
- CHECK(new_space.HasBeenSetup());
+ CHECK(new_space.SetUp(HEAP->ReservedSemiSpaceSize(),
+ HEAP->ReservedSemiSpaceSize()));
+ CHECK(new_space.HasBeenSetUp());
- while (new_space.Available() >= Page::kMaxHeapObjectSize) {
+ while (new_space.Available() >= Page::kMaxNonCodeHeapObjectSize) {
Object* obj =
- new_space.AllocateRaw(Page::kMaxHeapObjectSize)->ToObjectUnchecked();
+ new_space.AllocateRaw(Page::kMaxNonCodeHeapObjectSize)->
+ ToObjectUnchecked();
CHECK(new_space.Contains(HeapObject::cast(obj)));
}
@@ -217,13 +205,13 @@ TEST(NewSpace) {
TEST(OldSpace) {
- OS::Setup();
+ OS::SetUp();
Isolate* isolate = Isolate::Current();
isolate->InitializeLoggingAndCounters();
Heap* heap = isolate->heap();
CHECK(heap->ConfigureHeapDefault());
MemoryAllocator* memory_allocator = new MemoryAllocator(isolate);
- CHECK(memory_allocator->Setup(heap->MaxReserved(),
+ CHECK(memory_allocator->SetUp(heap->MaxReserved(),
heap->MaxExecutableSize()));
TestMemoryAllocatorScope test_scope(isolate, memory_allocator);
@@ -233,16 +221,10 @@ TEST(OldSpace) {
NOT_EXECUTABLE);
CHECK(s != NULL);
- void* chunk = memory_allocator->ReserveInitialChunk(
- 4 * heap->ReservedSemiSpaceSize());
- CHECK(chunk != NULL);
- Address start = static_cast<Address>(chunk);
- size_t size = RoundUp(start, 2 * heap->ReservedSemiSpaceSize()) - start;
-
- CHECK(s->Setup(start, size));
+ CHECK(s->SetUp());
while (s->Available() > 0) {
- s->AllocateRaw(Page::kMaxHeapObjectSize)->ToObjectUnchecked();
+ s->AllocateRaw(Page::kMaxNonCodeHeapObjectSize)->ToObjectUnchecked();
}
s->TearDown();
@@ -258,14 +240,12 @@ TEST(LargeObjectSpace) {
LargeObjectSpace* lo = HEAP->lo_space();
CHECK(lo != NULL);
- Map* faked_map = reinterpret_cast<Map*>(HeapObject::FromAddress(0));
int lo_size = Page::kPageSize;
- Object* obj = lo->AllocateRaw(lo_size)->ToObjectUnchecked();
+ Object* obj = lo->AllocateRaw(lo_size, NOT_EXECUTABLE)->ToObjectUnchecked();
CHECK(obj->IsHeapObject());
HeapObject* ho = HeapObject::cast(obj);
- ho->set_map(faked_map);
CHECK(lo->Contains(HeapObject::cast(obj)));
@@ -275,14 +255,13 @@ TEST(LargeObjectSpace) {
while (true) {
intptr_t available = lo->Available();
- { MaybeObject* maybe_obj = lo->AllocateRaw(lo_size);
+ { MaybeObject* maybe_obj = lo->AllocateRaw(lo_size, NOT_EXECUTABLE);
if (!maybe_obj->ToObject(&obj)) break;
}
- HeapObject::cast(obj)->set_map(faked_map);
CHECK(lo->Available() < available);
};
CHECK(!lo->IsEmpty());
- CHECK(lo->AllocateRaw(lo_size)->IsFailure());
+ CHECK(lo->AllocateRaw(lo_size, NOT_EXECUTABLE)->IsFailure());
}
diff --git a/test/cctest/test-strings.cc b/test/cctest/test-strings.cc
index 55c21417..e11349bc 100644
--- a/test/cctest/test-strings.cc
+++ b/test/cctest/test-strings.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Check that we can traverse very deep stacks of ConsStrings using
// StringInputBuffer. Check that Get(int) works on very deep stacks
@@ -355,7 +355,7 @@ TEST(ExternalShortStringAdd) {
// Make sure we cover all always-flat lengths and at least one above.
static const int kMaxLength = 20;
- CHECK_GT(kMaxLength, i::String::kMinNonFlatLength);
+ CHECK_GT(kMaxLength, i::ConsString::kMinLength);
// Allocate two JavaScript arrays for holding short strings.
v8::Handle<v8::Array> ascii_external_strings =
@@ -502,6 +502,35 @@ TEST(SliceFromCons) {
}
+class AsciiVectorResource : public v8::String::ExternalAsciiStringResource {
+ public:
+ explicit AsciiVectorResource(i::Vector<const char> vector)
+ : data_(vector) {}
+ virtual ~AsciiVectorResource() {}
+ virtual size_t length() const { return data_.length(); }
+ virtual const char* data() const { return data_.start(); }
+ private:
+ i::Vector<const char> data_;
+};
+
+
+TEST(SliceFromExternal) {
+ FLAG_string_slices = true;
+ InitializeVM();
+ v8::HandleScope scope;
+ AsciiVectorResource resource(
+ i::Vector<const char>("abcdefghijklmnopqrstuvwxyz", 26));
+ Handle<String> string = FACTORY->NewExternalStringFromAscii(&resource);
+ CHECK(string->IsExternalString());
+ Handle<String> slice = FACTORY->NewSubString(string, 1, 25);
+ CHECK(slice->IsSlicedString());
+ CHECK(string->IsExternalString());
+ CHECK_EQ(SlicedString::cast(*slice)->parent(), *string);
+ CHECK(SlicedString::cast(*slice)->parent()->IsExternalString());
+ CHECK(slice->IsFlat());
+}
+
+
TEST(TrivialSlice) {
// This tests whether a slice that contains the entire parent string
// actually creates a new string (it should not).
diff --git a/test/cctest/test-threads.cc b/test/cctest/test-threads.cc
index 985b9e5b..713d1e84 100644
--- a/test/cctest/test-threads.cc
+++ b/test/cctest/test-threads.cc
@@ -63,7 +63,7 @@ enum Turn {
static Turn turn = FILL_CACHE;
-class ThreadA: public v8::internal::Thread {
+class ThreadA : public v8::internal::Thread {
public:
ThreadA() : Thread("ThreadA") { }
void Run() {
@@ -99,7 +99,7 @@ class ThreadA: public v8::internal::Thread {
};
-class ThreadB: public v8::internal::Thread {
+class ThreadB : public v8::internal::Thread {
public:
ThreadB() : Thread("ThreadB") { }
void Run() {
@@ -111,7 +111,7 @@ class ThreadB: public v8::internal::Thread {
v8::Context::Scope context_scope(v8::Context::New());
// Clear the caches by forcing major GC.
- HEAP->CollectAllGarbage(false);
+ HEAP->CollectAllGarbage(v8::internal::Heap::kNoGCFlags);
turn = SECOND_TIME_FILL_CACHE;
break;
}
@@ -190,3 +190,19 @@ TEST(ThreadIdValidation) {
delete threads[i];
}
}
+
+
+class ThreadC : public v8::internal::Thread {
+ public:
+ ThreadC() : Thread("ThreadC") { }
+ void Run() {
+ Join();
+ }
+};
+
+
+TEST(ThreadJoinSelf) {
+ ThreadC thread;
+ thread.Start();
+ thread.Join();
+}
diff --git a/test/cctest/test-utils.cc b/test/cctest/test-utils.cc
index e4f70df4..df8ff72e 100644
--- a/test/cctest/test-utils.cc
+++ b/test/cctest/test-utils.cc
@@ -105,7 +105,7 @@ void TestMemCopy(Vector<byte> src,
TEST(MemCopy) {
v8::V8::Initialize();
- OS::Setup();
+ OS::SetUp();
const int N = OS::kMinComplexMemCopy + 128;
Vector<byte> buffer1 = Vector<byte>::New(N);
Vector<byte> buffer2 = Vector<byte>::New(N);
diff --git a/test/cctest/test-weakmaps.cc b/test/cctest/test-weakmaps.cc
index db4db254..56d59362 100644
--- a/test/cctest/test-weakmaps.cc
+++ b/test/cctest/test-weakmaps.cc
@@ -50,7 +50,7 @@ static void PutIntoWeakMap(Handle<JSWeakMap> weakmap,
Handle<JSObject> key,
int value) {
Handle<ObjectHashTable> table = PutIntoObjectHashTable(
- Handle<ObjectHashTable>(weakmap->table()),
+ Handle<ObjectHashTable>(ObjectHashTable::cast(weakmap->table())),
Handle<JSObject>(JSObject::cast(*key)),
Handle<Smi>(Smi::FromInt(value)));
weakmap->set_table(*table);
@@ -85,13 +85,14 @@ TEST(Weakness) {
v8::HandleScope scope;
PutIntoWeakMap(weakmap, Handle<JSObject>(JSObject::cast(*key)), 23);
}
- CHECK_EQ(1, weakmap->table()->NumberOfElements());
+ CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
// Force a full GC.
HEAP->CollectAllGarbage(false);
CHECK_EQ(0, NumberOfWeakCalls);
- CHECK_EQ(1, weakmap->table()->NumberOfElements());
- CHECK_EQ(0, weakmap->table()->NumberOfDeletedElements());
+ CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
+ CHECK_EQ(
+ 0, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements());
// Make the global reference to the key weak.
{
@@ -107,12 +108,14 @@ TEST(Weakness) {
// weak references whereas the second one will also clear weak maps.
HEAP->CollectAllGarbage(false);
CHECK_EQ(1, NumberOfWeakCalls);
- CHECK_EQ(1, weakmap->table()->NumberOfElements());
- CHECK_EQ(0, weakmap->table()->NumberOfDeletedElements());
+ CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
+ CHECK_EQ(
+ 0, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements());
HEAP->CollectAllGarbage(false);
CHECK_EQ(1, NumberOfWeakCalls);
- CHECK_EQ(0, weakmap->table()->NumberOfElements());
- CHECK_EQ(1, weakmap->table()->NumberOfDeletedElements());
+ CHECK_EQ(0, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
+ CHECK_EQ(
+ 1, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements());
}
@@ -122,7 +125,7 @@ TEST(Shrinking) {
Handle<JSWeakMap> weakmap = AllocateJSWeakMap();
// Check initial capacity.
- CHECK_EQ(32, weakmap->table()->Capacity());
+ CHECK_EQ(32, ObjectHashTable::cast(weakmap->table())->Capacity());
// Fill up weak map to trigger capacity change.
{
@@ -135,15 +138,17 @@ TEST(Shrinking) {
}
// Check increased capacity.
- CHECK_EQ(128, weakmap->table()->Capacity());
+ CHECK_EQ(128, ObjectHashTable::cast(weakmap->table())->Capacity());
// Force a full GC.
- CHECK_EQ(32, weakmap->table()->NumberOfElements());
- CHECK_EQ(0, weakmap->table()->NumberOfDeletedElements());
+ CHECK_EQ(32, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
+ CHECK_EQ(
+ 0, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements());
HEAP->CollectAllGarbage(false);
- CHECK_EQ(0, weakmap->table()->NumberOfElements());
- CHECK_EQ(32, weakmap->table()->NumberOfDeletedElements());
+ CHECK_EQ(0, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
+ CHECK_EQ(
+ 32, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements());
// Check shrunk capacity.
- CHECK_EQ(32, weakmap->table()->Capacity());
+ CHECK_EQ(32, ObjectHashTable::cast(weakmap->table())->Capacity());
}
diff --git a/test/es5conform/es5conform.status b/test/es5conform/es5conform.status
index d095a247..12ebf903 100644
--- a/test/es5conform/es5conform.status
+++ b/test/es5conform/es5conform.status
@@ -41,16 +41,6 @@ chapter10/10.4/10.4.2/10.4.2-2-c-1: FAIL_OK
# We are compatible with Safari and Firefox.
chapter11/11.1/11.1.5: UNIMPLEMENTED
-# We do not have a global object called 'global' as required by tests.
-chapter15/15.1: FAIL_OK
-
-# NaN is writable. We are compatible with JSC.
-chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-178: FAIL_OK
-# Infinity is writable. We are compatible with JSC.
-chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-179: FAIL_OK
-# undefined is writable. We are compatible with JSC.
-chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-180: FAIL_OK
-
# Our Function object has an "arguments" property which is used as a
# non-property in the test.
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-183: FAIL_OK
@@ -106,9 +96,6 @@ chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-7: FAIL_OK
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-11: FAIL_OK
-# We do not implement all methods on RegExp.
-chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-13: FAIL
-
# SUBSETFAIL
chapter15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-14: FAIL_OK
@@ -196,27 +183,6 @@ chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-c-ii-4-s: SKIP
# have no effect on the actual array on which reduceRight is called.
chapter15/15.4/15.4.4/15.4.4.22/15.4.4.22-9-7: FAIL_OK
-# We do not correctly recognize \uFEFF as whitespace
-chapter15/15.5/15.5.4/15.5.4.20/15.5.4.20-4-10: FAIL
-chapter15/15.5/15.5.4/15.5.4.20/15.5.4.20-4-18: FAIL
-chapter15/15.5/15.5.4/15.5.4.20/15.5.4.20-4-34: FAIL
-
-# RegExp.prototype is not of type RegExp - we are bug compatible with JSC.
-chapter15/15.10/15.10.6/15.10.6: FAIL_OK
-
-# We do not have the properties of a RegExp instance on RegExp.prototype.
-# The spec says we should - but we are currently bug compatible with JSC.
-chapter15/15.10/15.10.7/15.10.7.1/15.10.7.1-1: FAIL_OK
-chapter15/15.10/15.10.7/15.10.7.1/15.10.7.1-2: FAIL_OK
-chapter15/15.10/15.10.7/15.10.7.2/15.10.7.2-1: FAIL_OK
-chapter15/15.10/15.10.7/15.10.7.2/15.10.7.2-2: FAIL_OK
-chapter15/15.10/15.10.7/15.10.7.3/15.10.7.3-1: FAIL_OK
-chapter15/15.10/15.10.7/15.10.7.3/15.10.7.3-2: FAIL_OK
-chapter15/15.10/15.10.7/15.10.7.4/15.10.7.4-1: FAIL_OK
-chapter15/15.10/15.10.7/15.10.7.4/15.10.7.4-2: FAIL_OK
-chapter15/15.10/15.10.7/15.10.7.5/15.10.7.5-1: FAIL_OK
-chapter15/15.10/15.10.7/15.10.7.5/15.10.7.5-2: FAIL_OK
-
##############################################################################
# Unimplemented parts of strict mode
# Setting expectations to fail only so that the tests trigger as soon as
@@ -348,8 +314,3 @@ chapter15/15.3/15.3.2/15.3.2.1/15.3.2.1-11-6-s: FAIL
# Array.prototype.reduce - null passed as thisValue to strict callbackfn
# Invalid test case: http://es5conform.codeplex.com/workitem/29085
chapter15/15.4/15.4.4/15.4.4.21/15.4.4.21-9-c-ii-4-s: FAIL
-
-[ $arch == mips ]
-
-# Skip all tests on MIPS.
-*: SKIP
diff --git a/test/message/message.status b/test/message/message.status
index 70354cee..fc2896b1 100644
--- a/test/message/message.status
+++ b/test/message/message.status
@@ -29,10 +29,3 @@ prefix message
# All tests in the bug directory are expected to fail.
bugs: FAIL
-
-
-##############################################################################
-[ $arch == mips ]
-
-# Skip all tests on MIPS.
-*: SKIP
diff --git a/test/mjsunit/apply.js b/test/mjsunit/apply.js
index c166110d..413ee937 100644
--- a/test/mjsunit/apply.js
+++ b/test/mjsunit/apply.js
@@ -190,3 +190,10 @@ assertEquals("morseper",
"moreseper-prime");
delete(Array.prototype["1"]);
+
+// Check correct handling of non-array argument lists.
+assertSame(this, f0.apply(this, {}), "non-array-1");
+assertSame(this, f0.apply(this, { length:1 }), "non-array-2");
+assertEquals(void 0, f1.apply(this, { length:1 }), "non-array-3");
+assertEquals(void 0, f1.apply(this, { 0:"foo" }), "non-array-4");
+assertEquals("foo", f1.apply(this, { length:1, 0:"foo" }), "non-array-5");
diff --git a/test/mjsunit/array-construct-transition.js b/test/mjsunit/array-construct-transition.js
new file mode 100644
index 00000000..577e321a
--- /dev/null
+++ b/test/mjsunit/array-construct-transition.js
@@ -0,0 +1,39 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --smi-only-arrays
+
+support_smi_only_arrays = %HasFastSmiOnlyElements(new Array(1,2,3,4,5,6,7,8));
+
+if (support_smi_only_arrays) {
+ var a = new Array(0, 1, 2);
+ assertTrue(%HasFastSmiOnlyElements(a));
+ var b = new Array(0.5, 1.2, 2.3);
+ assertTrue(%HasFastDoubleElements(b));
+ var c = new Array(0.5, 1.2, new Object());
+ assertTrue(%HasFastElements(c));
+}
diff --git a/test/mjsunit/array-join.js b/test/mjsunit/array-join.js
index 5c837a5c..c08c182f 100644
--- a/test/mjsunit/array-join.js
+++ b/test/mjsunit/array-join.js
@@ -75,10 +75,10 @@ if (Array.prototype.toString != oldToString) {
Array.prototype.toString = oldToString;
}
-var a = new Array(123123123);
-assertEquals(123123122, String(a).length);
-assertEquals(123123122, a.join(",").length);
-assertEquals(246246244, a.join("oo").length);
+var a = new Array(123123);
+assertEquals(123122, String(a).length);
+assertEquals(123122, a.join(",").length);
+assertEquals(246244, a.join("oo").length);
a = new Array(Math.pow(2,32) - 1); // Max length.
assertEquals("", a.join(""));
@@ -90,4 +90,4 @@ a = new Array(100001);
for (var i = 0; i < a.length; i++) a[i] = undefined;
a[5] = "ab";
a[90000] = "cd";
-assertEquals("abcd", a.join("")); // Must not throw. \ No newline at end of file
+assertEquals("abcd", a.join("")); // Must not throw.
diff --git a/test/mjsunit/array-literal-transitions.js b/test/mjsunit/array-literal-transitions.js
new file mode 100644
index 00000000..f657525e
--- /dev/null
+++ b/test/mjsunit/array-literal-transitions.js
@@ -0,0 +1,210 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+// Test element kind of objects.
+// Since --smi-only-arrays affects builtins, its default setting at compile
+// time sticks if built with snapshot. If --smi-only-arrays is deactivated
+// by default, only a no-snapshot build actually has smi-only arrays enabled
+// in this test case. Depending on whether smi-only arrays are actually
+// enabled, this test takes the appropriate code path to check smi-only arrays.
+
+support_smi_only_arrays = %HasFastSmiOnlyElements([1,2,3,4,5,6,7,8,9,10]);
+
+if (support_smi_only_arrays) {
+ print("Tests include smi-only arrays.");
+} else {
+ print("Tests do NOT include smi-only arrays.");
+}
+
+// IC and Crankshaft support for smi-only elements in dynamic array literals.
+function get(foo) { return foo; } // Used to generate dynamic values.
+
+function array_literal_test() {
+ var a0 = [1, 2, 3];
+ assertTrue(%HasFastSmiOnlyElements(a0));
+ var a1 = [get(1), get(2), get(3)];
+ assertTrue(%HasFastSmiOnlyElements(a1));
+
+ var b0 = [1, 2, get("three")];
+ assertTrue(%HasFastElements(b0));
+ var b1 = [get(1), get(2), get("three")];
+ assertTrue(%HasFastElements(b1));
+
+ var c0 = [1, 2, get(3.5)];
+ assertTrue(%HasFastDoubleElements(c0));
+ assertEquals(3.5, c0[2]);
+ assertEquals(2, c0[1]);
+ assertEquals(1, c0[0]);
+
+ var c1 = [1, 2, 3.5];
+ assertTrue(%HasFastDoubleElements(c1));
+ assertEquals(3.5, c1[2]);
+ assertEquals(2, c1[1]);
+ assertEquals(1, c1[0]);
+
+ var c2 = [get(1), get(2), get(3.5)];
+ assertTrue(%HasFastDoubleElements(c2));
+ assertEquals(3.5, c2[2]);
+ assertEquals(2, c2[1]);
+ assertEquals(1, c2[0]);
+
+ var object = new Object();
+ var d0 = [1, 2, object];
+ assertTrue(%HasFastElements(d0));
+ assertEquals(object, d0[2]);
+ assertEquals(2, d0[1]);
+ assertEquals(1, d0[0]);
+
+ var e0 = [1, 2, 3.5];
+ assertTrue(%HasFastDoubleElements(e0));
+ assertEquals(3.5, e0[2]);
+ assertEquals(2, e0[1]);
+ assertEquals(1, e0[0]);
+
+ var f0 = [1, 2, [1, 2]];
+ assertTrue(%HasFastElements(f0));
+ assertEquals([1,2], f0[2]);
+ assertEquals(2, f0[1]);
+ assertEquals(1, f0[0]);
+}
+
+if (support_smi_only_arrays) {
+ for (var i = 0; i < 3; i++) {
+ array_literal_test();
+ }
+ %OptimizeFunctionOnNextCall(array_literal_test);
+ array_literal_test();
+
+ function test_large_literal() {
+
+ function d() {
+ gc();
+ return 2.5;
+ }
+
+ function o() {
+ gc();
+ return new Object();
+ }
+
+ large =
+ [ 0, 1, 2, 3, 4, 5, d(), d(), d(), d(), d(), d(), o(), o(), o(), o() ];
+ assertFalse(%HasDictionaryElements(large));
+ assertFalse(%HasFastSmiOnlyElements(large));
+ assertFalse(%HasFastDoubleElements(large));
+ assertTrue(%HasFastElements(large));
+ assertEquals(large,
+ [0, 1, 2, 3, 4, 5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5,
+ new Object(), new Object(), new Object(), new Object()]);
+ }
+
+ for (var i = 0; i < 3; i++) {
+ test_large_literal();
+ }
+ %OptimizeFunctionOnNextCall(test_large_literal);
+ test_large_literal();
+
+ function deopt_array(use_literal) {
+ if (use_literal) {
+ return [.5, 3, 4];
+ } else {
+ return new Array();
+ }
+ }
+
+ deopt_array(false);
+ deopt_array(false);
+ deopt_array(false);
+ %OptimizeFunctionOnNextCall(deopt_array);
+ var array = deopt_array(false);
+ assertTrue(2 != %GetOptimizationStatus(deopt_array));
+ deopt_array(true);
+ assertTrue(2 != %GetOptimizationStatus(deopt_array));
+ array = deopt_array(false);
+ assertTrue(2 != %GetOptimizationStatus(deopt_array));
+
+ // Check that unexpected changes in the objects stored into the boilerplate
+ // also force a deopt.
+ function deopt_array_literal_all_smis(a) {
+ return [0, 1, a];
+ }
+
+ deopt_array_literal_all_smis(2);
+ deopt_array_literal_all_smis(3);
+ deopt_array_literal_all_smis(4);
+ array = deopt_array_literal_all_smis(4);
+ assertEquals(0, array[0]);
+ assertEquals(1, array[1]);
+ assertEquals(4, array[2]);
+ %OptimizeFunctionOnNextCall(deopt_array_literal_all_smis);
+ array = deopt_array_literal_all_smis(5);
+ array = deopt_array_literal_all_smis(6);
+ assertTrue(2 != %GetOptimizationStatus(deopt_array_literal_all_smis));
+ assertEquals(0, array[0]);
+ assertEquals(1, array[1]);
+ assertEquals(6, array[2]);
+
+ array = deopt_array_literal_all_smis(.5);
+ assertTrue(1 != %GetOptimizationStatus(deopt_array_literal_all_smis));
+ assertEquals(0, array[0]);
+ assertEquals(1, array[1]);
+ assertEquals(.5, array[2]);
+
+ function deopt_array_literal_all_doubles(a) {
+ return [0.5, 1, a];
+ }
+
+ deopt_array_literal_all_doubles(.5);
+ deopt_array_literal_all_doubles(.5);
+ deopt_array_literal_all_doubles(.5);
+ array = deopt_array_literal_all_doubles(0.5);
+ assertEquals(0.5, array[0]);
+ assertEquals(1, array[1]);
+ assertEquals(0.5, array[2]);
+ %OptimizeFunctionOnNextCall(deopt_array_literal_all_doubles);
+ array = deopt_array_literal_all_doubles(5);
+ array = deopt_array_literal_all_doubles(6);
+ assertTrue(2 != %GetOptimizationStatus(deopt_array_literal_all_doubles));
+ assertEquals(0.5, array[0]);
+ assertEquals(1, array[1]);
+ assertEquals(6, array[2]);
+
+ var foo = new Object();
+ array = deopt_array_literal_all_doubles(foo);
+ assertTrue(1 != %GetOptimizationStatus(deopt_array_literal_all_doubles));
+ assertEquals(0.5, array[0]);
+ assertEquals(1, array[1]);
+ assertEquals(foo, array[2]);
+}
+
+(function literals_after_osr() {
+ var color = [0];
+ // Trigger OSR.
+ while (%GetOptimizationStatus(literals_after_osr) == 2) {}
+ return [color[0]];
+})();
diff --git a/test/mjsunit/array-store-and-grow.js b/test/mjsunit/array-store-and-grow.js
new file mode 100644
index 00000000..131d4ebc
--- /dev/null
+++ b/test/mjsunit/array-store-and-grow.js
@@ -0,0 +1,183 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Verifies that the KeyedStoreIC correctly handles out-of-bounds stores
+// to an array that grow it by a single element. Test functions are
+// called twice to make sure that the IC is used, first call is handled
+// by the runtime in the miss stub.
+
+function array_store_1(a,b,c) {
+ return (a[b] = c);
+}
+
+// Check handling of the empty array.
+var a = [];
+array_store_1(a, 0, 1);
+a = [];
+array_store_1(a, 0, 1);
+assertEquals(1, a[0]);
+assertEquals(1, array_store_1([], 0, 1));
+
+a = [];
+for (x=0;x<100000;++x) {
+ assertEquals(x, array_store_1(a, x, x));
+}
+
+for (x=0;x<100000;++x) {
+ assertEquals(x, array_store_1([], 0, x));
+}
+
+function array_store_2(a,b,c) {
+ return (a[b] = c);
+}
+
+a = [];
+array_store_2(a, 0, 0.5);
+a = [];
+array_store_2(a, 0, 0.5);
+assertEquals(0.5, a[0]);
+assertEquals(0.5, array_store_2([], 0, 0.5));
+
+function array_store_3(a,b,c) {
+ return (a[b] = c);
+}
+
+x = new Object();
+a = [];
+array_store_3(a, 0, x);
+a = [];
+array_store_3(a, 0, x);
+assertEquals(x, a[0]);
+assertEquals(x, array_store_3([], 0, x));
+
+// Check the handling of COW arrays
+function makeCOW() {
+ return [1];
+}
+
+function array_store_4(a,b,c) {
+ return (a[b] = c);
+}
+
+a = makeCOW();
+array_store_4(a, 1, 1);
+a = makeCOW();
+array_store_4(a, 1, 1);
+assertEquals(1, a[1]);
+assertEquals(1, array_store_4([], 1, 1));
+
+function array_store_5(a,b,c) {
+ return (a[b] = c);
+}
+
+a = makeCOW();
+array_store_5(a, 1, 0.5);
+a = makeCOW();
+array_store_5(a, 1, 0.5);
+assertEquals(0.5, a[1]);
+assertEquals(0.5, array_store_5([], 1, 0.5));
+
+function array_store_6(a,b,c) {
+ return (a[b] = c);
+}
+
+a = makeCOW();
+array_store_6(a, 1, x);
+a = makeCOW();
+array_store_6(a, 1, x);
+assertEquals(x, a[1]);
+assertEquals(x, array_store_6([], 1, x));
+
+// Check the handling of mutable arrays.
+a = new Array(1,2,3);
+array_store_4(a, 3, 1);
+a = new Array(1,2,3);
+array_store_4(a, 3, 1);
+assertEquals(1, a[3]);
+assertEquals(1, array_store_4([], 3, 1));
+
+function array_store_5(a,b,c) {
+ return (a[b] = c);
+}
+
+a = new Array(1,2,3);
+array_store_5(a, 3, 0.5);
+a = new Array(1,2,3);
+array_store_5(a, 3, 0.5);
+assertEquals(0.5, a[3]);
+assertEquals(0.5, array_store_5([], 3, 0.5));
+
+function array_store_6(a,b,c) {
+ return (a[b] = c);
+}
+
+a = new Array(1,2,3);
+array_store_6(a, 3, x);
+a = new Array(1,2,3);
+array_store_6(a, 3, x);
+assertEquals(x, a[3]);
+assertEquals(x, array_store_6([], 3, x));
+
+function array_store_7(a,b,c) {
+ return (a[b] = c);
+}
+
+// Check the handling of mutable arrays of doubles
+var a = new Array(0.5, 1.5);
+array_store_7(a, 2, .5);
+a = new Array(0.5, 1.5);
+array_store_7(a, 2, .5);
+assertEquals(0.5, a[2]);
+a = new Array(0.5, 1.5);
+assertEquals(0.5, array_store_7(a, 2, 0.5));
+
+for (x=0;x<100000;++x) {
+ a = new Array(0.5, 1.5);
+ assertEquals(x, array_store_7(a, 2, x));
+}
+
+function array_store_8(a,b,c) {
+ return (a[b] = c);
+}
+
+var a = new Array(0.5, 1.5);
+array_store_8(a, 2, .5);
+a = new Array(0.5, 1.5);
+array_store_8(a, 10, .5);
+assertEquals(0.5, a[10]);
+
+// Grow the empty array with a double store.
+function array_store_9(a,b,c) {
+ return (a[b] = c);
+}
+
+var a = [];
+array_store_9(a, 0, 0.5);
+a = [];
+array_store_1(a, 0, 0.5);
+assertEquals(0.5, a[0]);
+assertEquals(0.5, array_store_1([], 0, 0.5));
diff --git a/test/mjsunit/array-tostring.js b/test/mjsunit/array-tostring.js
new file mode 100644
index 00000000..6708657e
--- /dev/null
+++ b/test/mjsunit/array-tostring.js
@@ -0,0 +1,159 @@
+// 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.
+
+// Array's toString should call the object's own join method, if one exists and
+// is callable. Otherwise, just use the original Object.toString function.
+
+var success = "[test success]";
+var expectedThis;
+function testJoin() {
+ assertEquals(0, arguments.length);
+ assertSame(expectedThis, this);
+ return success;
+}
+
+
+// On an Array object.
+
+// Default case.
+var a1 = [1, 2, 3];
+assertEquals(a1.join(), a1.toString());
+
+// Non-standard "join" function is called correctly.
+var a2 = [1, 2, 3];
+a2.join = testJoin;
+expectedThis = a2;
+assertEquals(success, a2.toString());
+
+// Non-callable join function is ignored and Object.prototype.toString is
+// used instead.
+var a3 = [1, 2, 3];
+a3.join = "not callable";
+assertEquals("[object Array]", a3.toString());
+
+// Non-existing join function is treated same as non-callable.
+var a4 = [1, 2, 3];
+a4.__proto__ = { toString: Array.prototype.toString };
+// No join on Array.
+assertEquals("[object Array]", a4.toString());
+
+
+// On a non-Array object.
+
+// Default looks-like-an-array case.
+var o1 = {length: 3, 0: 1, 1: 2, 2: 3,
+ toString: Array.prototype.toString,
+ join: Array.prototype.join};
+assertEquals(o1.join(), o1.toString());
+
+
+// Non-standard join is called correctly.
+// Check that we don't read, e.g., length before calling join.
+var o2 = {toString : Array.prototype.toString,
+ join: testJoin,
+ get length() { assertUnreachable(); },
+ get 0() { assertUnreachable(); }};
+expectedThis = o2;
+assertEquals(success, o2.toString());
+
+// Non-standard join is called even if it looks like an array.
+var o3 = {length: 3, 0: 1, 1: 2, 2: 3,
+ toString: Array.prototype.toString,
+ join: testJoin};
+expectedThis = o3;
+assertEquals(success, o3.toString());
+
+// Non-callable join works same as for Array.
+var o4 = {length: 3, 0: 1, 1: 2, 2: 3,
+ toString: Array.prototype.toString,
+ join: "not callable"};
+assertEquals("[object Object]", o4.toString());
+
+
+// Non-existing join works same as for Array.
+var o5 = {length: 3, 0: 1, 1: 2, 2: 3,
+ toString: Array.prototype.toString
+ /* no join */};
+assertEquals("[object Object]", o5.toString());
+
+
+// Test that ToObject is called before getting "join", so the instance
+// that "join" is read from is the same one passed as receiver later.
+var called_before = false;
+expectedThis = null;
+Object.defineProperty(Number.prototype, "join", {get: function() {
+ assertFalse(called_before);
+ called_before = true;
+ expectedThis = this;
+ return testJoin;
+ }});
+Number.prototype.arrayToString = Array.prototype.toString;
+assertEquals(success, (42).arrayToString());
+
+// ----------------------------------------------------------
+// Testing Array.prototype.toLocaleString
+
+// Ensure that it never uses Array.prototype.toString for anything.
+Array.prototype.toString = function() { assertUnreachable(); };
+
+// Default case.
+var la1 = [1, [2, 3], 4];
+assertEquals("1,2,3,4", la1.toLocaleString());
+
+// Used on a string (which looks like an array of characters).
+String.prototype.toLocaleString = Array.prototype.toLocaleString;
+assertEquals("1,2,3,4", "1234".toLocaleString());
+
+// If toLocaleString of element is not callable, throw a TypeError.
+var la2 = [1, {toLocaleString: "not callable"}, 3];
+assertThrows(function() { la2.toLocaleString(); }, TypeError);
+
+// If toLocaleString of element is callable, call it.
+var la3 = [1, {toLocaleString: function() { return "XX";}}, 3];
+assertEquals("1,XX,3", la3.toLocaleString());
+
+// Omitted elements, as well as undefined and null, become empty string.
+var la4 = [1, null, 3, undefined, 5,, 7];
+assertEquals("1,,3,,5,,7", la4.toLocaleString());
+
+
+// ToObject is called first and the same object is being used for the
+// rest of the operations.
+Object.defineProperty(Number.prototype, "length", {
+ get: function() {
+ exptectedThis = this;
+ return 3;
+ }});
+for (var i = 0; i < 3; i++) {
+ Object.defineProperty(Number.prototype, i, {
+ get: function() {
+ assertEquals(expectedThis, this);
+ return +this;
+ }});
+}
+Number.prototype.arrayToLocaleString = Array.prototype.toLocaleString;
+assertEquals("42,42,42", (42).arrayToLocaleString()); \ No newline at end of file
diff --git a/test/mjsunit/assert-opt-and-deopt.js b/test/mjsunit/assert-opt-and-deopt.js
index c9adb5bb..51cb99ad 100644
--- a/test/mjsunit/assert-opt-and-deopt.js
+++ b/test/mjsunit/assert-opt-and-deopt.js
@@ -150,11 +150,6 @@ tracker.AssertDeoptCount(f, 0);
f(1);
-tracker.AssertOptCount(f, 0);
-tracker.AssertIsOptimized(f, false);
-tracker.AssertDeoptHappened(f, false);
-tracker.AssertDeoptCount(f, 0);
-
%OptimizeFunctionOnNextCall(f);
f(1);
@@ -172,6 +167,7 @@ tracker.AssertDeoptCount(f, 1);
// Let's trigger optimization for another type.
for (var i = 0; i < 5; i++) f("a");
+
%OptimizeFunctionOnNextCall(f);
f("b");
diff --git a/test/mjsunit/bugs/bug-618.js b/test/mjsunit/bugs/bug-618.js
index ae843267..0513f87f 100644
--- a/test/mjsunit/bugs/bug-618.js
+++ b/test/mjsunit/bugs/bug-618.js
@@ -42,4 +42,4 @@ function C() {
assertEquals(23, new C().x);
C.prototype.__defineSetter__('x', function(value) { this.y = 23; });
-assertEquals(void 0, new C().x));
+assertEquals(void 0, new C().x);
diff --git a/test/mjsunit/bugs/harmony/debug-blockscopes.js b/test/mjsunit/bugs/harmony/debug-blockscopes.js
index a407c531..fda32eb3 100644
--- a/test/mjsunit/bugs/harmony/debug-blockscopes.js
+++ b/test/mjsunit/bugs/harmony/debug-blockscopes.js
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --expose-debug-as debug --harmony-block-scoping
+// Flags: --expose-debug-as debug --harmony-scoping
// The functions used for testing backtraces. They are at the top to make the
// testing of source line/column easier.
diff --git a/test/mjsunit/builtins.js b/test/mjsunit/builtins.js
index f2ad5446..e43b5891 100644
--- a/test/mjsunit/builtins.js
+++ b/test/mjsunit/builtins.js
@@ -27,8 +27,7 @@
// Flags: --expose-natives-as=builtins
-// Checks that all function properties of the builtin object are neither
-// writable nor configurable. Also, theose functions that are actually
+// Checks that all function properties of the builtin object that are actually
// constructors (recognized by having properties on their .prototype object),
// have only unconfigurable properties on the prototype, and the methods
// are also non-writable.
@@ -75,8 +74,6 @@ for (var i = 0; i < names.length; i++) {
assertTrue(desc.hasOwnProperty("value"));
var value = desc.value;
if (isFunction(value)) {
- assertFalse(desc.writable, name);
- assertFalse(desc.configurable, name);
checkConstructor(value, name);
}
}
diff --git a/test/mjsunit/comparison-ops-and-undefined.js b/test/mjsunit/comparison-ops-and-undefined.js
new file mode 100644
index 00000000..06db0765
--- /dev/null
+++ b/test/mjsunit/comparison-ops-and-undefined.js
@@ -0,0 +1,128 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function test_helper_for_ics(func, b1, b2, b3, b4) {
+ assertEquals(b1, func(.5, .5));
+ assertEquals(b2, func(.5, undefined));
+ assertEquals(b3, func(undefined, .5));
+ assertEquals(b4, func(undefined, undefined));
+}
+
+function test_helper_for_crankshaft(func, b1, b2, b3, b4) {
+ assertEquals(b1, func(.5, .5));
+ %OptimizeFunctionOnNextCall(func);
+ assertEquals(b1, func(.5, .5));
+ assertEquals(b2, func(.5, undefined));
+ assertEquals(b3, func(undefined, .5));
+ assertEquals(b4, func(undefined, undefined));
+}
+
+function less_1(a, b) {
+ return a < b;
+}
+
+test_helper_for_ics(less_1, false, false, false, false);
+
+function less_2(a, b) {
+ return a < b;
+}
+
+test_helper_for_crankshaft(less_1, false, false, false, false);
+
+function greater_1(a, b) {
+ return a > b;
+}
+
+test_helper_for_ics(greater_1, false, false, false, false);
+
+function greater_2(a, b) {
+ return a > b;
+}
+
+test_helper_for_crankshaft(greater_1, false, false, false, false);
+
+function less_equal_1(a, b) {
+ return a <= b;
+}
+
+test_helper_for_ics(less_equal_1, true, false, false, false);
+
+function less_equal_2(a, b) {
+ return a <= b;
+}
+
+test_helper_for_crankshaft(less_equal_1, true, false, false, false);
+
+function greater_equal_1(a, b) {
+ return a >= b;
+}
+
+test_helper_for_ics(greater_equal_1, true, false, false, false);
+
+function greater_equal_2(a, b) {
+ return a >= b;
+}
+
+test_helper_for_crankshaft(greater_equal_1, true, false, false, false);
+
+function equal_1(a, b) {
+ return a == b;
+}
+
+test_helper_for_ics(equal_1, true, false, false, true);
+
+function equal_2(a, b) {
+ return a == b;
+}
+
+test_helper_for_crankshaft(equal_2, true, false, false, true);
+
+function strict_equal_1(a, b) {
+ return a === b;
+}
+
+test_helper_for_ics(strict_equal_1, true, false, false, true);
+
+function strict_equal_2(a, b) {
+ return a === b;
+}
+
+test_helper_for_crankshaft(strict_equal_2, true, false, false, true);
+
+function not_equal_1(a, b) {
+ return a != b;
+}
+
+test_helper_for_ics(not_equal_1, false, true, true, false);
+
+function not_equal_2(a, b) {
+ return a != b;
+}
+
+test_helper_for_crankshaft(not_equal_2, false, true, true, false);
diff --git a/test/mjsunit/compiler/alloc-object-huge.js b/test/mjsunit/compiler/alloc-object-huge.js
new file mode 100644
index 00000000..d6d9f1b7
--- /dev/null
+++ b/test/mjsunit/compiler/alloc-object-huge.js
@@ -0,0 +1,308 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --inline-construct --nolimit-inlining
+
+// Test that huge constructors (more than 256 this assignments) are
+// handled correctly.
+
+// Test huge constructor when being inlined into hydrogen.
+function test() {
+ return new huge();
+}
+test();
+test();
+%OptimizeFunctionOnNextCall(test);
+var o = test();
+assertEquals(1, o.foo1);
+assertEquals(257, o.foo257);
+
+// Test huge constructor with specialized constructor stub.
+var o = new huge();
+assertEquals(1, o.foo1);
+assertEquals(257, o.foo257);
+
+// The huge constructor, nothing interesting beyond this point.
+function huge() {
+ this.foo1 = 1;
+ this.foo2 = 2;
+ this.foo3 = 3;
+ this.foo4 = 4;
+ this.foo5 = 5;
+ this.foo6 = 6;
+ this.foo7 = 7;
+ this.foo8 = 8;
+ this.foo9 = 9;
+ this.foo10 = 10;
+ this.foo11 = 11;
+ this.foo12 = 12;
+ this.foo13 = 13;
+ this.foo14 = 14;
+ this.foo15 = 15;
+ this.foo16 = 16;
+ this.foo17 = 17;
+ this.foo18 = 18;
+ this.foo19 = 19;
+ this.foo20 = 20;
+ this.foo21 = 21;
+ this.foo22 = 22;
+ this.foo23 = 23;
+ this.foo24 = 24;
+ this.foo25 = 25;
+ this.foo26 = 26;
+ this.foo27 = 27;
+ this.foo28 = 28;
+ this.foo29 = 29;
+ this.foo30 = 30;
+ this.foo31 = 31;
+ this.foo32 = 32;
+ this.foo33 = 33;
+ this.foo34 = 34;
+ this.foo35 = 35;
+ this.foo36 = 36;
+ this.foo37 = 37;
+ this.foo38 = 38;
+ this.foo39 = 39;
+ this.foo40 = 40;
+ this.foo41 = 41;
+ this.foo42 = 42;
+ this.foo43 = 43;
+ this.foo44 = 44;
+ this.foo45 = 45;
+ this.foo46 = 46;
+ this.foo47 = 47;
+ this.foo48 = 48;
+ this.foo49 = 49;
+ this.foo50 = 50;
+ this.foo51 = 51;
+ this.foo52 = 52;
+ this.foo53 = 53;
+ this.foo54 = 54;
+ this.foo55 = 55;
+ this.foo56 = 56;
+ this.foo57 = 57;
+ this.foo58 = 58;
+ this.foo59 = 59;
+ this.foo60 = 60;
+ this.foo61 = 61;
+ this.foo62 = 62;
+ this.foo63 = 63;
+ this.foo64 = 64;
+ this.foo65 = 65;
+ this.foo66 = 66;
+ this.foo67 = 67;
+ this.foo68 = 68;
+ this.foo69 = 69;
+ this.foo70 = 70;
+ this.foo71 = 71;
+ this.foo72 = 72;
+ this.foo73 = 73;
+ this.foo74 = 74;
+ this.foo75 = 75;
+ this.foo76 = 76;
+ this.foo77 = 77;
+ this.foo78 = 78;
+ this.foo79 = 79;
+ this.foo80 = 80;
+ this.foo81 = 81;
+ this.foo82 = 82;
+ this.foo83 = 83;
+ this.foo84 = 84;
+ this.foo85 = 85;
+ this.foo86 = 86;
+ this.foo87 = 87;
+ this.foo88 = 88;
+ this.foo89 = 89;
+ this.foo90 = 90;
+ this.foo91 = 91;
+ this.foo92 = 92;
+ this.foo93 = 93;
+ this.foo94 = 94;
+ this.foo95 = 95;
+ this.foo96 = 96;
+ this.foo97 = 97;
+ this.foo98 = 98;
+ this.foo99 = 99;
+ this.foo100 = 100;
+ this.foo101 = 101;
+ this.foo102 = 102;
+ this.foo103 = 103;
+ this.foo104 = 104;
+ this.foo105 = 105;
+ this.foo106 = 106;
+ this.foo107 = 107;
+ this.foo108 = 108;
+ this.foo109 = 109;
+ this.foo110 = 110;
+ this.foo111 = 111;
+ this.foo112 = 112;
+ this.foo113 = 113;
+ this.foo114 = 114;
+ this.foo115 = 115;
+ this.foo116 = 116;
+ this.foo117 = 117;
+ this.foo118 = 118;
+ this.foo119 = 119;
+ this.foo120 = 120;
+ this.foo121 = 121;
+ this.foo122 = 122;
+ this.foo123 = 123;
+ this.foo124 = 124;
+ this.foo125 = 125;
+ this.foo126 = 126;
+ this.foo127 = 127;
+ this.foo128 = 128;
+ this.foo129 = 129;
+ this.foo130 = 130;
+ this.foo131 = 131;
+ this.foo132 = 132;
+ this.foo133 = 133;
+ this.foo134 = 134;
+ this.foo135 = 135;
+ this.foo136 = 136;
+ this.foo137 = 137;
+ this.foo138 = 138;
+ this.foo139 = 139;
+ this.foo140 = 140;
+ this.foo141 = 141;
+ this.foo142 = 142;
+ this.foo143 = 143;
+ this.foo144 = 144;
+ this.foo145 = 145;
+ this.foo146 = 146;
+ this.foo147 = 147;
+ this.foo148 = 148;
+ this.foo149 = 149;
+ this.foo150 = 150;
+ this.foo151 = 151;
+ this.foo152 = 152;
+ this.foo153 = 153;
+ this.foo154 = 154;
+ this.foo155 = 155;
+ this.foo156 = 156;
+ this.foo157 = 157;
+ this.foo158 = 158;
+ this.foo159 = 159;
+ this.foo160 = 160;
+ this.foo161 = 161;
+ this.foo162 = 162;
+ this.foo163 = 163;
+ this.foo164 = 164;
+ this.foo165 = 165;
+ this.foo166 = 166;
+ this.foo167 = 167;
+ this.foo168 = 168;
+ this.foo169 = 169;
+ this.foo170 = 170;
+ this.foo171 = 171;
+ this.foo172 = 172;
+ this.foo173 = 173;
+ this.foo174 = 174;
+ this.foo175 = 175;
+ this.foo176 = 176;
+ this.foo177 = 177;
+ this.foo178 = 178;
+ this.foo179 = 179;
+ this.foo180 = 180;
+ this.foo181 = 181;
+ this.foo182 = 182;
+ this.foo183 = 183;
+ this.foo184 = 184;
+ this.foo185 = 185;
+ this.foo186 = 186;
+ this.foo187 = 187;
+ this.foo188 = 188;
+ this.foo189 = 189;
+ this.foo190 = 190;
+ this.foo191 = 191;
+ this.foo192 = 192;
+ this.foo193 = 193;
+ this.foo194 = 194;
+ this.foo195 = 195;
+ this.foo196 = 196;
+ this.foo197 = 197;
+ this.foo198 = 198;
+ this.foo199 = 199;
+ this.foo200 = 200;
+ this.foo201 = 201;
+ this.foo202 = 202;
+ this.foo203 = 203;
+ this.foo204 = 204;
+ this.foo205 = 205;
+ this.foo206 = 206;
+ this.foo207 = 207;
+ this.foo208 = 208;
+ this.foo209 = 209;
+ this.foo210 = 210;
+ this.foo211 = 211;
+ this.foo212 = 212;
+ this.foo213 = 213;
+ this.foo214 = 214;
+ this.foo215 = 215;
+ this.foo216 = 216;
+ this.foo217 = 217;
+ this.foo218 = 218;
+ this.foo219 = 219;
+ this.foo220 = 220;
+ this.foo221 = 221;
+ this.foo222 = 222;
+ this.foo223 = 223;
+ this.foo224 = 224;
+ this.foo225 = 225;
+ this.foo226 = 226;
+ this.foo227 = 227;
+ this.foo228 = 228;
+ this.foo229 = 229;
+ this.foo230 = 230;
+ this.foo231 = 231;
+ this.foo232 = 232;
+ this.foo233 = 233;
+ this.foo234 = 234;
+ this.foo235 = 235;
+ this.foo236 = 236;
+ this.foo237 = 237;
+ this.foo238 = 238;
+ this.foo239 = 239;
+ this.foo240 = 240;
+ this.foo241 = 241;
+ this.foo242 = 242;
+ this.foo243 = 243;
+ this.foo244 = 244;
+ this.foo245 = 245;
+ this.foo246 = 246;
+ this.foo247 = 247;
+ this.foo248 = 248;
+ this.foo249 = 249;
+ this.foo250 = 250;
+ this.foo251 = 251;
+ this.foo252 = 252;
+ this.foo253 = 253;
+ this.foo254 = 254;
+ this.foo255 = 255;
+ this.foo256 = 256;
+ this.foo257 = 257;
+}
diff --git a/test/mjsunit/compiler/alloc-object.js b/test/mjsunit/compiler/alloc-object.js
new file mode 100644
index 00000000..1d44efb5
--- /dev/null
+++ b/test/mjsunit/compiler/alloc-object.js
@@ -0,0 +1,90 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --expose-gc --inline-construct
+
+// Test that inlined object allocation works for different layouts of
+// objects (e.g. in object properties, slack tracking in progress or
+// changing of function prototypes)
+
+function test_helper(construct, a, b) {
+ return new construct(a, b);
+}
+
+function test(construct) {
+ %DeoptimizeFunction(test);
+ test_helper(construct, 0, 0);
+ test_helper(construct, 0, 0);
+ %OptimizeFunctionOnNextCall(test_helper);
+ // Test adding a new property after allocation was inlined.
+ var o = test_helper(construct, 1, 2);
+ o.z = 3;
+ assertEquals(1, o.x);
+ assertEquals(2, o.y);
+ assertEquals(3, o.z);
+ // Test changing the prototype after allocation was inlined.
+ construct.prototype = { z:6 };
+ var o = test_helper(construct, 4, 5);
+ assertEquals(4, o.x);
+ assertEquals(5, o.y);
+ assertEquals(6, o.z);
+ %DeoptimizeFunction(test_helper);
+ gc(); // Makes V8 forget about type information for test_helper.
+}
+
+function finalize_slack_tracking(construct) {
+ // Value chosen based on kGenerousAllocationCount = 8.
+ for (var i = 0; i < 8; i++) {
+ new construct(0, 0);
+ }
+}
+
+
+// Both properties are pre-allocated in object properties.
+function ConstructInObjectPreAllocated(a, b) {
+ this.x = a;
+ this.y = b;
+}
+finalize_slack_tracking(ConstructInObjectPreAllocated);
+test(ConstructInObjectPreAllocated);
+
+
+// Both properties are unused in object properties.
+function ConstructInObjectUnused(a, b) {
+ this.x = a < 0 ? 0 : a;
+ this.y = b > 0 ? b : 0;
+}
+finalize_slack_tracking(ConstructInObjectUnused);
+test(ConstructInObjectUnused);
+
+
+// Test inlined allocation while slack tracking is still in progress.
+function ConstructWhileSlackTracking(a, b) {
+ this.x = a;
+ this.y = b;
+}
+test(ConstructWhileSlackTracking);
diff --git a/test/mjsunit/compiler/compare.js b/test/mjsunit/compiler/compare.js
index 3f960870..460b0ab0 100644
--- a/test/mjsunit/compiler/compare.js
+++ b/test/mjsunit/compiler/compare.js
@@ -83,9 +83,9 @@ function TestNonPrimitive(order, f) {
}
TestNonPrimitive("xy", MaxLT);
-TestNonPrimitive("yx", MaxLE);
+TestNonPrimitive("xy", MaxLE);
TestNonPrimitive("xy", MaxGE);
-TestNonPrimitive("yx", MaxGT);
+TestNonPrimitive("xy", MaxGT);
// Test compare in case of aliased registers.
function CmpX(x) { if (x == x) return 42; }
diff --git a/test/mjsunit/compiler/inline-arguments.js b/test/mjsunit/compiler/inline-arguments.js
index 532fc26a..b6adf7f6 100644
--- a/test/mjsunit/compiler/inline-arguments.js
+++ b/test/mjsunit/compiler/inline-arguments.js
@@ -27,11 +27,89 @@
// Flags: --allow-natives-syntax
-// Test inlining functions that use arguments.
-function f() { return g(1, 2, 3); }
+function A() {
+}
-function g(x, y, z) { return %_ArgumentsLength(); }
+A.prototype.X = function (a, b, c) {
+ assertTrue(this instanceof A);
+ assertEquals(1, a);
+ assertEquals(2, b);
+ assertEquals(3, c);
+};
-for (var i = 0; i < 5; ++i) f();
-%OptimizeFunctionOnNextCall(f);
-assertEquals(3, f());
+A.prototype.Y = function () {
+ this.X.apply(this, arguments);
+};
+
+A.prototype.Z = function () {
+ this.Y(1,2,3);
+};
+
+var a = new A();
+a.Z(4,5,6);
+a.Z(4,5,6);
+%OptimizeFunctionOnNextCall(a.Z);
+a.Z(4,5,6);
+A.prototype.X.apply = function (receiver, args) {
+ return Function.prototype.apply.call(this, receiver, args);
+};
+a.Z(4,5,6);
+
+
+// Ensure that HArgumentsObject is inserted in a correct place
+// and dominates all uses.
+function F1() { }
+function F2() { F1.apply(this, arguments); }
+function F3(x, y) {
+ if (x) {
+ F2(y);
+ }
+}
+
+function F31() {
+ return F1.apply(this, arguments);
+}
+
+function F4() {
+ F3(true, false);
+ return F31(1);
+}
+
+F4(1);
+F4(1);
+F4(1);
+%OptimizeFunctionOnNextCall(F4);
+F4(1);
+
+
+// Test correct adapation of arguments.
+// Strict mode prevents arguments object from shadowing parameters.
+(function () {
+ "use strict";
+
+ function G2() {
+ assertArrayEquals([1,2], arguments);
+ }
+
+ function G4() {
+ assertArrayEquals([1,2,3,4], arguments);
+ }
+
+ function adapt2to4(a, b, c, d) {
+ G2.apply(this, arguments);
+ }
+
+ function adapt4to2(a, b) {
+ G4.apply(this, arguments);
+ }
+
+ function test_adaptation() {
+ adapt2to4(1, 2);
+ adapt4to2(1, 2, 3, 4);
+ }
+
+ test_adaptation();
+ test_adaptation();
+ %OptimizeFunctionOnNextCall(test_adaptation);
+ test_adaptation();
+})();
diff --git a/test/mjsunit/compiler/inline-arity-mismatch.js b/test/mjsunit/compiler/inline-arity-mismatch.js
new file mode 100644
index 00000000..4a61fa3a
--- /dev/null
+++ b/test/mjsunit/compiler/inline-arity-mismatch.js
@@ -0,0 +1,62 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+// Test inlining at call sites with mismatched arity.
+
+function f(a) {
+ return a.x;
+}
+
+function g(a, b) {
+ return a.x;
+}
+
+function h1(a, b) {
+ return f(a, a) * g(b);
+}
+
+function h2(a, b) {
+ return f(a, a) * g(b);
+}
+
+
+var o = {x: 2};
+
+assertEquals(4, h1(o, o));
+assertEquals(4, h1(o, o));
+assertEquals(4, h2(o, o));
+assertEquals(4, h2(o, o));
+%OptimizeFunctionOnNextCall(h1);
+%OptimizeFunctionOnNextCall(h2);
+assertEquals(4, h1(o, o));
+assertEquals(4, h2(o, o));
+
+var u = {y:0, x:1};
+assertEquals(2, h1(u, o));
+assertEquals(2, h2(o, u));
diff --git a/test/mjsunit/compiler/inline-construct.js b/test/mjsunit/compiler/inline-construct.js
new file mode 100644
index 00000000..af9e69c9
--- /dev/null
+++ b/test/mjsunit/compiler/inline-construct.js
@@ -0,0 +1,152 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --expose-gc --inline-construct
+
+// Test inlining of constructor calls.
+
+function TestInlinedConstructor(closure) {
+ var result;
+ var counter = { value:0 };
+ result = closure(11, 12, counter);
+ assertEquals(23, result);
+ assertEquals(1, counter.value);
+ result = closure(23, 19, counter);
+ assertEquals(42, result);
+ assertEquals(2, counter.value);
+ %OptimizeFunctionOnNextCall(closure);
+ result = closure(1, 42, counter)
+ assertEquals(43, result);
+ assertEquals(3, counter.value);
+ result = closure("foo", "bar", counter)
+ assertEquals("foobar", result)
+ assertEquals(4, counter.value);
+}
+
+function TestInAllContexts(constructor) {
+ function value_context(a, b, counter) {
+ var obj = new constructor(a, b, counter);
+ return obj.x;
+ }
+ function test_context(a, b, counter) {
+ if (!new constructor(a, b, counter)) {
+ assertUnreachable("should not happen");
+ }
+ return a + b;
+ }
+ function effect_context(a, b, counter) {
+ new constructor(a, b, counter);
+ return a + b;
+ }
+ TestInlinedConstructor(value_context);
+ TestInlinedConstructor(test_context);
+ TestInlinedConstructor(effect_context);
+ %DeoptimizeFunction(value_context);
+ %DeoptimizeFunction(test_context);
+ %DeoptimizeFunction(effect_context);
+ gc(); // Makes V8 forget about type information for *_context.
+}
+
+
+// Test constructor returning nothing in all contexts.
+function c1(a, b, counter) {
+ this.x = a + b;
+ counter.value++;
+}
+TestInAllContexts(c1);
+
+
+// Test constructor returning an object in all contexts.
+function c2(a, b, counter) {
+ var obj = new Object();
+ obj.x = a + b;
+ counter.value++;
+ return obj;
+}
+TestInAllContexts(c2);
+
+
+// Test constructor returning a primitive value in all contexts.
+function c3(a, b, counter) {
+ this.x = a + b;
+ counter.value++;
+ return "not an object";
+}
+TestInAllContexts(c3);
+
+
+// Test constructor called with too many arguments.
+function c_too_many(a, b) {
+ this.x = a + b;
+}
+function f_too_many(a, b, c) {
+ var obj = new c_too_many(a, b, c);
+ return obj.x;
+}
+assertEquals(23, f_too_many(11, 12, 1));
+assertEquals(42, f_too_many(23, 19, 1));
+%OptimizeFunctionOnNextCall(f_too_many);
+assertEquals(43, f_too_many(1, 42, 1));
+assertEquals("foobar", f_too_many("foo", "bar", "baz"))
+
+
+// Test constructor called with too few arguments.
+function c_too_few(a, b) {
+ assertSame(undefined, b);
+ this.x = a + 1;
+}
+function f_too_few(a) {
+ var obj = new c_too_few(a);
+ return obj.x;
+}
+assertEquals(12, f_too_few(11));
+assertEquals(24, f_too_few(23));
+%OptimizeFunctionOnNextCall(f_too_few);
+assertEquals(2, f_too_few(1));
+assertEquals("foo1", f_too_few("foo"))
+
+
+// Test constructor that cannot be inlined.
+function c_unsupported_syntax(a, b, counter) {
+ try {
+ this.x = a + b;
+ counter.value++;
+ } catch(e) {
+ throw new Error();
+ }
+}
+TestInAllContexts(c_unsupported_syntax);
+
+
+// Regression test: Inlined constructors called as functions do not get their
+// implicit receiver object set to undefined, even in strict mode.
+function c_strict(a, b, counter) {
+ "use strict";
+ this.x = a + b;
+ counter.value++;
+}
+TestInAllContexts(c_strict);
diff --git a/test/mjsunit/compiler/inline-context-slots.js b/test/mjsunit/compiler/inline-context-slots.js
new file mode 100644
index 00000000..d0e907b1
--- /dev/null
+++ b/test/mjsunit/compiler/inline-context-slots.js
@@ -0,0 +1,49 @@
+// 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.
+
+// Test inlining of functions with context slots.
+
+// Flags: --allow-natives-syntax
+
+
+// Caller/callee without a local context.
+
+(function() {
+ var X = 5;
+ var Y = 10;
+ function F() {}
+ F.prototype.max = function() {
+ return X > Y ? X : Y;
+ }
+ F.prototype.run = function() {
+ return this.max();
+ }
+ var f = new F();
+ for (var i=0; i<5; i++) f.run();
+ %OptimizeFunctionOnNextCall(f.run);
+ assertEquals(10, f.run());
+})();
diff --git a/test/mjsunit/compiler/inline-literals.js b/test/mjsunit/compiler/inline-literals.js
new file mode 100644
index 00000000..f78abe82
--- /dev/null
+++ b/test/mjsunit/compiler/inline-literals.js
@@ -0,0 +1,50 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+// Test that we can inline functions containing materialized literals.
+
+function o2(b, c) {
+ return { 'b':b, 'c':c, 'y':b + c };
+}
+
+function o1(a, b, c) {
+ return { 'a':a, 'x':o2(b, c) };
+}
+
+function TestObjectLiteral(a, b, c) {
+ var expected = { 'a':a, 'x':{ 'b':b, 'c':c, 'y':b + c } };
+ var result = o1(a, b, c);
+ assertEquals(expected, result, "TestObjectLiteral");
+}
+
+TestObjectLiteral(1, 2, 3);
+TestObjectLiteral(1, 2, 3);
+%OptimizeFunctionOnNextCall(TestObjectLiteral);
+TestObjectLiteral(1, 2, 3);
+TestObjectLiteral('a', 'b', 'c');
diff --git a/test/mjsunit/regress/regress-221.js b/test/mjsunit/compiler/lazy-const-lookup.js
index d3f2e355..b4f15a1c 100644
--- a/test/mjsunit/regress/regress-221.js
+++ b/test/mjsunit/compiler/lazy-const-lookup.js
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// 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:
@@ -25,10 +25,17 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Test that direct eval calls handle the case where eval has been
-// deleted correctly.
+// Flags: --allow-natives-syntax
-// See http://code.google.com/p/v8/issues/detail?id=221
+function outer() {
+ const x = 1;
+ function inner() {
+ return x;
+ }
+ inner();
+ %OptimizeFunctionOnNextCall(inner);
+ inner();
+}
-assertThrows('eval(delete eval)');
+outer();
diff --git a/test/mjsunit/compiler/literals-optimized.js b/test/mjsunit/compiler/literals-optimized.js
new file mode 100644
index 00000000..049e21a3
--- /dev/null
+++ b/test/mjsunit/compiler/literals-optimized.js
@@ -0,0 +1,121 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+// Test optimized versions of array and object literals.
+
+function TestOptimizedLiteral(create, verify) {
+ verify(create(1, 2, 3), 1, 2, 3);
+ verify(create(3, 5, 7), 3, 5, 7);
+ %OptimizeFunctionOnNextCall(create);
+ verify(create(11, 23, 42), 11, 23, 42);
+}
+
+
+// Test shallow array literal.
+function create_arr_shallow(a, b, c) {
+ return [0, a, 0, b, 0, c];
+}
+function verify_arr_shallow(array, a, b, c) {
+ assertSame(6, array.length);
+ assertSame(0, array[0]);
+ assertSame(a, array[1]);
+ assertSame(0, array[2]);
+ assertSame(b, array[3]);
+ assertSame(0, array[4]);
+ assertSame(c, array[5]);
+}
+TestOptimizedLiteral(create_arr_shallow, verify_arr_shallow);
+
+
+// Test nested array literal.
+function create_arr_nested(a, b, c) {
+ return [[0, a], [b, c], [1, 2], 3];
+}
+function verify_arr_nested(array, a, b, c) {
+ assertSame(4, array.length);
+ assertSame(2, array[0].length);
+ assertSame(0, array[0][0]);
+ assertSame(a, array[0][1]);
+ assertSame(2, array[1].length);
+ assertSame(b, array[1][0]);
+ assertSame(c, array[1][1]);
+ assertSame(2, array[2].length);
+ assertSame(1, array[2][0]);
+ assertSame(2, array[2][1]);
+ assertSame(3, array[3]);
+}
+TestOptimizedLiteral(create_arr_nested, verify_arr_nested);
+
+
+// Test shallow object literal.
+function create_obj_shallow(a, b, c) {
+ return { x:a, y:b, z:c, v:'foo', 9:'bar' };
+}
+function verify_obj_shallow(object, a, b, c) {
+ assertSame(a, object.x);
+ assertSame(b, object.y);
+ assertSame(c, object.z);
+ assertSame('foo', object.v);
+ assertSame('bar', object[9]);
+}
+TestOptimizedLiteral(create_obj_shallow, verify_obj_shallow);
+
+
+// Test nested object literal.
+function create_obj_nested(a, b, c) {
+ return { x:{ v:a, w:b }, y:{ v:1, w:2 }, z:c, v:'foo', 9:'bar' };
+}
+function verify_obj_nested(object, a, b, c) {
+ assertSame(a, object.x.v);
+ assertSame(b, object.x.w);
+ assertSame(1, object.y.v);
+ assertSame(2, object.y.w);
+ assertSame(c, object.z);
+ assertSame('foo', object.v);
+ assertSame('bar', object[9]);
+}
+TestOptimizedLiteral(create_obj_nested, verify_obj_nested);
+
+
+// Test mixed array and object literal.
+function create_mixed_nested(a, b, c) {
+ return { x:[1, 2], y:[a, b], z:c, v:{ v:'foo' }, 9:'bar' };
+}
+function verify_mixed_nested(object, a, b, c) {
+ assertSame(2, object.x.length);
+ assertSame(1, object.x[0]);
+ assertSame(2, object.x[1]);
+ assertSame(2, object.y.length);
+ assertSame(a, object.y[0]);
+ assertSame(b, object.y[1]);
+ assertSame(c, object.z);
+ assertSame('foo', object.v.v);
+ assertSame('bar', object[9]);
+}
+TestOptimizedLiteral(create_mixed_nested, verify_mixed_nested);
diff --git a/test/mjsunit/compiler/math-floor-global.js b/test/mjsunit/compiler/math-floor-global.js
new file mode 100644
index 00000000..9ec183fa
--- /dev/null
+++ b/test/mjsunit/compiler/math-floor-global.js
@@ -0,0 +1,161 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --max-new-space-size=256 --allow-natives-syntax
+
+// Test inlining of Math.floor when assigned to a global.
+var flo = Math.floor;
+var test_id = 0;
+
+function testFloor(expect, input) {
+ var test = new Function('n',
+ '"' + (test_id++) + '";return flo(n)');
+ assertEquals(expect, test(input));
+ assertEquals(expect, test(input));
+ assertEquals(expect, test(input));
+ %OptimizeFunctionOnNextCall(test);
+ assertEquals(expect, test(input));
+}
+
+function zero() {
+ var x = 0.5;
+ return (function() { return x - 0.5; })();
+}
+
+function test() {
+ testFloor(0, 0);
+ testFloor(0, zero());
+ testFloor(-0, -0);
+ testFloor(Infinity, Infinity);
+ testFloor(-Infinity, -Infinity);
+ testFloor(NaN, NaN);
+
+ // Ensure that a negative zero coming from Math.floor is properly handled
+ // by other operations.
+ function ifloor(x) {
+ return 1 / Math.floor(x);
+ }
+ assertEquals(-Infinity, ifloor(-0));
+ assertEquals(-Infinity, ifloor(-0));
+ assertEquals(-Infinity, ifloor(-0));
+ %OptimizeFunctionOnNextCall(ifloor);
+ assertEquals(-Infinity, ifloor(-0));
+
+ testFloor(0, 0.1);
+ testFloor(0, 0.49999999999999994);
+ testFloor(0, 0.5);
+ testFloor(0, 0.7);
+ testFloor(-1, -0.1);
+ testFloor(-1, -0.49999999999999994);
+ testFloor(-1, -0.5);
+ testFloor(-1, -0.7);
+ testFloor(1, 1);
+ testFloor(1, 1.1);
+ testFloor(1, 1.5);
+ testFloor(1, 1.7);
+ testFloor(-1, -1);
+ testFloor(-2, -1.1);
+ testFloor(-2, -1.5);
+ testFloor(-2, -1.7);
+
+ testFloor(0, Number.MIN_VALUE);
+ testFloor(-1, -Number.MIN_VALUE);
+ testFloor(Number.MAX_VALUE, Number.MAX_VALUE);
+ testFloor(-Number.MAX_VALUE, -Number.MAX_VALUE);
+ testFloor(Infinity, Infinity);
+ testFloor(-Infinity, -Infinity);
+
+ // 2^30 is a smi boundary.
+ var two_30 = 1 << 30;
+
+ testFloor(two_30, two_30);
+ testFloor(two_30, two_30 + 0.1);
+ testFloor(two_30, two_30 + 0.5);
+ testFloor(two_30, two_30 + 0.7);
+
+ testFloor(two_30 - 1, two_30 - 1);
+ testFloor(two_30 - 1, two_30 - 1 + 0.1);
+ testFloor(two_30 - 1, two_30 - 1 + 0.5);
+ testFloor(two_30 - 1, two_30 - 1 + 0.7);
+
+ testFloor(-two_30, -two_30);
+ testFloor(-two_30, -two_30 + 0.1);
+ testFloor(-two_30, -two_30 + 0.5);
+ testFloor(-two_30, -two_30 + 0.7);
+
+ testFloor(-two_30 + 1, -two_30 + 1);
+ testFloor(-two_30 + 1, -two_30 + 1 + 0.1);
+ testFloor(-two_30 + 1, -two_30 + 1 + 0.5);
+ testFloor(-two_30 + 1, -two_30 + 1 + 0.7);
+
+ // 2^52 is a precision boundary.
+ var two_52 = (1 << 30) * (1 << 22);
+
+ testFloor(two_52, two_52);
+ testFloor(two_52, two_52 + 0.1);
+ assertEquals(two_52, two_52 + 0.5);
+ testFloor(two_52, two_52 + 0.5);
+ assertEquals(two_52 + 1, two_52 + 0.7);
+ testFloor(two_52 + 1, two_52 + 0.7);
+
+ testFloor(two_52 - 1, two_52 - 1);
+ testFloor(two_52 - 1, two_52 - 1 + 0.1);
+ testFloor(two_52 - 1, two_52 - 1 + 0.5);
+ testFloor(two_52 - 1, two_52 - 1 + 0.7);
+
+ testFloor(-two_52, -two_52);
+ testFloor(-two_52, -two_52 + 0.1);
+ testFloor(-two_52, -two_52 + 0.5);
+ testFloor(-two_52, -two_52 + 0.7);
+
+ testFloor(-two_52 + 1, -two_52 + 1);
+ testFloor(-two_52 + 1, -two_52 + 1 + 0.1);
+ testFloor(-two_52 + 1, -two_52 + 1 + 0.5);
+ testFloor(-two_52 + 1, -two_52 + 1 + 0.7);
+}
+
+
+// Test in a loop to cover the custom IC and GC-related issues.
+for (var i = 0; i < 50; i++) {
+ test();
+}
+
+
+// Regression test for a bug where a negative zero coming from Math.floor
+// was not properly handled by other operations.
+function floorsum(i, n) {
+ var ret = Math.floor(n);
+ while (--i > 0) {
+ ret += Math.floor(n);
+ }
+ return ret;
+}
+assertEquals(-0, floorsum(1, -0));
+%OptimizeFunctionOnNextCall(floorsum);
+// The optimized function will deopt. Run it with enough iterations to try
+// to optimize via OSR (triggering the bug).
+assertEquals(-0, floorsum(100000, -0));
diff --git a/test/mjsunit/compiler/math-floor-local.js b/test/mjsunit/compiler/math-floor-local.js
new file mode 100644
index 00000000..e44b15c7
--- /dev/null
+++ b/test/mjsunit/compiler/math-floor-local.js
@@ -0,0 +1,161 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --max-new-space-size=256 --allow-natives-syntax
+
+// Test inlining of Math.floor when assigned to a local.
+var test_id = 0;
+
+function testFloor(expect, input) {
+ var test = new Function('n',
+ '"' + (test_id++) +
+ '";var f = Math.floor; return f(n)');
+ assertEquals(expect, test(input));
+ assertEquals(expect, test(input));
+ assertEquals(expect, test(input));
+ %OptimizeFunctionOnNextCall(test);
+ assertEquals(expect, test(input));
+}
+
+function zero() {
+ var x = 0.5;
+ return (function() { return x - 0.5; })();
+}
+
+function test() {
+ testFloor(0, 0);
+ testFloor(0, zero());
+ testFloor(-0, -0);
+ testFloor(Infinity, Infinity);
+ testFloor(-Infinity, -Infinity);
+ testFloor(NaN, NaN);
+
+ // Ensure that a negative zero coming from Math.floor is properly handled
+ // by other operations.
+ function ifloor(x) {
+ return 1 / Math.floor(x);
+ }
+ assertEquals(-Infinity, ifloor(-0));
+ assertEquals(-Infinity, ifloor(-0));
+ assertEquals(-Infinity, ifloor(-0));
+ %OptimizeFunctionOnNextCall(ifloor);
+ assertEquals(-Infinity, ifloor(-0));
+
+ testFloor(0, 0.1);
+ testFloor(0, 0.49999999999999994);
+ testFloor(0, 0.5);
+ testFloor(0, 0.7);
+ testFloor(-1, -0.1);
+ testFloor(-1, -0.49999999999999994);
+ testFloor(-1, -0.5);
+ testFloor(-1, -0.7);
+ testFloor(1, 1);
+ testFloor(1, 1.1);
+ testFloor(1, 1.5);
+ testFloor(1, 1.7);
+ testFloor(-1, -1);
+ testFloor(-2, -1.1);
+ testFloor(-2, -1.5);
+ testFloor(-2, -1.7);
+
+ testFloor(0, Number.MIN_VALUE);
+ testFloor(-1, -Number.MIN_VALUE);
+ testFloor(Number.MAX_VALUE, Number.MAX_VALUE);
+ testFloor(-Number.MAX_VALUE, -Number.MAX_VALUE);
+ testFloor(Infinity, Infinity);
+ testFloor(-Infinity, -Infinity);
+
+ // 2^30 is a smi boundary.
+ var two_30 = 1 << 30;
+
+ testFloor(two_30, two_30);
+ testFloor(two_30, two_30 + 0.1);
+ testFloor(two_30, two_30 + 0.5);
+ testFloor(two_30, two_30 + 0.7);
+
+ testFloor(two_30 - 1, two_30 - 1);
+ testFloor(two_30 - 1, two_30 - 1 + 0.1);
+ testFloor(two_30 - 1, two_30 - 1 + 0.5);
+ testFloor(two_30 - 1, two_30 - 1 + 0.7);
+
+ testFloor(-two_30, -two_30);
+ testFloor(-two_30, -two_30 + 0.1);
+ testFloor(-two_30, -two_30 + 0.5);
+ testFloor(-two_30, -two_30 + 0.7);
+
+ testFloor(-two_30 + 1, -two_30 + 1);
+ testFloor(-two_30 + 1, -two_30 + 1 + 0.1);
+ testFloor(-two_30 + 1, -two_30 + 1 + 0.5);
+ testFloor(-two_30 + 1, -two_30 + 1 + 0.7);
+
+ // 2^52 is a precision boundary.
+ var two_52 = (1 << 30) * (1 << 22);
+
+ testFloor(two_52, two_52);
+ testFloor(two_52, two_52 + 0.1);
+ assertEquals(two_52, two_52 + 0.5);
+ testFloor(two_52, two_52 + 0.5);
+ assertEquals(two_52 + 1, two_52 + 0.7);
+ testFloor(two_52 + 1, two_52 + 0.7);
+
+ testFloor(two_52 - 1, two_52 - 1);
+ testFloor(two_52 - 1, two_52 - 1 + 0.1);
+ testFloor(two_52 - 1, two_52 - 1 + 0.5);
+ testFloor(two_52 - 1, two_52 - 1 + 0.7);
+
+ testFloor(-two_52, -two_52);
+ testFloor(-two_52, -two_52 + 0.1);
+ testFloor(-two_52, -two_52 + 0.5);
+ testFloor(-two_52, -two_52 + 0.7);
+
+ testFloor(-two_52 + 1, -two_52 + 1);
+ testFloor(-two_52 + 1, -two_52 + 1 + 0.1);
+ testFloor(-two_52 + 1, -two_52 + 1 + 0.5);
+ testFloor(-two_52 + 1, -two_52 + 1 + 0.7);
+}
+
+
+// Test in a loop to cover the custom IC and GC-related issues.
+for (var i = 0; i < 50; i++) {
+ test();
+}
+
+
+// Regression test for a bug where a negative zero coming from Math.floor
+// was not properly handled by other operations.
+function floorsum(i, n) {
+ var ret = Math.floor(n);
+ while (--i > 0) {
+ ret += Math.floor(n);
+ }
+ return ret;
+}
+assertEquals(-0, floorsum(1, -0));
+%OptimizeFunctionOnNextCall(floorsum);
+// The optimized function will deopt. Run it with enough iterations to try
+// to optimize via OSR (triggering the bug).
+assertEquals(-0, floorsum(100000, -0));
diff --git a/test/mjsunit/compiler/optimized-for-in.js b/test/mjsunit/compiler/optimized-for-in.js
new file mode 100644
index 00000000..cb8c66df
--- /dev/null
+++ b/test/mjsunit/compiler/optimized-for-in.js
@@ -0,0 +1,300 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --optimize-for-in --allow-natives-syntax
+
+// Test for-in support in Crankshaft. For simplicity this tests assumes certain
+// fixed iteration order for properties and will have to be adjusted if V8
+// stops following insertion order.
+
+
+function a(t) {
+ var result = [];
+ for (var i in t) {
+ result.push(i + t[i]);
+ }
+ return result.join('');
+}
+
+// Check that we correctly deoptimize on map check.
+function b(t) {
+ var result = [];
+ for (var i in t) {
+ result.push(i + t[i]);
+ delete t[i];
+ }
+ return result.join('');
+}
+
+// Check that we correctly deoptimize during preparation step.
+function c(t) {
+ var result = [];
+ for (var i in t) {
+ result.push(i + t[i]);
+ }
+ return result.join('');
+}
+
+// Check that we deoptimize to the place after side effect in the right state.
+function d(t) {
+ var result = [];
+ var o;
+ for (var i in (o = t())) {
+ result.push(i + o[i]);
+ }
+ return result.join('');
+}
+
+// Check that we correctly deoptimize on map check inserted for fused load.
+function e(t) {
+ var result = [];
+ for (var i in t) {
+ delete t[i];
+ t[i] = i;
+ result.push(i + t[i]);
+ }
+ return result.join('');
+}
+
+// Nested for-in loops.
+function f(t) {
+ var result = [];
+ for (var i in t) {
+ for (var j in t) {
+ result.push(i + j + t[i] + t[j]);
+ }
+ }
+ return result.join('');
+}
+
+// Deoptimization from the inner for-in loop.
+function g(t) {
+ var result = [];
+ for (var i in t) {
+ for (var j in t) {
+ result.push(i + j + t[i] + t[j]);
+ var v = t[i];
+ delete t[i];
+ t[i] = v;
+ }
+ }
+ return result.join('');
+}
+
+
+// Break from the inner for-in loop.
+function h(t, deopt) {
+ var result = [];
+ for (var i in t) {
+ for (var j in t) {
+ result.push(i + j + t[i] + t[j]);
+ break;
+ }
+ }
+ deopt.deopt;
+ return result.join('');
+}
+
+// Continue in the inner loop.
+function j(t, deopt) {
+ var result = [];
+ for (var i in t) {
+ for (var j in t) {
+ result.push(i + j + t[i] + t[j]);
+ continue;
+ }
+ }
+ deopt.deopt;
+ return result.join('');
+}
+
+// Continue of the outer loop.
+function k(t, deopt) {
+ var result = [];
+ outer: for (var i in t) {
+ for (var j in t) {
+ result.push(i + j + t[i] + t[j]);
+ continue outer;
+ }
+ }
+ deopt.deopt;
+ return result.join('');
+}
+
+// Break of the outer loop.
+function l(t, deopt) {
+ var result = [];
+ outer: for (var i in t) {
+ for (var j in t) {
+ result.push(i + j + t[i] + t[j]);
+ break outer;
+ }
+ }
+ deopt.deopt;
+ return result.join('');
+}
+
+// Test deoptimization from inlined frame (currently it is not inlined).
+function m0(t, deopt) {
+ for (var i in t) {
+ for (var j in t) {
+ deopt.deopt;
+ return i + j + t[i] + t[j];
+ }
+ }
+}
+
+function m(t, deopt) {
+ return m0(t, deopt);
+}
+
+
+function tryFunction(s, mkT, f) {
+ var d = {deopt: false};
+ assertEquals(s, f(mkT(), d));
+ assertEquals(s, f(mkT(), d));
+ assertEquals(s, f(mkT(), d));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(s, f(mkT(), d));
+ assertEquals(s, f(mkT(), {}));
+}
+
+var s = "a1b2c3d4";
+function mkTable() { return { a: "1", b: "2", c: "3", d: "4" }; }
+
+
+tryFunction(s, mkTable, a);
+tryFunction(s, mkTable, b);
+tryFunction("0a1b2c3d", function () { return "abcd"; }, c);
+tryFunction("0a1b2c3d", function () {
+ var cnt = false;
+ return function () {
+ cnt = true;
+ return "abcd";
+ }
+}, d);
+tryFunction("aabbccdd", mkTable, e);
+
+function mkSmallTable() { return { a: "1", b: "2" }; }
+
+tryFunction("aa11ab12ba21bb22", mkSmallTable, f);
+tryFunction("aa11ab12bb22ba21", mkSmallTable, g);
+tryFunction("aa11ba21", mkSmallTable, h);
+tryFunction("aa11ab12ba21bb22", mkSmallTable, j);
+tryFunction("aa11ba21", mkSmallTable, h);
+tryFunction("aa11ba21", mkSmallTable, k);
+tryFunction("aa11", mkSmallTable, l);
+tryFunction("aa11", mkSmallTable, m);
+
+// Test handling of null.
+tryFunction("", function () {
+ return function () { return null; }
+}, function (t) {
+ for (var i in t()) { return i; }
+ return "";
+});
+
+// Test smis.
+tryFunction("", function () {
+ return function () { return 11; }
+}, function (t) {
+ for (var i in t()) { return i; }
+ return "";
+});
+
+// Test LoadFieldByIndex for out of object properties.
+function O() { this.a = 1; }
+for (var i = 0; i < 10; i++) new O();
+tryFunction("a1b2c3d4e5f6", function () {
+ var o = new O();
+ o.b = 2;
+ o.c = 3;
+ o.d = 4;
+ o.e = 5;
+ o.f = 6;
+ return o;
+}, function (t) {
+ var r = [];
+ for (var i in t) r.push(i + t[i]);
+ return r.join('');
+});
+
+// Test OSR inside for-in.
+function osr_inner(t, limit) {
+ var r = 1;
+ for (var x in t) {
+ if (t.hasOwnProperty(x)) {
+ for (var i = 0; i < t[x].length; i++) {
+ r += t[x][i];
+ if (i === limit) {
+ %OptimizeFunctionOnNextCall(osr_inner, "osr");
+ }
+ }
+ r += x;
+ }
+ }
+ return r;
+}
+
+function osr_outer(t, osr_after) {
+ var r = 1;
+ for (var x in t) {
+ for (var i = 0; i < t[x].length; i++) {
+ r += t[x][i];
+ }
+ if (x === osr_after) {
+ %OptimizeFunctionOnNextCall(osr_outer, "osr");
+ }
+ r += x;
+ }
+ return r;
+}
+
+function osr_outer_and_deopt(t, osr_after) {
+ var r = 1;
+ for (var x in t) {
+ r += x;
+ if (x == osr_after) {
+ %OptimizeFunctionOnNextCall(osr_outer_and_deopt, "osr");
+ }
+ }
+ return r;
+}
+
+function test_osr() {
+ with ({}) {} // Disable optimizations of this function.
+ var arr = new Array(20);
+ for (var i = 0; i < arr.length; i++) {
+ arr[i] = i + 1;
+ }
+ arr.push(":"); // Force deopt at the end of the loop.
+ assertEquals("211:x1234567891011121314151617181920:y", osr_inner({x: arr, y: arr}, (arr.length / 2) | 0));
+ assertEquals("7x456y", osr_outer({x: [1,2,3], y: [4,5,6]}, "x"));
+ assertEquals("101234567", osr_outer_and_deopt([1,2,3,4,5,6,7,8], "5"));
+}
+
+test_osr();
diff --git a/test/mjsunit/cyclic-error-to-string.js b/test/mjsunit/compiler/regress-96989.js
index 2502b534..aedeb243 100644
--- a/test/mjsunit/cyclic-error-to-string.js
+++ b/test/mjsunit/compiler/regress-96989.js
@@ -25,22 +25,19 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Test printing of cyclic errors which return the empty string for
-// compatibility with Safari and Firefox.
-var e = new Error();
-assertEquals('Error', e + '');
+// Flags: --allow-natives-syntax
-e = new Error();
-e.name = e;
-e.message = e;
-e.stack = e;
-e.arguments = e;
-assertEquals(': ', e + '');
+// Test correct handling of uninitialized const.
-e = new Error();
-e.name = [ e ];
-e.message = [ e ];
-e.stack = [ e ];
-e.arguments = [ e ];
-assertEquals(': ', e + '');
+function test() {
+ for (var i = 41; i < 42; i++) {
+ var c = t ^ i;
+ }
+ const t;
+ return c;
+}
+
+for (var i=0; i<10; i++) test();
+%OptimizeFunctionOnNextCall(test);
+assertEquals(41, test());
diff --git a/test/mjsunit/compiler/regress-deopt-call-as-function.js b/test/mjsunit/compiler/regress-deopt-call-as-function.js
new file mode 100644
index 00000000..c4080969
--- /dev/null
+++ b/test/mjsunit/compiler/regress-deopt-call-as-function.js
@@ -0,0 +1,62 @@
+// 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.
+
+// Test deoptimization after inlined call.
+
+function bar(a, b) {try { return a; } finally { } }
+
+function test_context() {
+ function foo(x) { return 42; }
+ var s, t;
+ for (var i = 0x7fff0000; i < 0x80000000; i++) {
+ bar(t = foo(i) ? bar(42 + i - i) : bar(0), s = i + t);
+ }
+ return s;
+}
+assertEquals(0x7fffffff + 42, test_context());
+
+
+function value_context() {
+ function foo(x) { return 42; }
+ var s, t;
+ for (var i = 0x7fff0000; i < 0x80000000; i++) {
+ bar(t = foo(i), s = i + t);
+ }
+ return s;
+}
+assertEquals(0x7fffffff + 42, value_context());
+
+
+function effect_context() {
+ function foo(x) { return 42; }
+ var s, t;
+ for (var i = 0x7fff0000; i < 0x80000000; i++) {
+ bar(foo(i), s = i + 42);
+ }
+ return s;
+}
+assertEquals(0x7fffffff + 42, effect_context());
diff --git a/test/mjsunit/compiler/regress-funarguments.js b/test/mjsunit/compiler/regress-funarguments.js
index cea40bc9..c913bd95 100644
--- a/test/mjsunit/compiler/regress-funarguments.js
+++ b/test/mjsunit/compiler/regress-funarguments.js
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
+
// Test function.arguments.
function A() {}
@@ -60,13 +62,16 @@ function hej(x) {
return o.g(x, "z");
}
-function stress() {
- for (var i=0; i<5000000; i++) o.g(i, "g");
- for (var j=0; j<5000000; j++) hej(j);
+function opt() {
+ for (var k=0; k<2; k++) {
+ for (var i=0; i<5; i++) o.g(i, "g");
+ for (var j=0; j<5; j++) hej(j);
+ }
+ %OptimizeFunctionOnNextCall(o.g);
+ %OptimizeFunctionOnNextCall(hej);
}
-stress();
-
+opt();
assertArrayEquals([0, "g"], o.g(0, "g"));
assertArrayEquals([1, "f"], o.g(1, "g"));
assertArrayEquals([0, "h"], hej(0));
@@ -74,8 +79,7 @@ assertArrayEquals([1, "f"], hej(1));
o = new B();
-stress();
-
+opt();
assertArrayEquals([0, "f"], o.g(0, "g"));
assertArrayEquals([1, "g"], o.g(1, "g"));
assertArrayEquals([0, "f"], hej(0));
diff --git a/test/mjsunit/compiler/regress-inline-callfunctionstub.js b/test/mjsunit/compiler/regress-inline-callfunctionstub.js
new file mode 100644
index 00000000..a39d26df
--- /dev/null
+++ b/test/mjsunit/compiler/regress-inline-callfunctionstub.js
@@ -0,0 +1,46 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+// Test inlined of calls-as-function two levels deep.
+function f() { return 42; }
+
+var o = {g : function () { return f(); } }
+function main(func) {
+ var v=0;
+ for (var i=0; i<1; i++) {
+ if (func()) v = 42;
+ }
+}
+
+main(o.g);
+main(o.g);
+main(o.g);
+%OptimizeFunctionOnNextCall(main);
+main(o.g);
+
diff --git a/test/mjsunit/compiler/regress-toint32.js b/test/mjsunit/compiler/regress-toint32.js
new file mode 100644
index 00000000..54c2f76d
--- /dev/null
+++ b/test/mjsunit/compiler/regress-toint32.js
@@ -0,0 +1,45 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --noenable-sse3
+
+var a = new Int32Array(1);
+var G = 0x80000000;
+
+function f(x) {
+ var v = x;
+ v = v + 1;
+ a[0] = v;
+ v = v - 1;
+ return v;
+}
+
+assertEquals(G, f(G));
+assertEquals(G, f(G));
+%OptimizeFunctionOnNextCall(f);
+assertEquals(G, f(G));
+
diff --git a/test/mjsunit/compiler/strict-recompile.js b/test/mjsunit/compiler/strict-recompile.js
new file mode 100644
index 00000000..96e8bcab
--- /dev/null
+++ b/test/mjsunit/compiler/strict-recompile.js
@@ -0,0 +1,51 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function foo() {
+ try {
+ var o = {};
+ Object.defineProperty(o, 'x', {value: 12, writable: false});
+ o.x = 13;
+ } catch(e) {
+ return true;
+ }
+ return false;
+}
+
+assertFalse(foo());
+
+function do_eval(str) {
+ "use strict";
+ return eval(str);
+}
+
+var eval_foo = do_eval('(' + foo + ')');
+for (var i = 0; i < 5; i++) assertTrue(eval_foo());
+%OptimizeFunctionOnNextCall(eval_foo);
+assertTrue(eval_foo());
diff --git a/test/mjsunit/const-redecl.js b/test/mjsunit/const-redecl.js
index 94597089..c0b97e6c 100644
--- a/test/mjsunit/const-redecl.js
+++ b/test/mjsunit/const-redecl.js
@@ -98,7 +98,8 @@ function TestAll(expected,s,opt_e) {
var msg = s;
if (opt_e) { e = opt_e; msg += "; " + opt_e; }
assertEquals(expected, TestLocal(s,e), "local:'" + msg + "'");
- assertEquals(expected, TestGlobal(s,e), "global:'" + msg + "'");
+ // Redeclarations of global consts do not throw, they are silently ignored.
+ assertEquals(42, TestGlobal(s, 42), "global:'" + msg + "'");
assertEquals(expected, TestContext(s,e), "context:'" + msg + "'");
}
@@ -218,3 +219,62 @@ TestAll(0, "var a,b,c,d,e,f,g,h; " + loop, "x");
// Test that const inside with behaves correctly.
TestAll(87, "with ({x:42}) { const x = 87; }", "x");
TestAll(undefined, "with ({x:42}) { const x; }", "x");
+
+
+// Additional tests for how various combinations of re-declarations affect
+// the values of the var/const in question.
+try {
+ eval("var undefined;");
+} catch (ex) {
+ assertUnreachable("undefined (1) has thrown");
+}
+
+var original_undef = undefined;
+var undefined = 1; // Should be silently ignored.
+assertEquals(original_undef, undefined, "undefined got overwritten");
+undefined = original_undef;
+
+var a; const a; const a = 1;
+assertEquals(1, a, "a has wrong value");
+a = 2;
+assertEquals(2, a, "a should be writable");
+
+var b = 1; const b = 2;
+assertEquals(2, b, "b has wrong value");
+
+var c = 1; const c = 2; const c = 3;
+assertEquals(3, c, "c has wrong value");
+
+const d = 1; const d = 2;
+assertEquals(1, d, "d has wrong value");
+
+const e = 1; var e = 2;
+assertEquals(1, e, "e has wrong value");
+
+const f = 1; const f;
+assertEquals(1, f, "f has wrong value");
+
+var g; const g = 1;
+assertEquals(1, g, "g has wrong value");
+g = 2;
+assertEquals(2, g, "g should be writable");
+
+const h; var h = 1;
+assertEquals(undefined,h, "h has wrong value");
+
+eval("Object.defineProperty(this, 'i', { writable: true });"
+ + "const i = 7;"
+ + "assertEquals(7, i, \"i has wrong value\");");
+
+var global = this;
+assertThrows(function() {
+ Object.defineProperty(global, 'j', { writable: true })
+}, TypeError);
+const j = 2; // This is what makes the function above throw, because the
+// const declaration gets hoisted and makes the property non-configurable.
+assertEquals(2, j, "j has wrong value");
+
+var k = 1; const k;
+// You could argue about the expected result here. For now, the winning
+// argument is that "const k;" is equivalent to "const k = undefined;".
+assertEquals(undefined, k, "k has wrong value");
diff --git a/test/mjsunit/count-based-osr.js b/test/mjsunit/count-based-osr.js
new file mode 100644
index 00000000..125c4e26
--- /dev/null
+++ b/test/mjsunit/count-based-osr.js
@@ -0,0 +1,38 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --count-based-interrupts --interrupt-budget=10 --weighted-back-edges --allow-natives-syntax
+
+// Test that OSR works properly when using count-based interrupting/profiling.
+
+function osr_this() {
+ var a = 1;
+ // Trigger OSR.
+ while (%GetOptimizationStatus(osr_this) == 2) {}
+ return a;
+}
+assertEquals(1, osr_this());
diff --git a/test/mjsunit/d8-os.js b/test/mjsunit/d8-os.js
index 56403268..239938cd 100644
--- a/test/mjsunit/d8-os.js
+++ b/test/mjsunit/d8-os.js
@@ -54,6 +54,8 @@ function str_error(str) {
if (this.os && os.system) {
+ // Ensure that we have a valid working directory.
+ os.chdir("/tmp");
try {
// Delete the dir if it is lying around from last time.
os.system("ls", [TEST_DIR]);
@@ -61,52 +63,53 @@ if (this.os && os.system) {
} catch (e) {
}
os.mkdirp(TEST_DIR);
- os.chdir(TEST_DIR);
try {
// Check the chdir worked.
os.system('ls', [TEST_DIR]);
// Simple create dir.
- os.mkdirp("dir");
+ os.mkdirp(TEST_DIR + "/dir");
// Create dir in dir.
- os.mkdirp("dir/foo");
+ os.mkdirp(TEST_DIR + "/dir/foo");
// Check that they are there.
- os.system('ls', ['dir/foo']);
+ os.system('ls', [TEST_DIR + '/dir/foo']);
// Check that we can detect when something is not there.
- assertThrows("os.system('ls', ['dir/bar']);", "dir not there");
+ assertThrows("os.system('ls', [TEST_DIR + '/dir/bar']);", "dir not there");
// Check that mkdirp makes intermediate directories.
- os.mkdirp("dir2/foo");
- os.system("ls", ["dir2/foo"]);
+ os.mkdirp(TEST_DIR + "/dir2/foo");
+ os.system("ls", [TEST_DIR + "/dir2/foo"]);
// Check that mkdirp doesn't mind if the dir is already there.
- os.mkdirp("dir2/foo");
- os.mkdirp("dir2/foo/");
+ os.mkdirp(TEST_DIR + "/dir2/foo");
+ os.mkdirp(TEST_DIR + "/dir2/foo/");
// Check that mkdirp can cope with trailing /
- os.mkdirp("dir3/");
- os.system("ls", ["dir3"]);
+ os.mkdirp(TEST_DIR + "/dir3/");
+ os.system("ls", [TEST_DIR + "/dir3"]);
// Check that we get an error if the name is taken by a file.
- os.system("sh", ["-c", "echo foo > file1"]);
- os.system("ls", ["file1"]);
- assertThrows("os.mkdirp('file1');", "mkdir over file1");
- assertThrows("os.mkdirp('file1/foo');", "mkdir over file2");
- assertThrows("os.mkdirp('file1/');", "mkdir over file3");
- assertThrows("os.mkdirp('file1/foo/');", "mkdir over file4");
+ os.system("sh", ["-c", "echo foo > " + TEST_DIR + "/file1"]);
+ os.system("ls", [TEST_DIR + "/file1"]);
+ assertThrows("os.mkdirp(TEST_DIR + '/file1');", "mkdir over file1");
+ assertThrows("os.mkdirp(TEST_DIR + '/file1/foo');", "mkdir over file2");
+ assertThrows("os.mkdirp(TEST_DIR + '/file1/');", "mkdir over file3");
+ assertThrows("os.mkdirp(TEST_DIR + '/file1/foo/');", "mkdir over file4");
// Create a dir we cannot read.
- os.mkdirp("dir4", 0);
+ os.mkdirp(TEST_DIR + "/dir4", 0);
// This test fails if you are root since root can read any dir.
- assertThrows("os.chdir('dir4');", "chdir dir4 I");
- os.rmdir("dir4");
- assertThrows("os.chdir('dir4');", "chdir dir4 II");
- // Set umask.
+ assertThrows("os.chdir(TEST_DIR + '/dir4');", "chdir dir4 I");
+ os.rmdir(TEST_DIR + "/dir4");
+ assertThrows("os.chdir(TEST_DIR + '/dir4');", "chdir dir4 II");
+
+ // Set umask. This changes the umask for the whole process and is
+ // the reason why the test cannot be run multi-threaded.
var old_umask = os.umask(0777);
// Create a dir we cannot read.
- os.mkdirp("dir5");
+ os.mkdirp(TEST_DIR + "/dir5");
// This test fails if you are root since root can read any dir.
- assertThrows("os.chdir('dir5');", "cd dir5 I");
- os.rmdir("dir5");
- assertThrows("os.chdir('dir5');", "chdir dir5 II");
+ assertThrows("os.chdir(TEST_DIR + '/dir5');", "cd dir5 I");
+ os.rmdir(TEST_DIR + "/dir5");
+ assertThrows("os.chdir(TEST_DIR + '/dir5');", "chdir dir5 II");
os.umask(old_umask);
- os.mkdirp("hest/fisk/../fisk/ged");
- os.system("ls", ["hest/fisk/ged"]);
+ os.mkdirp(TEST_DIR + "/hest/fisk/../fisk/ged");
+ os.system("ls", [TEST_DIR + "/hest/fisk/ged"]);
os.setenv("FOO", "bar");
var environment = os.system("printenv");
@@ -143,42 +146,43 @@ if (this.os && os.system) {
assertEquals("baz\n", os.system("echo", ["baz"]));
//}
}
+
+ // Too few args.
+ arg_error("os.umask();");
+ arg_error("os.system();");
+ arg_error("os.mkdirp();");
+ arg_error("os.chdir();");
+ arg_error("os.setenv();");
+ arg_error("os.rmdir();");
+
+ // Too many args.
+ arg_error("os.setenv('FOO=bar');");
+ arg_error("os.umask(0, 0);");
+ arg_error("os.system('ls', [], -1, -1, -1);");
+ arg_error("os.mkdirp('foo', 0, 0)");
+ arg_error("os.chdir('foo', 'bar')");
+ arg_error("os.rmdir('foo', 'bar');");
+
+ // Wrong kind of args.
+ arg_error("os.umask([]);");
+ arg_error("os.system('ls', 'foo');");
+ arg_error("os.system('ls', 123);");
+ arg_error("os.system('ls', [], 'foo');");
+ arg_error("os.system('ls', [], -1, 'foo');");
+ arg_error("os.mkdirp('foo', 'bar');");
+
+ // Test broken toString().
+ str_error("os.system(e);");
+ str_error("os.system('ls', [e]);");
+ str_error("os.system('ls', ['.', e]);");
+ str_error("os.system('ls', [e, '.']);");
+ str_error("os.mkdirp(e);");
+ str_error("os.setenv(e, 'goo');");
+ str_error("os.setenv('goo', e);");
+ str_error("os.chdir(e);");
+ str_error("os.rmdir(e);");
+
} finally {
os.system("rm", ["-r", TEST_DIR]);
}
-
- // Too few args.
- arg_error("os.umask();");
- arg_error("os.system();");
- arg_error("os.mkdirp();");
- arg_error("os.chdir();");
- arg_error("os.setenv();");
- arg_error("os.rmdir();");
-
- // Too many args.
- arg_error("os.setenv('FOO=bar');");
- arg_error("os.umask(0, 0);");
- arg_error("os.system('ls', [], -1, -1, -1);");
- arg_error("os.mkdirp('foo', 0, 0)");
- arg_error("os.chdir('foo', 'bar')");
- arg_error("os.rmdir('foo', 'bar');");
-
- // Wrong kind of args.
- arg_error("os.umask([]);");
- arg_error("os.system('ls', 'foo');");
- arg_error("os.system('ls', 123);");
- arg_error("os.system('ls', [], 'foo');");
- arg_error("os.system('ls', [], -1, 'foo');");
- arg_error("os.mkdirp('foo', 'bar');");
-
- // Test broken toString().
- str_error("os.system(e);");
- str_error("os.system('ls', [e]);");
- str_error("os.system('ls', ['.', e]);");
- str_error("os.system('ls', [e, '.']);");
- str_error("os.mkdirp(e);");
- str_error("os.setenv(e, 'goo');");
- str_error("os.setenv('goo', e);");
- str_error("os.chdir(e);");
- str_error("os.rmdir(e);");
}
diff --git a/test/mjsunit/date.js b/test/mjsunit/date.js
index a7f6cfa7..3e153aba 100644
--- a/test/mjsunit/date.js
+++ b/test/mjsunit/date.js
@@ -157,7 +157,7 @@ testToLocaleTimeString();
// Test that -0 is treated correctly in MakeDay.
var d = new Date();
assertDoesNotThrow("d.setDate(-0)");
-assertDoesNotThrow("new Date(-0, -0, -0, -0, -0, -0. -0)");
+assertDoesNotThrow("new Date(-0, -0, -0, -0, -0, -0, -0)");
assertDoesNotThrow("new Date(0x40000000, 0x40000000, 0x40000000," +
"0x40000000, 0x40000000, 0x40000000, 0x40000000)")
assertDoesNotThrow("new Date(-0x40000001, -0x40000001, -0x40000001," +
@@ -178,7 +178,7 @@ assertTrue(isNaN(Date.UTC(-271821, 3, 19, 23, 59, 59, 999)));
assertTrue(isNaN(Date.UTC(-271821, 3, 19)));
-// Test creation of large date values.
+// Test creation with large date values.
d = new Date(1969, 12, 1, 99999999999);
assertTrue(isNaN(d.getTime()));
d = new Date(1969, 12, 1, -99999999999);
@@ -187,6 +187,18 @@ d = new Date(1969, 12, 1, Infinity);
assertTrue(isNaN(d.getTime()));
d = new Date(1969, 12, 1, -Infinity);
assertTrue(isNaN(d.getTime()));
+d = new Date(1969, 12, 1, 0);
+d.setTime(Math.pow(2, 64));
+assertTrue(isNaN(d.getTime()));
+d = new Date(1969, 12, 1, 0);
+d.setTime(Math.pow(-2, 64));
+assertTrue(isNaN(d.getTime()));
+
+
+// Test creation with obscure date values.
+assertEquals(8640000000000000, Date.UTC(1970, 0, 1 + 100000001, -24));
+assertEquals(-8640000000000000, Date.UTC(1970, 0, 1 - 100000001, 24));
+
// Parsing ES5 ISO-8601 dates.
// When TZ is omitted, it defaults to 'Z' meaning UTC.
diff --git a/test/mjsunit/debug-break-inline.js b/test/mjsunit/debug-break-inline.js
new file mode 100644
index 00000000..4418fa8d
--- /dev/null
+++ b/test/mjsunit/debug-break-inline.js
@@ -0,0 +1,100 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// This test tests that deoptimization due to debug breaks works for
+// inlined functions where the full-code is generated before the
+// debugger is attached.
+//
+//See http://code.google.com/p/chromium/issues/detail?id=105375
+
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug;
+
+var count = 0;
+var break_count = 0;
+
+// Debug event listener which sets a breakpoint first time it is hit
+// and otherwise counts break points hit and checks that the expected
+// state is reached.
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ break_count++;
+ if (break_count == 1) {
+ Debug.setBreakPoint(g, 3);
+
+ for (var i = 0; i < exec_state.frameCount(); i++) {
+ var frame = exec_state.frame(i);
+ // When function f is optimized (1 means YES, see runtime.cc) we
+ // expect an optimized frame for f and g.
+ if (%GetOptimizationStatus(f) == 1) {
+ if (i == 1) {
+ assertTrue(frame.isOptimizedFrame());
+ assertTrue(frame.isInlinedFrame());
+ assertEquals(4 - i, frame.inlinedFrameIndex());
+ } else if (i == 2) {
+ assertTrue(frame.isOptimizedFrame());
+ assertFalse(frame.isInlinedFrame());
+ } else {
+ assertFalse(frame.isOptimizedFrame());
+ assertFalse(frame.isInlinedFrame());
+ }
+ }
+ }
+ }
+ }
+}
+
+function f() {
+ g();
+}
+
+function g() {
+ count++;
+ h();
+ var b = 1; // Break point is set here.
+}
+
+function h() {
+ debugger;
+}
+
+f();f();f();
+%OptimizeFunctionOnNextCall(f);
+f();
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+f();
+
+assertEquals(5, count);
+assertEquals(2, break_count);
+
+// Get rid of the debug event listener.
+Debug.setListener(null);
diff --git a/test/mjsunit/debug-evaluate-locals-optimized-double.js b/test/mjsunit/debug-evaluate-locals-optimized-double.js
index 8447df53..cf25c0c0 100644
--- a/test/mjsunit/debug-evaluate-locals-optimized-double.js
+++ b/test/mjsunit/debug-evaluate-locals-optimized-double.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --expose-debug-as debug --allow-natives-syntax
+// Flags: --expose-debug-as debug --expose-gc --allow-natives-syntax --inline-construct
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
@@ -34,6 +34,27 @@ var exception = false;
var testingConstructCall = false;
+var input = [
+ {a: 1, b: 2},
+ {a: 3, b: 4},
+ {a: 5, b: 6},
+ {a: 7, b: 8},
+ {a: 9, b: 10}
+];
+
+var expected = [
+ { locals: {a0: 1.01, b0: 2.02}, args: { names: ["i", "x0", "y0"], values: [0, 3.03, 4.04] } },
+ { locals: {a1: 3.03, b1: 4.04}, args: { names: ["i", "x1", "y1"], values: [1, 5.05, 6.06] } },
+ { locals: {a2: 5.05, b2: 6.06}, args: { names: ["i"], values: [2] } },
+ { locals: {a3: 7.07, b3: 8.08}, args: { names: ["i", "x3", "y3", "z3"],
+ values: [3, 9.09, 10.10, undefined] }
+ },
+ { locals: {a4: 9.09, b4: 10.10}, args: { names: ["i", "x4", "y4"], values: [4, 11.11, 12.12] } }
+];
+
+function arraySum(arr) {
+ return arr.reduce(function (a, b) { return a + b; }, 0);
+}
function listener(event, exec_state, event_data, data) {
try {
@@ -44,42 +65,63 @@ function listener(event, exec_state, event_data, data) {
for (var i = 0; i < exec_state.frameCount(); i++) {
var frame = exec_state.frame(i);
if (i < exec_state.frameCount() - 1) {
- var expected_a = i * 2 + 1 + (i * 2 + 1) / 100;
- var expected_b = i * 2 + 2 + (i * 2 + 2) / 100;
- var expected_x = (i + 1) * 2 + 1 + ((i + 1) * 2 + 1) / 100;
- var expected_y = (i + 1) * 2 + 2 + ((i + 1) * 2 + 2) / 100;
-
- // All frames except the bottom one has normal variables a and b.
- var a = ('a' === frame.localName(0)) ? 0 : 1;
- var b = 1 - a;
- assertEquals('a', frame.localName(a));
- assertEquals('b', frame.localName(b));
- assertEquals(expected_a, frame.localValue(a).value());
- assertEquals(expected_b, frame.localValue(b).value());
-
- // All frames except the bottom one has arguments variables x and y.
- assertEquals('x', frame.argumentName(0));
- assertEquals('y', frame.argumentName(1));
- assertEquals(expected_x, frame.argumentValue(0).value());
- assertEquals(expected_y, frame.argumentValue(1).value());
+ var expected_args = expected[i].args;
+ var expected_locals = expected[i].locals;
+
+ // All frames except the bottom one have expected locals.
+ var locals = {};
+ for (var j = 0; j < frame.localCount(); j++) {
+ locals[frame.localName(j)] = frame.localValue(j).value();
+ }
+ assertPropertiesEqual(expected_locals, locals);
+
+ // All frames except the bottom one have expected arguments.
+ for (var j = 0; j < expected_args.names.length; j++) {
+ assertEquals(expected_args.names[j], frame.argumentName(j));
+ assertEquals(expected_args.values[j], frame.argumentValue(j).value());
+ }
// All frames except the bottom one have two scopes.
assertEquals(2, frame.scopeCount());
assertEquals(debug.ScopeType.Local, frame.scope(0).scopeType());
assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
- assertEquals(expected_a, frame.scope(0).scopeObject().value()['a']);
- assertEquals(expected_b, frame.scope(0).scopeObject().value()['b']);
- assertEquals(expected_x, frame.scope(0).scopeObject().value()['x']);
- assertEquals(expected_y, frame.scope(0).scopeObject().value()['y']);
+
+ Object.keys(expected_locals).forEach(function (name) {
+ assertEquals(expected_locals[name], frame.scope(0).scopeObject().value()[name]);
+ });
+
+ for (var j = 0; j < expected_args.names.length; j++) {
+ var arg_name = expected_args.names[j];
+ var arg_value = expected_args.values[j];
+ assertEquals(arg_value, frame.scope(0).scopeObject().value()[arg_name]);
+ }
// Evaluate in the inlined frame.
- assertEquals(expected_a, frame.evaluate('a').value());
- assertEquals(expected_x, frame.evaluate('x').value());
- assertEquals(expected_x, frame.evaluate('arguments[0]').value());
- assertEquals(expected_a + expected_b + expected_x + expected_y,
- frame.evaluate('a + b + x + y').value());
- assertEquals(expected_x + expected_y,
- frame.evaluate('arguments[0] + arguments[1]').value());
+ Object.keys(expected_locals).forEach(function (name) {
+ assertEquals(expected_locals[name], frame.evaluate(name).value());
+ });
+
+ for (var j = 0; j < expected_args.names.length; j++) {
+ var arg_name = expected_args.names[j];
+ var arg_value = expected_args.values[j];
+ assertEquals(arg_value, frame.evaluate(arg_name).value());
+ assertEquals(arg_value, frame.evaluate('arguments['+j+']').value());
+ }
+
+ var expected_args_sum = arraySum(expected_args.values);
+ var expected_locals_sum =
+ arraySum(Object.keys(expected_locals).
+ map(function (k) { return expected_locals[k]; }));
+
+ assertEquals(expected_locals_sum + expected_args_sum,
+ frame.evaluate(Object.keys(expected_locals).join('+') + ' + ' +
+ expected_args.names.join('+')).value());
+
+ var arguments_sum = expected_args.names.map(function(_, idx) {
+ return "arguments[" + idx + "]";
+ }).join('+');
+ assertEquals(expected_args_sum,
+ frame.evaluate(arguments_sum).value());
} else {
// The bottom frame only have the global scope.
assertEquals(1, frame.scopeCount());
@@ -98,7 +140,13 @@ function listener(event, exec_state, event_data, data) {
}
// Check for construct call.
- assertEquals(testingConstructCall && i == 4, frame.isConstructCall());
+ if (i == 4) {
+ assertEquals(testingConstructCall, frame.isConstructCall());
+ } else if (i == 2) {
+ assertTrue(frame.isConstructCall());
+ } else {
+ assertFalse(frame.isConstructCall());
+ }
// When function f is optimized (1 means YES, see runtime.cc) we
// expect an optimized frame for f with g1, g2 and g3 inlined.
@@ -121,65 +169,70 @@ function listener(event, exec_state, event_data, data) {
listenerComplete = true;
}
} catch (e) {
- exception = e
+ exception = e.toString() + e.stack;
};
};
-f();f();f();
+for (var i = 0; i < 4; i++) f(input.length - 1, 11.11, 12.12);
%OptimizeFunctionOnNextCall(f);
-f();
+f(input.length - 1, 11.11, 12.12);
// Add the debug event listener.
Debug.setListener(listener);
-function h(x, y) {
- var a = 1;
- var b = 2;
- a = a + a / 100;
- b = b + b / 100;
+function h(i, x0, y0) {
+ var a0 = input[i].a;
+ var b0 = input[i].b;
+ a0 = a0 + a0 / 100;
+ b0 = b0 + b0 / 100;
debugger; // Breakpoint.
};
-function g3(x, y) {
- var a = 3;
- var b = 4;
- a = a + a / 100;
- b = b + b / 100;
- h(a, b);
- return a+b;
+function g3(i, x1, y1) {
+ var a1 = input[i].a;
+ var b1 = input[i].b;
+ a1 = a1 + a1 / 100;
+ b1 = b1 + b1 / 100;
+ h(i - 1, a1, b1);
+ return a1+b1;
};
-function g2(x, y) {
- var a = 5;
- var b = 6;
- a = a + a / 100;
- b = b + b / 100;
- g3(a, b);
+function g2(i) {
+ var a2 = input[i].a;
+ var b2 = input[i].b;
+ a2 = a2 + a2 / 100;
+ b2 = b2 + b2 / 100;
+ g3(i - 1, a2, b2);
};
-function g1(x, y) {
- var a = 7;
- var b = 8;
- a = a + a / 100;
- b = b + b / 100;
- g2(a, b);
+function g1(i, x3, y3, z3) {
+ var a3 = input[i].a;
+ var b3 = input[i].b;
+ a3 = a3 + a3 / 100;
+ b3 = b3 + b3 / 100;
+ new g2(i - 1, a3, b3);
};
-function f(x, y) {
- var a = 9;
- var b = 10;
- a = a + a / 100;
- b = b + b / 100;
- g1(a, b);
+function f(i, x4, y4) {
+ var a4 = input[i].a;
+ var b4 = input[i].b;
+ a4 = a4 + a4 / 100;
+ b4 = b4 + b4 / 100;
+ g1(i - 1, a4, b4);
};
// Test calling f normally and as a constructor.
-f(11.11, 12.12);
+f(input.length - 1, 11.11, 12.12);
+f(input.length - 1, 11.11, 12.12, "");
testingConstructCall = true;
-new f(11.11, 12.12);
+new f(input.length - 1, 11.11, 12.12);
+new f(input.length - 1, 11.11, 12.12, "");
-// Make sure that the debug event listener vas invoked.
+// Make sure that the debug event listener was invoked.
assertFalse(exception, "exception in listener " + exception)
assertTrue(listenerComplete);
+//Throw away type information for next run.
+gc();
+
Debug.setListener(null);
diff --git a/test/mjsunit/debug-evaluate-locals-optimized.js b/test/mjsunit/debug-evaluate-locals-optimized.js
index c3cd5eb2..c88a683a 100644
--- a/test/mjsunit/debug-evaluate-locals-optimized.js
+++ b/test/mjsunit/debug-evaluate-locals-optimized.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --expose-debug-as debug --allow-natives-syntax
+// Flags: --expose-debug-as debug --expose-gc --allow-natives-syntax --inline-construct
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
@@ -34,6 +34,17 @@ var exception = false;
var testingConstructCall = false;
+var expected = [
+ { locals: {a0: 1, b0: 2}, args: { names: ["i", "x0", "y0"], values: [0, 3, 4] } },
+ { locals: {a1: 3, b1: 4}, args: { names: ["i", "x1", "y1"], values: [1, 5, 6] } },
+ { locals: {a2: 5, b2: 6}, args: { names: ["i"], values: [2] } },
+ { locals: {a3: 7, b3: 8}, args: { names: ["i", "x3", "y3", "z3"], values: [3, 9, 10, undefined] } },
+ { locals: {a4: 9, b4: 10}, args: { names: ["i", "x4", "y4"], values: [4, 11, 12] } }
+];
+
+function arraySum(arr) {
+ return arr.reduce(function (a, b) { return a + b; }, 0);
+}
function listener(event, exec_state, event_data, data) {
try {
@@ -44,42 +55,63 @@ function listener(event, exec_state, event_data, data) {
for (var i = 0; i < exec_state.frameCount(); i++) {
var frame = exec_state.frame(i);
if (i < exec_state.frameCount() - 1) {
- var expected_a = i * 2 + 1;
- var expected_b = i * 2 + 2;
- var expected_x = (i + 1) * 2 + 1;
- var expected_y = (i + 1) * 2 + 2;
-
- // All frames except the bottom one has normal variables a and b.
- var a = ('a' === frame.localName(0)) ? 0 : 1;
- var b = 1 - a;
- assertEquals('a', frame.localName(a));
- assertEquals('b', frame.localName(b));
- assertEquals(expected_a, frame.localValue(a).value());
- assertEquals(expected_b, frame.localValue(b).value());
-
- // All frames except the bottom one has arguments variables x and y.
- assertEquals('x', frame.argumentName(0));
- assertEquals('y', frame.argumentName(1));
- assertEquals(expected_x, frame.argumentValue(0).value());
- assertEquals(expected_y, frame.argumentValue(1).value());
+ var expected_args = expected[i].args;
+ var expected_locals = expected[i].locals;
+
+ // All frames except the bottom one have expected locals.
+ var locals = {};
+ for (var j = 0; j < frame.localCount(); j++) {
+ locals[frame.localName(j)] = frame.localValue(j).value();
+ }
+ assertPropertiesEqual(expected_locals, locals);
+
+ // All frames except the bottom one have expected arguments.
+ for (var j = 0; j < expected_args.names.length; j++) {
+ assertEquals(expected_args.names[j], frame.argumentName(j));
+ assertEquals(expected_args.values[j], frame.argumentValue(j).value());
+ }
// All frames except the bottom one have two scopes.
assertEquals(2, frame.scopeCount());
assertEquals(debug.ScopeType.Local, frame.scope(0).scopeType());
assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
- assertEquals(expected_a, frame.scope(0).scopeObject().value()['a']);
- assertEquals(expected_b, frame.scope(0).scopeObject().value()['b']);
- assertEquals(expected_x, frame.scope(0).scopeObject().value()['x']);
- assertEquals(expected_y, frame.scope(0).scopeObject().value()['y']);
+
+ Object.keys(expected_locals).forEach(function (name) {
+ assertEquals(expected_locals[name], frame.scope(0).scopeObject().value()[name]);
+ });
+
+ for (var j = 0; j < expected_args.names.length; j++) {
+ var arg_name = expected_args.names[j];
+ var arg_value = expected_args.values[j];
+ assertEquals(arg_value, frame.scope(0).scopeObject().value()[arg_name]);
+ }
// Evaluate in the inlined frame.
- assertEquals(expected_a, frame.evaluate('a').value());
- assertEquals(expected_x, frame.evaluate('x').value());
- assertEquals(expected_x, frame.evaluate('arguments[0]').value());
- assertEquals(expected_a + expected_b + expected_x + expected_y,
- frame.evaluate('a + b + x + y').value());
- assertEquals(expected_x + expected_y,
- frame.evaluate('arguments[0] + arguments[1]').value());
+ Object.keys(expected_locals).forEach(function (name) {
+ assertEquals(expected_locals[name], frame.evaluate(name).value());
+ });
+
+ for (var j = 0; j < expected_args.names.length; j++) {
+ var arg_name = expected_args.names[j];
+ var arg_value = expected_args.values[j];
+ assertEquals(arg_value, frame.evaluate(arg_name).value());
+ assertEquals(arg_value, frame.evaluate('arguments['+j+']').value());
+ }
+
+ var expected_args_sum = arraySum(expected_args.values);
+ var expected_locals_sum =
+ arraySum(Object.keys(expected_locals).
+ map(function (k) { return expected_locals[k]; }));
+
+ assertEquals(expected_locals_sum + expected_args_sum,
+ frame.evaluate(Object.keys(expected_locals).join('+') + ' + ' +
+ expected_args.names.join('+')).value());
+
+ var arguments_sum = expected_args.names.map(function(_, idx) {
+ return "arguments[" + idx + "]";
+ }).join('+');
+ assertEquals(expected_args_sum,
+ frame.evaluate(arguments_sum).value());
} else {
// The bottom frame only have the global scope.
assertEquals(1, frame.scopeCount());
@@ -98,7 +130,13 @@ function listener(event, exec_state, event_data, data) {
}
// Check for construct call.
- assertEquals(testingConstructCall && i == 4, frame.isConstructCall());
+ if (i == 4) {
+ assertEquals(testingConstructCall, frame.isConstructCall());
+ } else if (i == 2) {
+ assertTrue(frame.isConstructCall());
+ } else {
+ assertFalse(frame.isConstructCall());
+ }
// When function f is optimized (1 means YES, see runtime.cc) we
// expect an optimized frame for f with g1, g2 and g3 inlined.
@@ -121,54 +159,59 @@ function listener(event, exec_state, event_data, data) {
listenerComplete = true;
}
} catch (e) {
- exception = e.stack;
+ exception = e.toString() + e.stack;
};
};
-f();f();f();
+for (var i = 0; i < 4; i++) f(expected.length - 1, 11, 12);
%OptimizeFunctionOnNextCall(f);
-f();
+f(expected.length - 1, 11, 12);
// Add the debug event listener.
Debug.setListener(listener);
-function h(x, y) {
- var a = 1;
- var b = 2;
+function h(i, x0, y0) {
+ var a0 = expected[i].locals.a0;
+ var b0 = expected[i].locals.b0;
debugger; // Breakpoint.
-};
-
-function g3(x, y) {
- var a = 3;
- var b = 4;
- h(a, b);
-};
-
-function g2(x, y) {
- var a = 5;
- var b = 6;
- g3(a, b);
-};
-
-function g1(x, y) {
- var a = 7;
- var b = 8;
- g2(a, b);
-};
-
-function f(x, y) {
- var a = 9;
- var b = 10;
- g1(a, b);
-};
+}
+
+function g3(i, x1, y1) {
+ var a1 = expected[i].locals.a1;
+ var b1 = expected[i].locals.b1;
+ h(i - 1, a1, b1);
+}
+
+function g2(i) {
+ var a2 = expected[i].locals.a2;
+ var b2 = expected[i].locals.b2;
+ g3(i - 1, a2, b2);
+}
+
+function g1(i, x3, y3, z3) {
+ var a3 = expected[i].locals.a3;
+ var b3 = expected[i].locals.b3;
+ new g2(i - 1, a3, b3);
+}
+
+function f(i, x4, y4) {
+ var a4 = expected[i].locals.a4;
+ var b4 = expected[i].locals.b4;
+ g1(i - 1, a4, b4);
+}
// Test calling f normally and as a constructor.
-f(11, 12);
+f(expected.length - 1, 11, 12);
+f(expected.length - 1, 11, 12, 0);
testingConstructCall = true;
-new f(11, 12);
+new f(expected.length - 1, 11, 12);
+new f(expected.length - 1, 11, 12, 0);
-// Make sure that the debug event listener vas invoked.
+// Make sure that the debug event listener was invoked.
assertFalse(exception, "exception in listener " + exception)
assertTrue(listenerComplete);
+// Throw away type information for next run.
+gc();
+
Debug.setListener(null);
diff --git a/test/mjsunit/debug-scopes.js b/test/mjsunit/debug-scopes.js
index 1c23b0bf..942bd2bb 100644
--- a/test/mjsunit/debug-scopes.js
+++ b/test/mjsunit/debug-scopes.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// 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:
@@ -25,13 +25,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --expose-debug-as debug
+// Flags: --expose-debug-as debug --allow-natives-syntax
// The functions used for testing backtraces. They are at the top to make the
// testing of source line/column easier.
-
// Get the Debug object exposed from the debug context global object.
-Debug = debug.Debug;
+var Debug = debug.Debug;
var test_name;
var listener_delegate;
@@ -439,6 +438,26 @@ with(with_object) {
EndTest();
+// With block in function that is marked for optimization while being executed.
+BeginTest("With 7");
+
+function with_7() {
+ with({}) {
+ %OptimizeFunctionOnNextCall(with_7);
+ debugger;
+ }
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.With,
+ debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({}, 0, exec_state);
+};
+with_7();
+EndTest();
+
+
// Simple closure formed by returning an inner function referering the outer
// functions arguments.
BeginTest("Closure 1");
@@ -950,6 +969,28 @@ try {
EndTest();
+// Catch block in function that is marked for optimization while being executed.
+BeginTest("Catch block 7");
+function catch_block_7() {
+ %OptimizeFunctionOnNextCall(catch_block_7);
+ try {
+ throw 'Exception';
+ } catch (e) {
+ debugger;
+ }
+};
+
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Catch,
+ debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({e:'Exception'}, 0, exec_state);
+};
+catch_block_7();
+EndTest();
+
+
assertEquals(begin_test_count, break_count,
'one or more tests did not enter the debugger');
assertEquals(begin_test_count, end_test_count,
diff --git a/test/mjsunit/debug-set-script-source.js b/test/mjsunit/debug-set-script-source.js
new file mode 100644
index 00000000..34ae8488
--- /dev/null
+++ b/test/mjsunit/debug-set-script-source.js
@@ -0,0 +1,64 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+var script_number = 0;
+var script_names = [];
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.BeforeCompile) {
+ event_data.script().setSource(event_data.script().source() +
+ " //@ sourceURL=proper_location_" + (++script_number));
+ } else if (event == Debug.DebugEvent.AfterCompile) {
+ try {
+ event_data.script().setSource("a=1 //@ sourceURL=wrong_location");
+ } catch(e) {
+ exception = e;
+ }
+ script_names.push(event_data.script().name());
+ }
+};
+
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+// Compile different sources.
+eval('a=1');
+eval('(function(){})');
+
+assertEquals(2, script_names.length);
+assertEquals("proper_location_1", script_names[0]);
+assertEquals("proper_location_2", script_names[1]);
+
+assertEquals("illegal access", exception);
+
+Debug.setListener(null);
diff --git a/test/mjsunit/debug-step-3.js b/test/mjsunit/debug-step-3.js
new file mode 100644
index 00000000..9cac0f56
--- /dev/null
+++ b/test/mjsunit/debug-step-3.js
@@ -0,0 +1,94 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+
+// This test tests that full code compiled without debug break slots
+// is recompiled with debug break slots when debugging is started.
+
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+var bp;
+var done = false;
+var step_count = 0;
+var set_bp = false
+
+// Debug event listener which steps until the global variable done is true.
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ if (!done) exec_state.prepareStep(Debug.StepAction.StepNext);
+ step_count++;
+ }
+};
+
+// Set the global variables state to prpare the stepping test.
+function prepare_step_test() {
+ done = false;
+ step_count = 0;
+}
+
+// Test function to step through.
+function f() {
+ var a = 0;
+ if (set_bp) { bp = Debug.setBreakPoint(f, 3); }
+ var i = 1;
+ var j = 2;
+ done = true;
+};
+
+prepare_step_test();
+f();
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+// Make f set a breakpoint with an activation on the stack.
+prepare_step_test();
+set_bp = true;
+f();
+// TODO(1782): Fix issue to bring back this assert.
+//assertEquals(4, step_count);
+Debug.clearBreakPoint(bp);
+
+// Set a breakpoint on the first var statement (line 1).
+set_bp = false;
+bp = Debug.setBreakPoint(f, 3);
+
+// Step through the function ensuring that the var statements are hit as well.
+prepare_step_test();
+f();
+assertEquals(4, step_count);
+
+// Clear the breakpoint and check that no stepping happens.
+Debug.clearBreakPoint(bp);
+prepare_step_test();
+f();
+assertEquals(0, step_count);
+
+// Get rid of the debug event listener.
+Debug.setListener(null);
diff --git a/test/mjsunit/debug-stepin-accessor.js b/test/mjsunit/debug-stepin-accessor.js
index 2c9c8c32..70acd5ef 100644
--- a/test/mjsunit/debug-stepin-accessor.js
+++ b/test/mjsunit/debug-stepin-accessor.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -112,8 +112,8 @@ function testGetter1_2() {
function testGetter1_3() {
expected_function_name = 'getter1';
expected_source_line_text = ' return this.name; // getter 1';
- debugger;
for (var i = 1; i < 2; i++) {
+ debugger;
var x = c['getter' + i];
}
}
diff --git a/test/mjsunit/debug-stepin-function-call.js b/test/mjsunit/debug-stepin-function-call.js
index 385fcb2f..3b5240c9 100644
--- a/test/mjsunit/debug-stepin-function-call.js
+++ b/test/mjsunit/debug-stepin-function-call.js
@@ -135,8 +135,15 @@ function apply4() {
var yetAnotherLocal = 10;
}
+// Test step into bound function.
+function bind1() {
+ var bound = g.bind(null, 3);
+ debugger;
+ bound();
+}
+
var testFunctions =
- [call1, call2, call3, call4, apply1, apply2, apply3, apply4];
+ [call1, call2, call3, call4, apply1, apply2, apply3, apply4, bind1];
for (var i = 0; i < testFunctions.length; i++) {
state = 0;
@@ -145,5 +152,13 @@ for (var i = 0; i < testFunctions.length; i++) {
assertEquals(3, state);
}
+// Test global bound function.
+state = 0;
+var globalBound = g.bind(null, 3);
+debugger;
+globalBound();
+assertNull(exception);
+assertEquals(3, state);
+
// Get rid of the debug event listener.
Debug.setListener(null); \ No newline at end of file
diff --git a/test/mjsunit/debug-stepout-scope.js b/test/mjsunit/debug-stepout-scope.js
new file mode 100644
index 00000000..9c040da9
--- /dev/null
+++ b/test/mjsunit/debug-stepout-scope.js
@@ -0,0 +1,423 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug --expose-natives-as=builtins
+
+// Check that the ScopeIterator can properly recreate the scope at
+// every point when stepping through functions.
+
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ // Access scope details.
+ var scope_count = exec_state.frame().scopeCount();
+ for (var i = 0; i < scope_count; i++) {
+ var scope = exec_state.frame().scope(i);
+ // assertTrue(scope.isScope());
+ scope.scopeType();
+ scope.scopeObject();
+ }
+
+ // Do steps until we reach the global scope again.
+ if (true) {
+ exec_state.prepareStep(Debug.StepAction.StepInMin, 1);
+ }
+ }
+}
+
+Debug.setListener(listener);
+
+
+function test1() {
+ debugger;
+ with ({x:1}) {
+ x = 2;
+ }
+}
+test1();
+
+
+function test2() {
+ if (true) {
+ with ({}) {
+ debugger;
+ }
+ } else {
+ with ({}) {
+ return 10;
+ }
+ }
+}
+test2();
+
+
+function test3() {
+ if (true) {
+ debugger;
+ } else {
+ with ({}) {
+ return 10;
+ }
+ }
+}
+test3();
+
+
+function test4() {
+ debugger;
+ with ({x:1}) x = 1
+}
+test4();
+
+
+function test5() {
+ debugger;
+ var dummy = 1;
+ with ({}) {
+ with ({}) {
+ dummy = 2;
+ }
+ }
+ dummy = 3;
+}
+test5();
+
+
+function test6() {
+ debugger;
+ try {
+ throw 'stuff';
+ } catch (e) {
+ e = 1;
+ }
+}
+test6();
+
+
+function test7() {
+ debugger;
+ function foo() {}
+}
+test7();
+
+
+function test8() {
+ debugger;
+ (function foo() {})();
+}
+test8();
+
+
+var q = 42;
+var prefixes = [ "debugger; ",
+ "if (false) { try { throw 0; } catch(x) { return x; } }; debugger; " ];
+var bodies = [ "1",
+ "1 ",
+ "1;",
+ "1; ",
+ "q",
+ "q ",
+ "q;",
+ "q; ",
+ "try { throw 'stuff' } catch (e) { e = 1; }",
+ "try { throw 'stuff' } catch (e) { e = 1; } ",
+ "try { throw 'stuff' } catch (e) { e = 1; };",
+ "try { throw 'stuff' } catch (e) { e = 1; }; " ];
+var with_bodies = [ "with ({}) {}",
+ "with ({x:1}) x",
+ "with ({x:1}) x = 1",
+ "with ({x:1}) x ",
+ "with ({x:1}) x = 1 ",
+ "with ({x:1}) x;",
+ "with ({x:1}) x = 1;",
+ "with ({x:1}) x; ",
+ "with ({x:1}) x = 1; " ];
+
+
+function test9() {
+ debugger;
+ for (var i = 0; i < prefixes.length; ++i) {
+ var pre = prefixes[i];
+ for (var j = 0; j < bodies.length; ++j) {
+ var body = bodies[j];
+ eval(pre + body);
+ eval("'use strict'; " + pre + body);
+ }
+ for (var j = 0; j < with_bodies.length; ++j) {
+ var body = with_bodies[j];
+ eval(pre + body);
+ }
+ }
+}
+test9();
+
+
+function test10() {
+ debugger;
+ with ({}) {
+ return 10;
+ }
+}
+test10();
+
+
+function test11() {
+ debugger;
+ try {
+ throw 'stuff';
+ } catch (e) {
+ return 10;
+ }
+}
+test11();
+
+
+// Test global eval and function constructor.
+for (var i = 0; i < prefixes.length; ++i) {
+ var pre = prefixes[i];
+ for (var j = 0; j < bodies.length; ++j) {
+ var body = bodies[j];
+ eval(pre + body);
+ eval("'use strict'; " + pre + body);
+ Function(pre + body)();
+ }
+ for (var j = 0; j < with_bodies.length; ++j) {
+ var body = with_bodies[j];
+ eval(pre + body);
+ Function(pre + body)();
+ }
+}
+
+
+try {
+ with({}) {
+ debugger;
+ eval("{}$%:^");
+ }
+} catch(e) {
+ nop();
+}
+
+// Return from function constructed with Function constructor.
+var anon = 12;
+for (var i = 0; i < prefixes.length; ++i) {
+ var pre = prefixes[i];
+ Function(pre + "return 42")();
+ Function(pre + "return 42 ")();
+ Function(pre + "return 42;")();
+ Function(pre + "return 42; ")();
+ Function(pre + "return anon")();
+ Function(pre + "return anon ")();
+ Function(pre + "return anon;")();
+ Function(pre + "return anon; ")();
+}
+
+
+function nop() {}
+
+
+function stress() {
+ debugger;
+
+ L: with ({x:12}) {
+ break L;
+ }
+
+
+ with ({x: 'outer'}) {
+ label: {
+ with ({x: 'inner'}) {
+ break label;
+ }
+ }
+ }
+
+
+ with ({x: 'outer'}) {
+ label: {
+ with ({x: 'inner'}) {
+ break label;
+ }
+ }
+ nop();
+ }
+
+
+ with ({x: 'outer'}) {
+ label: {
+ with ({x: 'middle'}) {
+ with ({x: 'inner'}) {
+ break label;
+ }
+ }
+ }
+ }
+
+
+ with ({x: 'outer'}) {
+ label: {
+ with ({x: 'middle'}) {
+ with ({x: 'inner'}) {
+ break label;
+ }
+ }
+ }
+ nop();
+ }
+
+
+ with ({x: 'outer'}) {
+ for (var i = 0; i < 3; ++i) {
+ with ({x: 'inner' + i}) {
+ continue;
+ }
+ }
+ }
+
+
+ with ({x: 'outer'}) {
+ label: for (var i = 0; i < 3; ++i) {
+ with ({x: 'middle' + i}) {
+ for (var j = 0; j < 3; ++j) {
+ with ({x: 'inner' + j}) {
+ continue label;
+ }
+ }
+ }
+ }
+ }
+
+
+ with ({x: 'outer'}) {
+ try {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ } catch (e) {
+ }
+ }
+
+
+ with ({x: 'outer'}) {
+ try {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ } catch (e) {
+ nop();
+ }
+ }
+
+
+ with ({x: 'outer'}) {
+ try {
+ with ({x: 'middle'}) {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ }
+ } catch (e) {
+ }
+ }
+
+
+ try {
+ with ({x: 'outer'}) {
+ try {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ } finally {
+ }
+ }
+ } catch (e) {
+ }
+
+
+ try {
+ with ({x: 'outer'}) {
+ try {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ } finally {
+ nop();
+ }
+ }
+ } catch (e) {
+ }
+
+
+ function stress1() {
+ with ({x:12}) {
+ return x;
+ }
+ }
+ stress1();
+
+
+ function stress2() {
+ with ({x: 'outer'}) {
+ with ({x: 'inner'}) {
+ return x;
+ }
+ }
+ }
+ stress2();
+
+ function stress3() {
+ try {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ } catch (e) {
+ return e;
+ }
+ }
+ stress3();
+
+
+ function stress4() {
+ try {
+ with ({x: 'inner'}) {
+ throw 0;
+ }
+ } catch (e) {
+ with ({x: 'inner'}) {
+ return e;
+ }
+ }
+ }
+ stress4();
+
+}
+stress();
+
+
+// With block as the last(!) statement in global code.
+with ({}) { debugger; } \ No newline at end of file
diff --git a/test/mjsunit/element-kind.js b/test/mjsunit/element-kind.js
deleted file mode 100644
index 48a029f2..00000000
--- a/test/mjsunit/element-kind.js
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax
-// Test element kind of objects
-
-var element_kind = {
- fast_elements : 1,
- fast_double_elements : 2,
- dictionary_elements : 3,
- external_byte_elements : 4,
- external_unsigned_byte_elements : 5,
- external_short_elements : 6,
- external_unsigned_short_elements : 7,
- external_int_elements : 8,
- external_unsigned_int_elements : 9,
- external_float_elements : 10,
- external_double_elements : 11,
- external_pixel_elements : 12
-}
-
-// We expect an object to only be of one element kind.
-function assertKind(expected, obj){
- assertEquals(expected == element_kind.fast_elements,
- %HasFastElements(obj));
- assertEquals(expected == element_kind.fast_double_elements,
- %HasFastDoubleElements(obj));
- assertEquals(expected == element_kind.dictionary_elements,
- %HasDictionaryElements(obj));
- assertEquals(expected == element_kind.external_byte_elements,
- %HasExternalByteElements(obj));
- assertEquals(expected == element_kind.external_unsigned_byte_elements,
- %HasExternalUnsignedByteElements(obj));
- assertEquals(expected == element_kind.external_short_elements,
- %HasExternalShortElements(obj));
- assertEquals(expected == element_kind.external_unsigned_short_elements,
- %HasExternalUnsignedShortElements(obj));
- assertEquals(expected == element_kind.external_int_elements,
- %HasExternalIntElements(obj));
- assertEquals(expected == element_kind.external_unsigned_int_elements,
- %HasExternalUnsignedIntElements(obj));
- assertEquals(expected == element_kind.external_float_elements,
- %HasExternalFloatElements(obj));
- assertEquals(expected == element_kind.external_double_elements,
- %HasExternalDoubleElements(obj));
- assertEquals(expected == element_kind.external_pixel_elements,
- %HasExternalPixelElements(obj));
- // every external kind is also an external array
- assertEquals(expected >= element_kind.external_byte_elements,
- %HasExternalArrayElements(obj));
-}
-
-var me = {};
-assertKind(element_kind.fast_elements, me);
-me.dance = 0xD15C0;
-me.drink = 0xC0C0A;
-assertKind(element_kind.fast_elements, me);
-
-var you = new Array();
-for(i = 0; i < 1337; i++) {
- you[i] = i;
-}
-assertKind(element_kind.fast_elements, you);
-
-assertKind(element_kind.dictionary_elements, new Array(0xC0C0A));
-
-// fast_double_elements not yet available
-
-
-assertKind(element_kind.external_byte_elements, new Int8Array(9001));
-assertKind(element_kind.external_unsigned_byte_elements, new Uint8Array(007));
-assertKind(element_kind.external_short_elements, new Int16Array(666));
-assertKind(element_kind.external_unsigned_short_elements, new Uint16Array(42));
-assertKind(element_kind.external_int_elements, new Int32Array(0xF));
-assertKind(element_kind.external_unsigned_int_elements, new Uint32Array(23));
-assertKind(element_kind.external_float_elements, new Float32Array(7));
-assertKind(element_kind.external_double_elements, new Float64Array(0));
-assertKind(element_kind.external_pixel_elements, new PixelArray(512));
diff --git a/test/mjsunit/elements-kind-depends.js b/test/mjsunit/elements-kind-depends.js
new file mode 100644
index 00000000..82f188b7
--- /dev/null
+++ b/test/mjsunit/elements-kind-depends.js
@@ -0,0 +1,74 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --smi-only-arrays
+
+function burn() {
+ var a = new Array(3);
+ a[0] = 10;
+ a[1] = 15.5;
+ a[2] = 20;
+ return a;
+}
+
+function check(a) {
+ assertEquals(10, a[0]);
+ assertEquals(15.5, a[1]);
+ assertEquals(20, a[2]);
+}
+
+var b;
+for (var i = 0; i < 3; ++i) {
+ b = burn();
+ check(b); // all OK
+}
+%OptimizeFunctionOnNextCall(burn);
+b = burn();
+check(b); // fails
+
+
+function loop_test(x) {
+ for (i=0;i<3;i++) {
+ x[i] = (i+1) * 0.5;
+ }
+}
+
+function check2(b) {
+ assertEquals(0.5, b[0]);
+ assertEquals(1.0, b[1]);
+ assertEquals(1.5, b[2]);
+}
+
+for (var i = 0; i < 3; ++i) {
+ b = [0,1,2];
+ loop_test(b);
+ check2(b);
+}
+%OptimizeFunctionOnNextCall(loop_test);
+b = [0,1,2];
+loop_test(b);
+check2(b);
diff --git a/test/mjsunit/elements-kind.js b/test/mjsunit/elements-kind.js
new file mode 100644
index 00000000..4aa79de6
--- /dev/null
+++ b/test/mjsunit/elements-kind.js
@@ -0,0 +1,346 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+
+// Test element kind of objects.
+// Since --smi-only-arrays affects builtins, its default setting at compile
+// time sticks if built with snapshot. If --smi-only-arrays is deactivated
+// by default, only a no-snapshot build actually has smi-only arrays enabled
+// in this test case. Depending on whether smi-only arrays are actually
+// enabled, this test takes the appropriate code path to check smi-only arrays.
+
+support_smi_only_arrays = %HasFastSmiOnlyElements(new Array(1,2,3,4,5,6,7,8));
+
+if (support_smi_only_arrays) {
+ print("Tests include smi-only arrays.");
+} else {
+ print("Tests do NOT include smi-only arrays.");
+}
+
+var elements_kind = {
+ fast_smi_only : 'fast smi only elements',
+ fast : 'fast elements',
+ fast_double : 'fast double elements',
+ dictionary : 'dictionary elements',
+ external_byte : 'external byte elements',
+ external_unsigned_byte : 'external unsigned byte elements',
+ external_short : 'external short elements',
+ external_unsigned_short : 'external unsigned short elements',
+ external_int : 'external int elements',
+ external_unsigned_int : 'external unsigned int elements',
+ external_float : 'external float elements',
+ external_double : 'external double elements',
+ external_pixel : 'external pixel elements'
+}
+
+function getKind(obj) {
+ if (%HasFastSmiOnlyElements(obj)) return elements_kind.fast_smi_only;
+ if (%HasFastElements(obj)) return elements_kind.fast;
+ if (%HasFastDoubleElements(obj)) return elements_kind.fast_double;
+ if (%HasDictionaryElements(obj)) return elements_kind.dictionary;
+ // Every external kind is also an external array.
+ assertTrue(%HasExternalArrayElements(obj));
+ if (%HasExternalByteElements(obj)) {
+ return elements_kind.external_byte;
+ }
+ if (%HasExternalUnsignedByteElements(obj)) {
+ return elements_kind.external_unsigned_byte;
+ }
+ if (%HasExternalShortElements(obj)) {
+ return elements_kind.external_short;
+ }
+ if (%HasExternalUnsignedShortElements(obj)) {
+ return elements_kind.external_unsigned_short;
+ }
+ if (%HasExternalIntElements(obj)) {
+ return elements_kind.external_int;
+ }
+ if (%HasExternalUnsignedIntElements(obj)) {
+ return elements_kind.external_unsigned_int;
+ }
+ if (%HasExternalFloatElements(obj)) {
+ return elements_kind.external_float;
+ }
+ if (%HasExternalDoubleElements(obj)) {
+ return elements_kind.external_double;
+ }
+ if (%HasExternalPixelElements(obj)) {
+ return elements_kind.external_pixel;
+ }
+}
+
+function assertKind(expected, obj, name_opt) {
+ if (!support_smi_only_arrays &&
+ expected == elements_kind.fast_smi_only) {
+ expected = elements_kind.fast;
+ }
+ assertEquals(expected, getKind(obj), name_opt);
+}
+
+var me = {};
+assertKind(elements_kind.fast, me);
+me.dance = 0xD15C0;
+me.drink = 0xC0C0A;
+assertKind(elements_kind.fast, me);
+
+if (support_smi_only_arrays) {
+ var too = [1,2,3];
+ assertKind(elements_kind.fast_smi_only, too);
+ too.dance = 0xD15C0;
+ too.drink = 0xC0C0A;
+ assertKind(elements_kind.fast_smi_only, too);
+}
+
+// Make sure the element kind transitions from smionly when a non-smi is stored.
+var you = new Array();
+assertKind(elements_kind.fast_smi_only, you);
+for (var i = 0; i < 1337; i++) {
+ var val = i;
+ if (i == 1336) {
+ assertKind(elements_kind.fast_smi_only, you);
+ val = new Object();
+ }
+ you[i] = val;
+}
+assertKind(elements_kind.fast, you);
+
+assertKind(elements_kind.dictionary, new Array(0xDECAF));
+
+var fast_double_array = new Array(0xDECAF);
+for (var i = 0; i < 0xDECAF; i++) fast_double_array[i] = i / 2;
+assertKind(elements_kind.fast_double, fast_double_array);
+
+assertKind(elements_kind.external_byte, new Int8Array(9001));
+assertKind(elements_kind.external_unsigned_byte, new Uint8Array(007));
+assertKind(elements_kind.external_short, new Int16Array(666));
+assertKind(elements_kind.external_unsigned_short, new Uint16Array(42));
+assertKind(elements_kind.external_int, new Int32Array(0xF));
+assertKind(elements_kind.external_unsigned_int, new Uint32Array(23));
+assertKind(elements_kind.external_float, new Float32Array(7));
+assertKind(elements_kind.external_double, new Float64Array(0));
+assertKind(elements_kind.external_pixel, new PixelArray(512));
+
+// Crankshaft support for smi-only array elements.
+function monomorphic(array) {
+ assertKind(elements_kind.fast_smi_only, array);
+ for (var i = 0; i < 3; i++) {
+ array[i] = i + 10;
+ }
+ assertKind(elements_kind.fast_smi_only, array);
+ for (var i = 0; i < 3; i++) {
+ var a = array[i];
+ assertEquals(i + 10, a);
+ }
+}
+var smi_only = new Array(1, 2, 3);
+assertKind(elements_kind.fast_smi_only, smi_only);
+for (var i = 0; i < 3; i++) monomorphic(smi_only);
+%OptimizeFunctionOnNextCall(monomorphic);
+monomorphic(smi_only);
+
+if (support_smi_only_arrays) {
+ function construct_smis() {
+ var a = [0, 0, 0];
+ a[0] = 0; // Send the COW array map to the steak house.
+ assertKind(elements_kind.fast_smi_only, a);
+ return a;
+ }
+ function construct_doubles() {
+ var a = construct_smis();
+ a[0] = 1.5;
+ assertKind(elements_kind.fast_double, a);
+ return a;
+ }
+ function construct_objects() {
+ var a = construct_smis();
+ a[0] = "one";
+ assertKind(elements_kind.fast, a);
+ return a;
+ }
+
+ // Test crankshafted transition SMI->DOUBLE.
+ function convert_to_double(array) {
+ array[1] = 2.5;
+ assertKind(elements_kind.fast_double, array);
+ assertEquals(2.5, array[1]);
+ }
+ var smis = construct_smis();
+ for (var i = 0; i < 3; i++) convert_to_double(smis);
+ %OptimizeFunctionOnNextCall(convert_to_double);
+ smis = construct_smis();
+ convert_to_double(smis);
+ // Test crankshafted transitions SMI->FAST and DOUBLE->FAST.
+ function convert_to_fast(array) {
+ array[1] = "two";
+ assertKind(elements_kind.fast, array);
+ assertEquals("two", array[1]);
+ }
+ smis = construct_smis();
+ for (var i = 0; i < 3; i++) convert_to_fast(smis);
+ var doubles = construct_doubles();
+ for (var i = 0; i < 3; i++) convert_to_fast(doubles);
+ smis = construct_smis();
+ doubles = construct_doubles();
+ %OptimizeFunctionOnNextCall(convert_to_fast);
+ convert_to_fast(smis);
+ convert_to_fast(doubles);
+ // Test transition chain SMI->DOUBLE->FAST (crankshafted function will
+ // transition to FAST directly).
+ function convert_mixed(array, value, kind) {
+ array[1] = value;
+ assertKind(kind, array);
+ assertEquals(value, array[1]);
+ }
+ smis = construct_smis();
+ for (var i = 0; i < 3; i++) {
+ convert_mixed(smis, 1.5, elements_kind.fast_double);
+ }
+ doubles = construct_doubles();
+ for (var i = 0; i < 3; i++) {
+ convert_mixed(doubles, "three", elements_kind.fast);
+ }
+ smis = construct_smis();
+ doubles = construct_doubles();
+ %OptimizeFunctionOnNextCall(convert_mixed);
+ convert_mixed(smis, 1, elements_kind.fast);
+ convert_mixed(doubles, 1, elements_kind.fast);
+ assertTrue(%HaveSameMap(smis, doubles));
+}
+
+// Crankshaft support for smi-only elements in dynamic array literals.
+function get(foo) { return foo; } // Used to generate dynamic values.
+
+function crankshaft_test() {
+ if (support_smi_only_arrays) {
+ var a1 = [get(1), get(2), get(3)];
+ assertKind(elements_kind.fast_smi_only, a1);
+ }
+ var a2 = new Array(get(1), get(2), get(3));
+ assertKind(elements_kind.fast_smi_only, a2);
+ var b = [get(1), get(2), get("three")];
+ assertKind(elements_kind.fast, b);
+ var c = [get(1), get(2), get(3.5)];
+ if (support_smi_only_arrays) {
+ assertKind(elements_kind.fast_double, c);
+ }
+}
+for (var i = 0; i < 3; i++) {
+ crankshaft_test();
+}
+%OptimizeFunctionOnNextCall(crankshaft_test);
+crankshaft_test();
+
+// Elements_kind transitions for arrays.
+
+// A map can have three different elements_kind transitions: SMI->DOUBLE,
+// DOUBLE->OBJECT, and SMI->OBJECT. No matter in which order these three are
+// created, they must always end up with the same FAST map.
+
+// This test is meaningless without FAST_SMI_ONLY_ELEMENTS.
+if (support_smi_only_arrays) {
+ // Preparation: create one pair of identical objects for each case.
+ var a = [1, 2, 3];
+ var b = [1, 2, 3];
+ assertTrue(%HaveSameMap(a, b));
+ assertKind(elements_kind.fast_smi_only, a);
+ var c = [1, 2, 3];
+ c["case2"] = true;
+ var d = [1, 2, 3];
+ d["case2"] = true;
+ assertTrue(%HaveSameMap(c, d));
+ assertFalse(%HaveSameMap(a, c));
+ assertKind(elements_kind.fast_smi_only, c);
+ var e = [1, 2, 3];
+ e["case3"] = true;
+ var f = [1, 2, 3];
+ f["case3"] = true;
+ assertTrue(%HaveSameMap(e, f));
+ assertFalse(%HaveSameMap(a, e));
+ assertFalse(%HaveSameMap(c, e));
+ assertKind(elements_kind.fast_smi_only, e);
+ // Case 1: SMI->DOUBLE, DOUBLE->OBJECT, SMI->OBJECT.
+ a[0] = 1.5;
+ assertKind(elements_kind.fast_double, a);
+ a[0] = "foo";
+ assertKind(elements_kind.fast, a);
+ b[0] = "bar";
+ assertTrue(%HaveSameMap(a, b));
+ // Case 2: SMI->DOUBLE, SMI->OBJECT, DOUBLE->OBJECT.
+ c[0] = 1.5;
+ assertKind(elements_kind.fast_double, c);
+ assertFalse(%HaveSameMap(c, d));
+ d[0] = "foo";
+ assertKind(elements_kind.fast, d);
+ assertFalse(%HaveSameMap(c, d));
+ c[0] = "bar";
+ assertTrue(%HaveSameMap(c, d));
+ // Case 3: SMI->OBJECT, SMI->DOUBLE, DOUBLE->OBJECT.
+ e[0] = "foo";
+ assertKind(elements_kind.fast, e);
+ assertFalse(%HaveSameMap(e, f));
+ f[0] = 1.5;
+ assertKind(elements_kind.fast_double, f);
+ assertFalse(%HaveSameMap(e, f));
+ f[0] = "bar";
+ assertKind(elements_kind.fast, f);
+ assertTrue(%HaveSameMap(e, f));
+}
+
+// Test if Array.concat() works correctly with DOUBLE elements.
+if (support_smi_only_arrays) {
+ var a = [1, 2];
+ assertKind(elements_kind.fast_smi_only, a);
+ var b = [4.5, 5.5];
+ assertKind(elements_kind.fast_double, b);
+ var c = a.concat(b);
+ assertEquals([1, 2, 4.5, 5.5], c);
+ // TODO(1810): Change implementation so that we get DOUBLE elements here?
+ assertKind(elements_kind.fast, c);
+}
+
+// Test that Array.push() correctly handles SMI elements.
+if (support_smi_only_arrays) {
+ var a = [1, 2];
+ assertKind(elements_kind.fast_smi_only, a);
+ a.push(3, 4, 5);
+ assertKind(elements_kind.fast_smi_only, a);
+ assertEquals([1, 2, 3, 4, 5], a);
+}
+
+// Test that Array.splice() and Array.slice() return correct ElementsKinds.
+if (support_smi_only_arrays) {
+ var a = ["foo", "bar"];
+ assertKind(elements_kind.fast, a);
+ var b = a.splice(0, 1);
+ assertKind(elements_kind.fast, b);
+ var c = a.slice(0, 1);
+ assertKind(elements_kind.fast, c);
+}
+
+// Throw away type information in the ICs for next stress run.
+gc();
diff --git a/test/mjsunit/elements-transition-hoisting.js b/test/mjsunit/elements-transition-hoisting.js
new file mode 100644
index 00000000..5e78f10a
--- /dev/null
+++ b/test/mjsunit/elements-transition-hoisting.js
@@ -0,0 +1,211 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --smi-only-arrays --expose-gc
+
+// Ensure that ElementsKind transitions in various situations are hoisted (or
+// not hoisted) correctly, don't change the semantics programs and don't trigger
+// deopt through hoisting in important situations.
+
+support_smi_only_arrays = %HasFastSmiOnlyElements(new Array(1,2,3,4,5,6));
+
+if (support_smi_only_arrays) {
+ print("Tests include smi-only arrays.");
+} else {
+ print("Tests do NOT include smi-only arrays.");
+}
+
+// Force existing ICs from previous stress runs to be flushed, otherwise the
+// assumptions in this test about when deoptimizations get triggered are not
+// valid.
+gc();
+
+if (support_smi_only_arrays) {
+ // Make sure that a simple elements array transitions inside a loop before
+ // stores to an array gets hoisted in a way that doesn't generate a deopt in
+ // simple cases.}
+ function testDoubleConversion4(a) {
+ var object = new Object();
+ a[0] = 0;
+ var count = 3;
+ do {
+ a[0] = object;
+ } while (--count > 0);
+ }
+
+ testDoubleConversion4(new Array(5));
+ %OptimizeFunctionOnNextCall(testDoubleConversion4);
+ testDoubleConversion4(new Array(5));
+ testDoubleConversion4(new Array(5));
+ assertTrue(2 != %GetOptimizationStatus(testDoubleConversion4));
+
+ // Make sure that non-element related map checks that are not preceded by
+ // transitions in a loop still get hoisted in a way that doesn't generate a
+ // deopt in simple cases.
+ function testExactMapHoisting(a) {
+ var object = new Object();
+ a.foo = 0;
+ a[0] = 0;
+ a[1] = 1;
+ var count = 3;
+ do {
+ a.foo = object; // This map check should be hoistable
+ a[1] = object;
+ result = a.foo == object && a[1] == object;
+ } while (--count > 0);
+ }
+
+ testExactMapHoisting(new Array(5));
+ %OptimizeFunctionOnNextCall(testExactMapHoisting);
+ testExactMapHoisting(new Array(5));
+ testExactMapHoisting(new Array(5));
+ assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting));
+
+ // Make sure that non-element related map checks do NOT get hoisted if they
+ // depend on an elements transition before them and it's not possible to hoist
+ // that transition.
+ function testExactMapHoisting2(a) {
+ var object = new Object();
+ a.foo = 0;
+ a[0] = 0;
+ a[1] = 1;
+ var count = 3;
+ do {
+ if (a.bar === undefined) {
+ a[1] = 2.5;
+ }
+ a.foo = object; // This map check should NOT be hoistable because it
+ // includes a check for the FAST_ELEMENTS map as well as
+ // the FAST_DOUBLE_ELEMENTS map, which depends on the
+ // double transition above in the if, which cannot be
+ // hoisted.
+ } while (--count > 0);
+ }
+
+ testExactMapHoisting2(new Array(5));
+ %OptimizeFunctionOnNextCall(testExactMapHoisting2);
+ testExactMapHoisting2(new Array(5));
+ testExactMapHoisting2(new Array(5));
+ assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting2));
+
+ // Make sure that non-element related map checks do get hoisted if they use
+ // the transitioned map for the check and all transitions that they depend
+ // upon can hoisted, too.
+ function testExactMapHoisting3(a) {
+ var object = new Object();
+ a.foo = 0;
+ a[0] = 0;
+ a[1] = 1;
+ var count = 3;
+ do {
+ a[1] = 2.5;
+ a.foo = object; // This map check should be hoistable because all elements
+ // transitions in the loop can also be hoisted.
+ } while (--count > 0);
+ }
+
+ var add_transition = new Array(5);
+ add_transition.foo = 0;
+ add_transition[0] = new Object(); // For FAST_ELEMENT transition to be created
+ testExactMapHoisting3(new Array(5));
+ %OptimizeFunctionOnNextCall(testExactMapHoisting3);
+ testExactMapHoisting3(new Array(5));
+ testExactMapHoisting3(new Array(5));
+ assertTrue(2 != %GetOptimizationStatus(testExactMapHoisting3));
+
+ function testDominatingTransitionHoisting1(a) {
+ var object = new Object();
+ a[0] = 0;
+ var count = 3;
+ do {
+ if (a.baz != true) {
+ a[1] = 2.5;
+ }
+ a[0] = object;
+ } while (--count > 3);
+ }
+
+ testDominatingTransitionHoisting1(new Array(5));
+ %OptimizeFunctionOnNextCall(testDominatingTransitionHoisting1);
+ testDominatingTransitionHoisting1(new Array(5));
+ testDominatingTransitionHoisting1(new Array(5));
+ assertTrue(2 != %GetOptimizationStatus(testDominatingTransitionHoisting1));
+
+ function testHoistingWithSideEffect(a) {
+ var object = new Object();
+ a[0] = 0;
+ var count = 3;
+ do {
+ assertTrue(true);
+ a[0] = object;
+ } while (--count > 3);
+ }
+
+ testHoistingWithSideEffect(new Array(5));
+ %OptimizeFunctionOnNextCall(testHoistingWithSideEffect);
+ testHoistingWithSideEffect(new Array(5));
+ testHoistingWithSideEffect(new Array(5));
+ assertTrue(2 != %GetOptimizationStatus(testHoistingWithSideEffect));
+
+ function testStraightLineDupeElinination(a,b,c,d,e,f) {
+ var count = 3;
+ do {
+ assertTrue(true);
+ a[0] = b;
+ a[1] = c;
+ a[2] = d;
+ assertTrue(true);
+ a[3] = e; // TransitionElementsKind should be eliminated despite call.
+ a[4] = f;
+ } while (--count > 3);
+ }
+
+ testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,0,0,0,.5);
+ testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,0,0,.5,0);
+ testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,0,.5,0,0);
+ testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),0,.5,0,0,0);
+ testStraightLineDupeElinination(new Array(0, 0, 0, 0, 0),.5,0,0,0,0);
+ testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,0,0,0,.5);
+ testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,0,0,.5,0);
+ testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,0,.5,0,0);
+ testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),0,.5,0,0,0);
+ testStraightLineDupeElinination(new Array(.1,.1,.1,.1,.1),.5,0,0,0,0);
+ testStraightLineDupeElinination(new Array(5),.5,0,0,0,0);
+ testStraightLineDupeElinination(new Array(5),0,.5,0,0,0);
+ testStraightLineDupeElinination(new Array(5),0,0,.5,0,0);
+ testStraightLineDupeElinination(new Array(5),0,0,0,.5,0);
+ testStraightLineDupeElinination(new Array(5),0,0,0,0,.5);
+ testStraightLineDupeElinination(new Array(5),.5,0,0,0,0);
+ testStraightLineDupeElinination(new Array(5),0,.5,0,0,0);
+ testStraightLineDupeElinination(new Array(5),0,0,.5,0,0);
+ testStraightLineDupeElinination(new Array(5),0,0,0,.5,0);
+ testStraightLineDupeElinination(new Array(5),0,0,0,0,.5);
+ %OptimizeFunctionOnNextCall(testStraightLineDupeElinination);
+ testStraightLineDupeElinination(new Array(5));
+ testStraightLineDupeElinination(new Array(5));
+ assertTrue(2 != %GetOptimizationStatus(testStraightLineDupeElinination));
+}
diff --git a/test/mjsunit/elements-transition.js b/test/mjsunit/elements-transition.js
new file mode 100644
index 00000000..60e051b3
--- /dev/null
+++ b/test/mjsunit/elements-transition.js
@@ -0,0 +1,113 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --smi-only-arrays
+
+support_smi_only_arrays = %HasFastSmiOnlyElements(new Array(1,2,3,4,5,6,7,8));
+
+if (support_smi_only_arrays) {
+ print("Tests include smi-only arrays.");
+} else {
+ print("Tests do NOT include smi-only arrays.");
+}
+
+if (support_smi_only_arrays) {
+ function test(test_double, test_object, set, length) {
+ // We apply the same operations to two identical arrays. The first array
+ // triggers an IC miss, upon which the conversion stub is generated, but the
+ // actual conversion is done in runtime. The second array, arriving at
+ // the previously patched IC, is then converted using the conversion stub.
+ var array_1 = new Array(length);
+ var array_2 = new Array(length);
+
+ assertTrue(%HasFastSmiOnlyElements(array_1));
+ assertTrue(%HasFastSmiOnlyElements(array_2));
+ for (var i = 0; i < length; i++) {
+ if (i == length - 5 && test_double) {
+ // Trigger conversion to fast double elements at length-5.
+ set(array_1, i, 0.5);
+ set(array_2, i, 0.5);
+ assertTrue(%HasFastDoubleElements(array_1));
+ assertTrue(%HasFastDoubleElements(array_2));
+ } else if (i == length - 3 && test_object) {
+ // Trigger conversion to fast object elements at length-3.
+ set(array_1, i, 'object');
+ set(array_2, i, 'object');
+ assertTrue(%HasFastElements(array_1));
+ assertTrue(%HasFastElements(array_2));
+ } else if (i != length - 7) {
+ // Set the element to an integer but leave a hole at length-7.
+ set(array_1, i, 2*i+1);
+ set(array_2, i, 2*i+1);
+ }
+ }
+
+ for (var i = 0; i < length; i++) {
+ if (i == length - 5 && test_double) {
+ assertEquals(0.5, array_1[i]);
+ assertEquals(0.5, array_2[i]);
+ } else if (i == length - 3 && test_object) {
+ assertEquals('object', array_1[i]);
+ assertEquals('object', array_2[i]);
+ } else if (i != length - 7) {
+ assertEquals(2*i+1, array_1[i]);
+ assertEquals(2*i+1, array_2[i]);
+ } else {
+ assertEquals(undefined, array_1[i]);
+ assertEquals(undefined, array_2[i]);
+ }
+ }
+
+ assertEquals(length, array_1.length);
+ assertEquals(length, array_2.length);
+ }
+
+ test(false, false, function(a,i,v){ a[i] = v; }, 20);
+ test(true, false, function(a,i,v){ a[i] = v; }, 20);
+ test(false, true, function(a,i,v){ a[i] = v; }, 20);
+ test(true, true, function(a,i,v){ a[i] = v; }, 20);
+
+ test(false, false, function(a,i,v){ a[i] = v; }, 10000);
+ test(true, false, function(a,i,v){ a[i] = v; }, 10000);
+ test(false, true, function(a,i,v){ a[i] = v; }, 10000);
+ test(true, true, function(a,i,v){ a[i] = v; }, 10000);
+
+ // Check COW arrays
+ function get_cow() { return [1, 2, 3]; }
+
+ function transition(x) { x[0] = 1.5; }
+
+ var ignore = get_cow();
+ transition(ignore); // Handled by runtime.
+ var a = get_cow();
+ var b = get_cow();
+ transition(a); // Handled by IC.
+ assertEquals(1.5, a[0]);
+ assertEquals(1, b[0]);
+} else {
+ print("Test skipped because smi only arrays are not supported.");
+}
diff --git a/test/mjsunit/error-tostring.js b/test/mjsunit/error-tostring.js
new file mode 100644
index 00000000..a2856414
--- /dev/null
+++ b/test/mjsunit/error-tostring.js
@@ -0,0 +1,85 @@
+// 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.
+
+
+// Test default string representation of an Error object.
+
+var e = new Error();
+assertEquals('Error', e.toString());
+
+
+// Test printing of cyclic errors which return the empty string for
+// compatibility with Safari and Firefox.
+
+e = new Error();
+e.name = e;
+e.message = e;
+e.stack = "Does not occur in output";
+e.arguments = "Does not occur in output";
+e.type = "Does not occur in output";
+assertEquals('', e.toString());
+
+e = new Error();
+e.name = [ e ];
+e.message = [ e ];
+e.stack = "Does not occur in output";
+e.arguments = "Does not occur in output";
+e.type = "Does not occur in output";
+assertEquals('', e.toString());
+
+
+// Test the sequence in which getters and toString operations are called
+// on a given Error object. Verify the produced string representation.
+
+function testErrorToString(nameValue, messageValue) {
+ var seq = [];
+ var e = {
+ get name() {
+ seq.push(1);
+ return (nameValue === undefined) ? nameValue : {
+ toString: function() { seq.push(2); return nameValue; }
+ };
+ },
+ get message() {
+ seq.push(3);
+ return (messageValue === undefined) ? messageValue : {
+ toString: function() { seq.push(4); return messageValue; }
+ };
+ }
+ };
+ var string = Error.prototype.toString.call(e);
+ return [string,seq];
+}
+
+assertEquals(["Error",[1,3]], testErrorToString(undefined, undefined));
+assertEquals(["e1",[1,2,3]], testErrorToString("e1", undefined));
+assertEquals(["e1: null",[1,2,3,4]], testErrorToString("e1", null));
+assertEquals(["e1",[1,2,3,4]], testErrorToString("e1", ""));
+assertEquals(["Error: e2",[1,3,4]], testErrorToString(undefined, "e2"));
+assertEquals(["null: e2",[1,2,3,4]], testErrorToString(null, "e2"));
+assertEquals(["e2",[1,2,3,4]], testErrorToString("", "e2"));
+assertEquals(["e1: e2",[1,2,3,4]], testErrorToString("e1", "e2"));
diff --git a/test/mjsunit/eval.js b/test/mjsunit/eval.js
index b6284ba9..100f2165 100644
--- a/test/mjsunit/eval.js
+++ b/test/mjsunit/eval.js
@@ -39,7 +39,7 @@ assertEquals(1, count);
try {
eval('hest 7 &*^*&^');
- assertTrue(false, 'Did not throw on syntax error.');
+ assertUnreachable('Did not throw on syntax error.');
} catch (e) {
assertEquals('SyntaxError', e.name);
}
@@ -108,6 +108,7 @@ foo = 0;
result =
(function() {
var foo = 2;
+ // Should be non-direct call.
return x.eval('foo');
})();
assertEquals(0, result);
@@ -115,12 +116,33 @@ assertEquals(0, result);
foo = 0;
result =
(function() {
+ var foo = 2;
+ // Should be non-direct call.
+ return (1,eval)('foo');
+ })();
+assertEquals(0, result);
+
+foo = 0;
+result =
+ (function() {
var eval = function(x) { return x; };
var foo = eval(2);
+ // Should be non-direct call.
return e('foo');
})();
assertEquals(0, result);
+foo = 0;
+result =
+ (function() {
+ var foo = 2;
+ // Should be direct call.
+ with ({ eval : e }) {
+ return eval('foo');
+ }
+ })();
+assertEquals(2, result);
+
result =
(function() {
var eval = function(x) { return 2 * x; };
@@ -135,19 +157,17 @@ result =
})();
assertEquals(this, result);
-result =
- (function() {
- var obj = { f: function(eval) { return eval("this"); } };
- return obj.f(eval);
- })();
-assertEquals(this, result);
+(function() {
+ var obj = { f: function(eval) { return eval("this"); } };
+ result = obj.f(eval);
+ assertEquals(obj, result);
+})();
-result =
- (function() {
- var obj = { f: function(eval) { arguments; return eval("this"); } };
- return obj.f(eval);
- })();
-assertEquals(this, result);
+(function() {
+ var obj = { f: function(eval) { arguments; return eval("this"); } };
+ result = obj.f(eval);
+ assertEquals(obj, result);
+})();
eval = function(x) { return 2 * x; };
result =
@@ -156,6 +176,9 @@ result =
})();
assertEquals(4, result);
+
+
+
// Regression test: calling a function named eval found in a context that is
// not the global context should get the global object as receiver.
result =
diff --git a/test/mjsunit/external-array.js b/test/mjsunit/external-array.js
index 81c6cfe8..32f78a72 100644
--- a/test/mjsunit/external-array.js
+++ b/test/mjsunit/external-array.js
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -43,6 +43,50 @@ f(a);
assertEquals(0, a[0]);
assertEquals(0, a[1]);
+// No-parameter constructor should fail right now.
+function abfunc1() {
+ return new ArrayBuffer();
+}
+assertThrows(abfunc1);
+
+// Test derivation from an ArrayBuffer
+var ab = new ArrayBuffer(12);
+var derived_uint8 = new Uint8Array(ab);
+assertEquals(12, derived_uint8.length);
+var derived_uint32 = new Uint32Array(ab);
+assertEquals(3, derived_uint32.length);
+var derived_uint32_2 = new Uint32Array(ab,4);
+assertEquals(2, derived_uint32_2.length);
+var derived_uint32_3 = new Uint32Array(ab,4,1);
+assertEquals(1, derived_uint32_3.length);
+
+// If a given byteOffset and length references an area beyond the end of the
+// ArrayBuffer an exception is raised.
+function abfunc3() {
+ new Uint32Array(ab,4,3);
+}
+assertThrows(abfunc3);
+function abfunc4() {
+ new Uint32Array(ab,16);
+}
+assertThrows(abfunc4);
+
+// The given byteOffset must be a multiple of the element size of the specific
+// type, otherwise an exception is raised.
+function abfunc5() {
+ new Uint32Array(ab,5);
+}
+assertThrows(abfunc5);
+
+// If length is not explicitly specified, the length of the ArrayBuffer minus
+// the byteOffset must be a multiple of the element size of the specific type,
+// or an exception is raised.
+var ab2 = new ArrayBuffer(13);
+function abfunc6() {
+ new Uint32Array(ab2,4);
+}
+assertThrows(abfunc6);
+
// Test the correct behavior of the |BYTES_PER_ELEMENT| property (which is
// "constant", but not read-only).
a = new Int32Array(2);
@@ -273,3 +317,37 @@ for (var t = 0; t < types.length; t++) {
%DeoptimizeFunction(array_load_set_smi_check2);
gc(); // Makes V8 forget about type information for array_load_set_smi_check.
}
+
+// Check handling of undefined in 32- and 64-bit external float arrays.
+
+function store_float32_undefined(ext_array) {
+ ext_array[0] = undefined;
+}
+
+var float32_array = new Float32Array(1);
+// Make sure runtime does it right
+store_float32_undefined(float32_array);
+assertTrue(isNaN(float32_array[0]));
+// Make sure the ICs do it right
+store_float32_undefined(float32_array);
+assertTrue(isNaN(float32_array[0]));
+// Make sure that Cranskshft does it right.
+%OptimizeFunctionOnNextCall(store_float32_undefined);
+store_float32_undefined(float32_array);
+assertTrue(isNaN(float32_array[0]));
+
+function store_float64_undefined(ext_array) {
+ ext_array[0] = undefined;
+}
+
+var float64_array = new Float64Array(1);
+// Make sure runtime does it right
+store_float64_undefined(float64_array);
+assertTrue(isNaN(float64_array[0]));
+// Make sure the ICs do it right
+store_float64_undefined(float64_array);
+assertTrue(isNaN(float64_array[0]));
+// Make sure that Cranskshft does it right.
+%OptimizeFunctionOnNextCall(store_float64_undefined);
+store_float64_undefined(float64_array);
+assertTrue(isNaN(float64_array[0]));
diff --git a/test/mjsunit/function-bind.js b/test/mjsunit/function-bind.js
index e9d02213..4a8f2d2a 100644
--- a/test/mjsunit/function-bind.js
+++ b/test/mjsunit/function-bind.js
@@ -29,29 +29,31 @@
// Simple tests.
function foo(x, y, z) {
- return x + y + z;
+ return [this, arguments.length, x];
}
+assertEquals(3, foo.length);
+
var f = foo.bind(foo);
-assertEquals(3, f(1, 1, 1));
+assertEquals([foo, 3, 1], f(1, 2, 3));
assertEquals(3, f.length);
-f = foo.bind(foo, 2);
-assertEquals(4, f(1, 1));
+f = foo.bind(foo, 1);
+assertEquals([foo, 3, 1], f(2, 3));
assertEquals(2, f.length);
-f = foo.bind(foo, 2, 2);
-assertEquals(5, f(1));
+f = foo.bind(foo, 1, 2);
+assertEquals([foo, 3, 1], f(3));
assertEquals(1, f.length);
-f = foo.bind(foo, 2, 2, 2);
-assertEquals(6, f());
+f = foo.bind(foo, 1, 2, 3);
+assertEquals([foo, 3, 1], f());
assertEquals(0, f.length);
// Test that length works correctly even if more than the actual number
// of arguments are given when binding.
f = foo.bind(foo, 1, 2, 3, 4, 5, 6, 7, 8, 9);
-assertEquals(6, f());
+assertEquals([foo, 9, 1], f());
assertEquals(0, f.length);
// Use a different bound object.
@@ -78,64 +80,97 @@ assertEquals(0, f.length);
// When only giving the thisArg, any number of binds should have
// the same effect.
f = foo.bind(foo);
-assertEquals(3, f(1, 1, 1));
-f = foo.bind(foo).bind(foo).bind(foo).bind(foo);
-assertEquals(3, f(1, 1, 1));
+assertEquals([foo, 3, 1], f(1, 2, 3));
+
+var not_foo = {};
+f = foo.bind(foo).bind(not_foo).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(1, 2, 3));
assertEquals(3, f.length);
// Giving bound parameters should work at any place in the chain.
-f = foo.bind(foo, 1).bind(foo).bind(foo).bind(foo);
-assertEquals(3, f(1, 1));
+f = foo.bind(foo, 1).bind(not_foo).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(2, 3));
assertEquals(2, f.length);
-f = foo.bind(foo).bind(foo, 1).bind(foo).bind(foo);
-assertEquals(3, f(1, 1));
+f = foo.bind(foo).bind(not_foo, 1).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(2, 3));
assertEquals(2, f.length);
-f = foo.bind(foo).bind(foo).bind(foo,1 ).bind(foo);
-assertEquals(3, f(1, 1));
+f = foo.bind(foo).bind(not_foo).bind(not_foo,1 ).bind(not_foo);
+assertEquals([foo, 3, 1], f(2, 3));
assertEquals(2, f.length);
-f = foo.bind(foo).bind(foo).bind(foo).bind(foo, 1);
-assertEquals(3, f(1, 1));
+f = foo.bind(foo).bind(not_foo).bind(not_foo).bind(not_foo, 1);
+assertEquals([foo, 3, 1], f(2, 3));
assertEquals(2, f.length);
-// Several parameters can be given, and given in different bind invokations.
-f = foo.bind(foo, 1, 1).bind(foo).bind(foo).bind(foo);
-assertEquals(3, f(1));
+// Several parameters can be given, and given in different bind invocations.
+f = foo.bind(foo, 1, 2).bind(not_foo).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(3));
+assertEquals(1, f.length);
+
+f = foo.bind(foo).bind(not_foo, 1, 2).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(1));
assertEquals(1, f.length);
-f = foo.bind(foo).bind(foo, 1, 1).bind(foo).bind(foo);
-assertEquals(3, f(1));
+f = foo.bind(foo).bind(not_foo, 1, 2).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(3));
assertEquals(1, f.length);
-f = foo.bind(foo).bind(foo, 1, 1).bind(foo).bind(foo);
-assertEquals(3, f(1));
+f = foo.bind(foo).bind(not_foo).bind(not_foo, 1, 2).bind(not_foo);
+assertEquals([foo, 3, 1], f(1));
assertEquals(1, f.length);
-f = foo.bind(foo).bind(foo).bind(foo, 1, 1).bind(foo);
-assertEquals(3, f(1));
+f = foo.bind(foo).bind(not_foo).bind(not_foo).bind(not_foo, 1, 2);
+assertEquals([foo, 3, 1], f(3));
assertEquals(1, f.length);
-f = foo.bind(foo).bind(foo).bind(foo).bind(foo, 1, 1);
-assertEquals(3, f(1));
+f = foo.bind(foo, 1).bind(not_foo, 2).bind(not_foo).bind(not_foo);
+assertEquals([foo, 3, 1], f(3));
assertEquals(1, f.length);
-f = foo.bind(foo, 1).bind(foo, 1).bind(foo).bind(foo);
-assertEquals(3, f(1));
+f = foo.bind(foo, 1).bind(not_foo).bind(not_foo, 2).bind(not_foo);
+assertEquals([foo, 3, 1], f(3));
assertEquals(1, f.length);
-f = foo.bind(foo, 1).bind(foo).bind(foo, 1).bind(foo);
-assertEquals(3, f(1));
+f = foo.bind(foo, 1).bind(not_foo).bind(not_foo).bind(not_foo, 2);
+assertEquals([foo, 3, 1], f(3));
assertEquals(1, f.length);
-f = foo.bind(foo, 1).bind(foo).bind(foo).bind(foo, 1);
-assertEquals(3, f(1));
+f = foo.bind(foo).bind(not_foo, 1).bind(not_foo).bind(not_foo, 2);
+assertEquals([foo, 3, 1], f(3));
assertEquals(1, f.length);
-f = foo.bind(foo).bind(foo, 1).bind(foo).bind(foo, 1);
-assertEquals(3, f(1));
+// The wrong number of arguments can be given to bound functions too.
+f = foo.bind(foo);
+assertEquals(3, f.length);
+assertEquals([foo, 0, undefined], f());
+assertEquals([foo, 1, 1], f(1));
+assertEquals([foo, 2, 1], f(1, 2));
+assertEquals([foo, 3, 1], f(1, 2, 3));
+assertEquals([foo, 4, 1], f(1, 2, 3, 4));
+
+f = foo.bind(foo, 1);
+assertEquals(2, f.length);
+assertEquals([foo, 1, 1], f());
+assertEquals([foo, 2, 1], f(2));
+assertEquals([foo, 3, 1], f(2, 3));
+assertEquals([foo, 4, 1], f(2, 3, 4));
+
+f = foo.bind(foo, 1, 2);
assertEquals(1, f.length);
+assertEquals([foo, 2, 1], f());
+assertEquals([foo, 3, 1], f(3));
+assertEquals([foo, 4, 1], f(3, 4));
+
+f = foo.bind(foo, 1, 2, 3);
+assertEquals(0, f.length);
+assertEquals([foo, 3, 1], f());
+assertEquals([foo, 4, 1], f(4));
+
+f = foo.bind(foo, 1, 2, 3, 4);
+assertEquals(0, f.length);
+assertEquals([foo, 4, 1], f());
// Test constructor calls.
@@ -171,13 +206,91 @@ assertEquals(3, obj2.z);
// Test bind chains when used as a constructor.
-
f = bar.bind(bar, 1).bind(bar, 2).bind(bar, 3);
obj2 = new f();
assertEquals(1, obj2.x);
assertEquals(2, obj2.y);
assertEquals(3, obj2.z);
-// Test instanceof obj2 is bar, not f.
+// Test obj2 is instanceof both bar and f.
assertTrue(obj2 instanceof bar);
-assertFalse(obj2 instanceof f);
+assertTrue(obj2 instanceof f);
+
+// This-args are not relevant to instanceof.
+f = bar.bind(foo.prototype, 1).
+ bind(String.prototype, 2).
+ bind(Function.prototype, 3);
+var obj3 = new f();
+assertTrue(obj3 instanceof bar);
+assertTrue(obj3 instanceof f);
+assertFalse(obj3 instanceof foo);
+assertFalse(obj3 instanceof Function);
+assertFalse(obj3 instanceof String);
+
+// thisArg is converted to object.
+f = foo.bind(undefined);
+assertEquals([this, 0, undefined], f());
+
+f = foo.bind(null);
+assertEquals([this, 0, undefined], f());
+
+f = foo.bind(42);
+assertEquals([Object(42), 0, undefined], f());
+
+f = foo.bind("foo");
+assertEquals([Object("foo"), 0, undefined], f());
+
+f = foo.bind(true);
+assertEquals([Object(true), 0, undefined], f());
+
+// Strict functions don't convert thisArg.
+function soo(x, y, z) {
+ "use strict";
+ return [this, arguments.length, x];
+}
+
+var s = soo.bind(undefined);
+assertEquals([undefined, 0, undefined], s());
+
+s = soo.bind(null);
+assertEquals([null, 0, undefined], s());
+
+s = soo.bind(42);
+assertEquals([42, 0, undefined], s());
+
+s = soo.bind("foo");
+assertEquals(["foo", 0, undefined], s());
+
+s = soo.bind(true);
+assertEquals([true, 0, undefined], s());
+
+// Test that .arguments and .caller are poisoned according to the ES5 spec.
+
+// Check that property descriptors are correct (unconfigurable, unenumerable,
+// and both get and set is the ThrowTypeError function).
+var cdesc = Object.getOwnPropertyDescriptor(f, "caller");
+var adesc = Object.getOwnPropertyDescriptor(f, "arguments");
+
+assertFalse(cdesc.enumerable);
+assertFalse(cdesc.configurable);
+
+assertFalse(adesc.enumerable);
+assertFalse(adesc.configurable);
+
+assertSame(cdesc.get, cdesc.set);
+assertSame(cdesc.get, adesc.get);
+assertSame(cdesc.get, adesc.set);
+
+assertTrue(cdesc.get instanceof Function);
+assertEquals(0, cdesc.get.length);
+assertThrows(cdesc.get, TypeError);
+
+assertThrows(function() { return f.caller; }, TypeError);
+assertThrows(function() { f.caller = 42; }, TypeError);
+assertThrows(function() { return f.arguments; }, TypeError);
+assertThrows(function() { f.arguments = 42; }, TypeError);
+
+// Shouldn't throw. Accessing the functions caller must throw if
+// the caller is strict and the callee isn't. A bound function is built-in,
+// but not considered strict.
+(function foo() { return foo.caller; }).bind()();
diff --git a/test/mjsunit/function-call.js b/test/mjsunit/function-call.js
index 06479ad4..26890ed1 100644
--- a/test/mjsunit/function-call.js
+++ b/test/mjsunit/function-call.js
@@ -68,8 +68,7 @@ var should_throw_on_null_and_undefined =
String.prototype.toUpperCase,
String.prototype.toLocaleUpperCase,
String.prototype.trim,
- Number.prototype.toLocaleString,
- Error.prototype.toString];
+ Number.prototype.toLocaleString];
// Non generic natives do not work on any input other than the specific
// type, but since this change will allow call to be invoked with undefined
@@ -134,7 +133,8 @@ var non_generic =
Date.prototype.toJSON,
RegExp.prototype.exec,
RegExp.prototype.test,
- RegExp.prototype.toString];
+ RegExp.prototype.toString,
+ Error.prototype.toString];
// Mapping functions.
diff --git a/test/mjsunit/function-named-self-reference.js b/test/mjsunit/function-named-self-reference.js
new file mode 100644
index 00000000..5b03b094
--- /dev/null
+++ b/test/mjsunit/function-named-self-reference.js
@@ -0,0 +1,45 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+var fn = function fn(val) {
+ if (val) return val;
+
+ %OptimizeFunctionOnNextCall(fn);
+
+ function run(val) {
+ var res = fn((val + 1) << 1);
+
+ return res;
+ }
+
+ return run(0);
+}
+
+var res = fn();
+assertEquals(res, 2);
diff --git a/test/mjsunit/fuzz-natives.js b/test/mjsunit/fuzz-natives.js
index ff6677e6..2965e745 100644
--- a/test/mjsunit/fuzz-natives.js
+++ b/test/mjsunit/fuzz-natives.js
@@ -163,6 +163,9 @@ var knownProblems = {
"PromoteScheduledException": true,
"DeleteHandleScopeExtensions": true,
+ // Vararg with minimum number > 0.
+ "Call": true,
+
// Requires integer arguments to be non-negative.
"Apply": true,
@@ -181,8 +184,9 @@ var knownProblems = {
"RegExpConstructResult": true,
"_RegExpConstructResult": true,
- // This function performs some checks compile time (it requires its first
- // argument to be a compile time smi).
+ // This functions perform some checks compile time (they require one of their
+ // arguments to be a compile time smi).
+ "_DateField": true,
"_GetFromCache": true,
// This function expects its first argument to be a non-smi.
diff --git a/test/mjsunit/get-own-property-descriptor.js b/test/mjsunit/get-own-property-descriptor.js
index abb24200..159c63bc 100644
--- a/test/mjsunit/get-own-property-descriptor.js
+++ b/test/mjsunit/get-own-property-descriptor.js
@@ -73,7 +73,7 @@ assertEquals(descObjectElement.value, 42);
var a = new String('foobar');
for (var i = 0; i < a.length; i++) {
var descStringObject = Object.getOwnPropertyDescriptor(a, i);
- assertFalse(descStringObject.enumerable);
+ assertTrue(descStringObject.enumerable);
assertFalse(descStringObject.configurable);
assertFalse(descStringObject.writable);
assertEquals(descStringObject.value, a.substring(i, i+1));
diff --git a/test/mjsunit/getter-in-value-prototype.js b/test/mjsunit/getter-in-value-prototype.js
index b55320ac..abe2cb19 100644
--- a/test/mjsunit/getter-in-value-prototype.js
+++ b/test/mjsunit/getter-in-value-prototype.js
@@ -31,5 +31,5 @@
// JSObject.
String.prototype.__defineGetter__('x', function() { return this; });
-assertEquals('asdf', 'asdf'.x);
+assertEquals(Object('asdf'), 'asdf'.x);
diff --git a/test/mjsunit/global-const-var-conflicts.js b/test/mjsunit/global-const-var-conflicts.js
index d38d0ee8..2fca96f9 100644
--- a/test/mjsunit/global-const-var-conflicts.js
+++ b/test/mjsunit/global-const-var-conflicts.js
@@ -26,7 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Check that dynamically introducing conflicting consts/vars
-// leads to exceptions.
+// is silently ignored (and does not lead to exceptions).
var caught = 0;
@@ -46,12 +46,12 @@ eval("var c");
try { eval("const c"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
assertTrue(typeof c == 'undefined');
try { eval("const c = 1"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
-assertTrue(typeof c == 'undefined');
+assertEquals(1, c);
eval("var d = 0");
try { eval("const d"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
-assertEquals(0, d);
+assertEquals(undefined, d);
try { eval("const d = 1"); } catch (e) { caught++; assertTrue(e instanceof TypeError); }
-assertEquals(0, d);
+assertEquals(1, d);
-assertEquals(8, caught);
+assertEquals(0, caught);
diff --git a/test/mjsunit/harmony/block-conflicts.js b/test/mjsunit/harmony/block-conflicts.js
index 8d3de6f9..8388504b 100644
--- a/test/mjsunit/harmony/block-conflicts.js
+++ b/test/mjsunit/harmony/block-conflicts.js
@@ -25,10 +25,13 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-block-scoping
+// Flags: --harmony-scoping
// Test for conflicting variable bindings.
+// TODO(ES6): properly activate extended mode
+"use strict";
+
function CheckException(e) {
var string = e.toString();
assertTrue(string.indexOf("has already been declared") >= 0 ||
@@ -80,6 +83,11 @@ var letbinds = [ "let x",
"let x = function() {}",
"let x, y",
"let y, x",
+ "const x = 0",
+ "const x = undefined",
+ "const x = function() {}",
+ "const x = 2, y = 3",
+ "const y = 4, x = 5",
];
var varbinds = [ "var x",
"var x = 0",
@@ -122,5 +130,5 @@ for (var v = 0; v < varbinds.length; ++v) {
// Test conflicting parameter/var bindings.
for (var v = 0; v < varbinds.length; ++v) {
- TestConflict('(function (x) { ' + varbinds[v] + '; })()');
+ TestNoConflict('(function (x) { ' + varbinds[v] + '; })()');
}
diff --git a/test/mjsunit/harmony/block-const-assign.js b/test/mjsunit/harmony/block-const-assign.js
new file mode 100644
index 00000000..8297a558
--- /dev/null
+++ b/test/mjsunit/harmony/block-const-assign.js
@@ -0,0 +1,131 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-scoping
+
+// Test that we throw early syntax errors in harmony mode
+// when using an immutable binding in an assigment or with
+// prefix/postfix decrement/increment operators.
+// TODO(ES6): properly activate extended mode
+"use strict";
+
+
+// Function local const.
+function constDecl0(use) {
+ return "(function() { const constvar = 1; " + use + "; });";
+}
+
+
+function constDecl1(use) {
+ return "(function() { " + use + "; const constvar = 1; });";
+}
+
+
+// Function local const, assign from eval.
+function constDecl2(use) {
+ use = "eval('(function() { " + use + " })')";
+ return "(function() { const constvar = 1; " + use + "; })();";
+}
+
+
+function constDecl3(use) {
+ use = "eval('(function() { " + use + " })')";
+ return "(function() { " + use + "; const constvar = 1; })();";
+}
+
+
+// Block local const.
+function constDecl4(use) {
+ return "(function() { { const constvar = 1; " + use + "; } });";
+}
+
+
+function constDecl5(use) {
+ return "(function() { { " + use + "; const constvar = 1; } });";
+}
+
+
+// Block local const, assign from eval.
+function constDecl6(use) {
+ use = "eval('(function() {" + use + "})')";
+ return "(function() { { const constvar = 1; " + use + "; } })();";
+}
+
+
+function constDecl7(use) {
+ use = "eval('(function() {" + use + "})')";
+ return "(function() { { " + use + "; const constvar = 1; } })();";
+}
+
+
+// Function expression name.
+function constDecl8(use) {
+ return "(function constvar() { " + use + "; });";
+}
+
+
+// Function expression name, assign from eval.
+function constDecl9(use) {
+ use = "eval('(function(){" + use + "})')";
+ return "(function constvar() { " + use + "; })();";
+}
+
+let decls = [ constDecl0,
+ constDecl1,
+ constDecl2,
+ constDecl3,
+ constDecl4,
+ constDecl5,
+ constDecl6,
+ constDecl7,
+ constDecl8,
+ constDecl9
+ ];
+let uses = [ 'constvar = 1;',
+ 'constvar += 1;',
+ '++constvar;',
+ 'constvar++;'
+ ];
+
+function Test(d,u) {
+ 'use strict';
+ try {
+ print(d(u));
+ eval(d(u));
+ } catch (e) {
+ assertInstanceof(e, SyntaxError);
+ assertTrue(e.toString().indexOf("Assignment to constant variable") >= 0);
+ return;
+ }
+ assertUnreachable();
+}
+
+for (var d = 0; d < decls.length; ++d) {
+ for (var u = 0; u < uses.length; ++u) {
+ Test(decls[d], uses[u]);
+ }
+}
diff --git a/test/mjsunit/harmony/block-early-errors.js b/test/mjsunit/harmony/block-early-errors.js
new file mode 100644
index 00000000..791f001a
--- /dev/null
+++ b/test/mjsunit/harmony/block-early-errors.js
@@ -0,0 +1,55 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-scoping
+
+function CheckException(e) {
+ var string = e.toString();
+ assertInstanceof(e, SyntaxError);
+ assertTrue(string.indexOf("Illegal let") >= 0);
+}
+
+function Check(str) {
+ try {
+ eval("(function () { " + str + " })");
+ assertUnreachable();
+ } catch (e) {
+ CheckException(e);
+ }
+ try {
+ eval("(function () { { " + str + " } })");
+ assertUnreachable();
+ } catch (e) {
+ CheckException(e);
+ }
+}
+
+// Check for early syntax errors when using let
+// declarations outside of extended mode.
+Check("let x;");
+Check("let x = 1;");
+Check("let x, y;");
diff --git a/test/mjsunit/harmony/block-for.js b/test/mjsunit/harmony/block-for.js
new file mode 100644
index 00000000..e84f0d2f
--- /dev/null
+++ b/test/mjsunit/harmony/block-for.js
@@ -0,0 +1,146 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-scoping
+
+// TODO(ES6): properly activate extended mode
+"use strict";
+
+function props(x) {
+ var array = [];
+ for (let p in x) array.push(p);
+ return array.sort();
+}
+
+assertEquals(0, props({}).length);
+assertEquals(1, props({x:1}).length);
+assertEquals(2, props({x:1, y:2}).length);
+
+assertArrayEquals(["x"], props({x:1}));
+assertArrayEquals(["x", "y"], props({x:1, y:2}));
+assertArrayEquals(["x", "y", "zoom"], props({x:1, y:2, zoom:3}));
+
+assertEquals(0, props([]).length);
+assertEquals(1, props([1]).length);
+assertEquals(2, props([1,2]).length);
+
+assertArrayEquals(["0"], props([1]));
+assertArrayEquals(["0", "1"], props([1,2]));
+assertArrayEquals(["0", "1", "2"], props([1,2,3]));
+
+var o = {};
+var a = [];
+let i = "outer_i";
+let s = "outer_s";
+for (let i = 0x0020; i < 0x01ff; i+=2) {
+ let s = 'char:' + String.fromCharCode(i);
+ a.push(s);
+ o[s] = i;
+}
+assertArrayEquals(a, props(o));
+assertEquals(i, "outer_i");
+assertEquals(s, "outer_s");
+
+var a = [];
+assertEquals(0, props(a).length);
+a[Math.pow(2,30)-1] = 0;
+assertEquals(1, props(a).length);
+a[Math.pow(2,31)-1] = 0;
+assertEquals(2, props(a).length);
+a[1] = 0;
+assertEquals(3, props(a).length);
+
+var result = '';
+for (let p in {a : [0], b : 1}) { result += p; }
+assertEquals('ab', result);
+
+var result = '';
+for (let p in {a : {v:1}, b : 1}) { result += p; }
+assertEquals('ab', result);
+
+var result = '';
+for (let p in { get a() {}, b : 1}) { result += p; }
+assertEquals('ab', result);
+
+var result = '';
+for (let p in { get a() {}, set a(x) {}, b : 1}) { result += p; }
+assertEquals('ab', result);
+
+
+// Check that there is exactly one variable without initializer
+// in a for-in statement with let variables.
+// TODO(ES6): properly activate extended mode
+assertThrows("function foo() { 'use strict'; for (let in {}) { } }", SyntaxError);
+assertThrows("function foo() { 'use strict'; for (let x = 3 in {}) { } }", SyntaxError);
+assertThrows("function foo() { 'use strict'; for (let x, y in {}) { } }", SyntaxError);
+assertThrows("function foo() { 'use strict'; for (let x = 3, y in {}) { } }", SyntaxError);
+assertThrows("function foo() { 'use strict'; for (let x, y = 4 in {}) { } }", SyntaxError);
+assertThrows("function foo() { 'use strict'; for (let x = 3, y = 4 in {}) { } }", SyntaxError);
+
+
+// In a normal for statement the iteration variable is not
+// freshly allocated for each iteration.
+function closures1() {
+ let a = [];
+ for (let i = 0; i < 5; ++i) {
+ a.push(function () { return i; });
+ }
+ for (let j = 0; j < 5; ++j) {
+ assertEquals(5, a[j]());
+ }
+}
+closures1();
+
+
+function closures2() {
+ let a = [], b = [];
+ for (let i = 0, j = 10; i < 5; ++i, ++j) {
+ a.push(function () { return i; });
+ b.push(function () { return j; });
+ }
+ for (let k = 0; k < 5; ++k) {
+ assertEquals(5, a[k]());
+ assertEquals(15, b[k]());
+ }
+}
+closures2();
+
+
+// In a for-in statement the iteration variable is fresh
+// for earch iteration.
+function closures3(x) {
+ let a = [];
+ for (let p in x) {
+ a.push(function () { return p; });
+ }
+ let k = 0;
+ for (let q in x) {
+ assertEquals(q, a[k]());
+ ++k;
+ }
+}
+closures3({a : [0], b : 1, c : {v : 1}, get d() {}, set e(x) {}});
diff --git a/test/mjsunit/harmony/block-leave.js b/test/mjsunit/harmony/block-leave.js
index 73eaf294..a7f6b694 100644
--- a/test/mjsunit/harmony/block-leave.js
+++ b/test/mjsunit/harmony/block-leave.js
@@ -25,7 +25,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-block-scoping
+// Flags: --harmony-scoping
+
+// TODO(ES6): properly activate extended mode
+"use strict";
// We want to test the context chain shape. In each of the tests cases
// below, the outer with is to force a runtime lookup of the identifier 'x'
@@ -64,31 +67,30 @@ try {
} catch (e) {
caught = true;
assertEquals(25, e);
- with ({y:19}) {
- assertEquals(19, y);
+ (function () {
try {
// NOTE: This checks that the block scope containing xx has been
// removed from the context chain.
- xx;
+ eval('xx');
assertTrue(false); // should not reach here
} catch (e2) {
assertTrue(e2 instanceof ReferenceError);
}
- }
+ })();
}
assertTrue(caught);
-with ({x: 'outer'}) {
+(function(x) {
label: {
let x = 'inner';
break label;
}
- assertEquals('outer', x);
-}
+ assertEquals('outer', eval('x'));
+})('outer');
-with ({x: 'outer'}) {
+(function(x) {
label: {
let x = 'middle';
{
@@ -96,20 +98,20 @@ with ({x: 'outer'}) {
break label;
}
}
- assertEquals('outer', x);
-}
+ assertEquals('outer', eval('x'));
+})('outer');
-with ({x: 'outer'}) {
+(function(x) {
for (var i = 0; i < 10; ++i) {
let x = 'inner' + i;
continue;
}
- assertEquals('outer', x);
-}
+ assertEquals('outer', eval('x'));
+})('outer');
-with ({x: 'outer'}) {
+(function(x) {
label: for (var i = 0; i < 10; ++i) {
let x = 'middle' + i;
for (var j = 0; j < 10; ++j) {
@@ -117,21 +119,21 @@ with ({x: 'outer'}) {
continue label;
}
}
- assertEquals('outer', x);
-}
+ assertEquals('outer', eval('x'));
+})('outer');
-with ({x: 'outer'}) {
+(function(x) {
try {
let x = 'inner';
throw 0;
} catch (e) {
- assertEquals('outer', x);
+ assertEquals('outer', eval('x'));
}
-}
+})('outer');
-with ({x: 'outer'}) {
+(function(x) {
try {
let x = 'middle';
{
@@ -139,27 +141,27 @@ with ({x: 'outer'}) {
throw 0;
}
} catch (e) {
- assertEquals('outer', x);
+ assertEquals('outer', eval('x'));
}
-}
+})('outer');
try {
- with ({x: 'outer'}) {
+ (function(x) {
try {
let x = 'inner';
throw 0;
} finally {
- assertEquals('outer', x);
+ assertEquals('outer', eval('x'));
}
- }
+ })('outer');
} catch (e) {
if (e instanceof MjsUnitAssertionError) throw e;
}
try {
- with ({x: 'outer'}) {
+ (function(x) {
try {
let x = 'middle';
{
@@ -167,9 +169,9 @@ try {
throw 0;
}
} finally {
- assertEquals('outer', x);
+ assertEquals('outer', eval('x'));
}
- }
+ })('outer');
} catch (e) {
if (e instanceof MjsUnitAssertionError) throw e;
}
@@ -179,47 +181,47 @@ try {
// from with.
function f() {}
-with ({x: 'outer'}) {
+(function(x) {
label: {
let x = 'inner';
break label;
}
f(); // The context could be restored from the stack after the call.
- assertEquals('outer', x);
-}
+ assertEquals('outer', eval('x'));
+})('outer');
-with ({x: 'outer'}) {
+(function(x) {
for (var i = 0; i < 10; ++i) {
let x = 'inner';
continue;
}
f();
- assertEquals('outer', x);
-}
+ assertEquals('outer', eval('x'));
+})('outer');
-with ({x: 'outer'}) {
+(function(x) {
try {
let x = 'inner';
throw 0;
} catch (e) {
f();
- assertEquals('outer', x);
+ assertEquals('outer', eval('x'));
}
-}
+})('outer');
try {
- with ({x: 'outer'}) {
+ (function(x) {
try {
let x = 'inner';
throw 0;
} finally {
f();
- assertEquals('outer', x);
+ assertEquals('outer', eval('x'));
}
- }
+ })('outer');
} catch (e) {
if (e instanceof MjsUnitAssertionError) throw e;
}
diff --git a/test/mjsunit/harmony/block-let-crankshaft.js b/test/mjsunit/harmony/block-let-crankshaft.js
index c2fb96b6..1db1792e 100644
--- a/test/mjsunit/harmony/block-let-crankshaft.js
+++ b/test/mjsunit/harmony/block-let-crankshaft.js
@@ -25,10 +25,209 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-block-scoping --allow-natives-syntax
+// Flags: --harmony-scoping --allow-natives-syntax
+
+// TODO(ES6): properly activate extended mode
+"use strict";
+
+// Check that the following functions are optimizable.
+var functions = [ f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14,
+ f15, f16, f17, f18, f19, f20, f21, f22, f23 ];
+
+for (var i = 0; i < functions.length; ++i) {
+ var func = functions[i];
+ print("Testing:");
+ print(func);
+ for (var j = 0; j < 10; ++j) {
+ func(12);
+ }
+ %OptimizeFunctionOnNextCall(func);
+ func(12);
+ assertTrue(%GetOptimizationStatus(func) != 2);
+}
+
+function f1() { }
+
+function f2(x) { }
+
+function f3() {
+ let x;
+}
+
+function f4() {
+ function foo() {
+ }
+}
+
+function f5() {
+ let x = 1;
+}
+
+function f6() {
+ const x = 1;
+}
+
+function f7(x) {
+ return x;
+}
+
+function f8() {
+ let x;
+ return x;
+}
+
+function f9() {
+ function x() {
+ }
+ return x;
+}
+
+function f10(x) {
+ x = 1;
+}
+
+function f11() {
+ let x;
+ x = 1;
+}
+
+function f12() {
+ function x() {};
+ x = 1;
+}
+
+function f13(x) {
+ (function() { x; });
+}
+
+function f14() {
+ let x;
+ (function() { x; });
+}
+
+function f15() {
+ function x() {
+ }
+ (function() { x; });
+}
+
+function f16() {
+ let x = 1;
+ (function() { x; });
+}
+
+function f17() {
+ const x = 1;
+ (function() { x; });
+}
+
+function f18(x) {
+ return x;
+ (function() { x; });
+}
+
+function f19() {
+ let x;
+ return x;
+ (function() { x; });
+}
+
+function f20() {
+ function x() {
+ }
+ return x;
+ (function() { x; });
+}
+
+function f21(x) {
+ x = 1;
+ (function() { x; });
+}
+
+function f22() {
+ let x;
+ x = 1;
+ (function() { x; });
+}
+
+function f23() {
+ function x() { }
+ x = 1;
+ (function() { x; });
+}
+
// Test that temporal dead zone semantics for function and block scoped
-// ket bindings are handled by the optimizing compiler.
+// let bindings are handled by the optimizing compiler.
+
+function TestFunctionLocal(s) {
+ 'use strict';
+ var func = eval("(function baz(){" + s + "; })");
+ print("Testing:");
+ print(func);
+ for (var i = 0; i < 5; ++i) {
+ try {
+ func();
+ assertUnreachable();
+ } catch (e) {
+ assertInstanceof(e, ReferenceError);
+ }
+ }
+ %OptimizeFunctionOnNextCall(func);
+ try {
+ func();
+ assertUnreachable();
+ } catch (e) {
+ assertInstanceof(e, ReferenceError);
+ }
+}
+
+function TestFunctionContext(s) {
+ 'use strict';
+ var func = eval("(function baz(){ " + s + "; (function() { x; }); })");
+ print("Testing:");
+ print(func);
+ for (var i = 0; i < 5; ++i) {
+ print(i);
+ try {
+ func();
+ assertUnreachable();
+ } catch (e) {
+ assertInstanceof(e, ReferenceError);
+ }
+ }
+ print("optimize");
+ %OptimizeFunctionOnNextCall(func);
+ try {
+ print("call");
+ func();
+ assertUnreachable();
+ } catch (e) {
+ print("catch");
+ assertInstanceof(e, ReferenceError);
+ }
+}
+
+function TestAll(s) {
+ TestFunctionLocal(s);
+ TestFunctionContext(s);
+}
+
+// Use before initialization in declaration statement.
+TestAll('let x = x + 1');
+TestAll('let x = x += 1');
+TestAll('let x = x++');
+TestAll('let x = ++x');
+TestAll('const x = x + 1');
+
+// Use before initialization in prior statement.
+TestAll('x + 1; let x;');
+TestAll('x = 1; let x;');
+TestAll('x += 1; let x;');
+TestAll('++x; let x;');
+TestAll('x++; let x;');
+TestAll('let y = x; const x = 1;');
+
function f(x, b) {
let y = (b ? y : x) + 42;
diff --git a/test/mjsunit/harmony/block-let-declaration.js b/test/mjsunit/harmony/block-let-declaration.js
index 49b63481..480e0334 100644
--- a/test/mjsunit/harmony/block-let-declaration.js
+++ b/test/mjsunit/harmony/block-let-declaration.js
@@ -25,41 +25,113 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-block-scoping
+// Flags: --harmony-scoping
// Test let declarations in various settings.
+// TODO(ES6): properly activate extended mode
+"use strict";
// Global
let x;
let y = 2;
+const z = 4;
// Block local
{
let y;
let x = 3;
+ const z = 5;
}
assertEquals(undefined, x);
assertEquals(2,y);
+assertEquals(4,z);
if (true) {
let y;
assertEquals(undefined, y);
}
+// Invalid declarations are early errors in harmony mode and thus should trigger
+// an exception in eval code during parsing, before even compiling or executing
+// the code. Thus the generated function is not called here.
function TestLocalThrows(str, expect) {
- assertThrows("(function(){" + str + "})()", expect);
+ assertThrows("(function(){ 'use strict'; " + str + "})", expect);
}
function TestLocalDoesNotThrow(str) {
- assertDoesNotThrow("(function(){" + str + "})()");
+ assertDoesNotThrow("(function(){ 'use strict'; " + str + "})()");
}
-// Unprotected statement
+// Test let declarations in statement positions.
TestLocalThrows("if (true) let x;", SyntaxError);
+TestLocalThrows("if (true) {} else let x;", SyntaxError);
TestLocalThrows("do let x; while (false)", SyntaxError);
TestLocalThrows("while (false) let x;", SyntaxError);
+TestLocalThrows("label: let x;", SyntaxError);
+TestLocalThrows("for (;false;) let x;", SyntaxError);
+TestLocalThrows("switch (true) { case true: let x; }", SyntaxError);
+TestLocalThrows("switch (true) { default: let x; }", SyntaxError);
+// Test const declarations with initialisers in statement positions.
+TestLocalThrows("if (true) const x = 1;", SyntaxError);
+TestLocalThrows("if (true) {} else const x = 1;", SyntaxError);
+TestLocalThrows("do const x = 1; while (false)", SyntaxError);
+TestLocalThrows("while (false) const x = 1;", SyntaxError);
+TestLocalThrows("label: const x = 1;", SyntaxError);
+TestLocalThrows("for (;false;) const x = 1;", SyntaxError);
+TestLocalThrows("switch (true) { case true: const x = 1; }", SyntaxError);
+TestLocalThrows("switch (true) { default: const x = 1; }", SyntaxError);
+
+// Test const declarations without initialisers.
+TestLocalThrows("const x;", SyntaxError);
+TestLocalThrows("const x = 1, y;", SyntaxError);
+TestLocalThrows("const x, y = 1;", SyntaxError);
+
+// Test const declarations without initialisers in statement positions.
+TestLocalThrows("if (true) const x;", SyntaxError);
+TestLocalThrows("if (true) {} else const x;", SyntaxError);
+TestLocalThrows("do const x; while (false)", SyntaxError);
+TestLocalThrows("while (false) const x;", SyntaxError);
+TestLocalThrows("label: const x;", SyntaxError);
+TestLocalThrows("for (;false;) const x;", SyntaxError);
+TestLocalThrows("switch (true) { case true: const x; }", SyntaxError);
+TestLocalThrows("switch (true) { default: const x; }", SyntaxError);
+
+// Test var declarations in statement positions.
TestLocalDoesNotThrow("if (true) var x;");
+TestLocalDoesNotThrow("if (true) {} else var x;");
TestLocalDoesNotThrow("do var x; while (false)");
TestLocalDoesNotThrow("while (false) var x;");
+TestLocalDoesNotThrow("label: var x;");
+TestLocalDoesNotThrow("for (;false;) var x;");
+TestLocalDoesNotThrow("switch (true) { case true: var x; }");
+TestLocalDoesNotThrow("switch (true) { default: var x; }");
+
+// Test function declarations in source element and
+// non-strict statement positions.
+function f() {
+ // Non-strict source element positions.
+ function g0() {
+ "use strict";
+ // Strict source element positions.
+ function h() { }
+ {
+ function h1() { }
+ }
+ }
+ {
+ function g1() { }
+ }
+}
+f();
+
+// Test function declarations in statement position in strict mode.
+TestLocalThrows("function f() { if (true) function g() {}", SyntaxError);
+TestLocalThrows("function f() { if (true) {} else function g() {}", SyntaxError);
+TestLocalThrows("function f() { do function g() {} while (false)", SyntaxError);
+TestLocalThrows("function f() { while (false) function g() {}", SyntaxError);
+TestLocalThrows("function f() { label: function g() {}", SyntaxError);
+TestLocalThrows("function f() { for (;false;) function g() {}", SyntaxError);
+TestLocalThrows("function f() { switch (true) { case true: function g() {} }", SyntaxError);
+TestLocalThrows("function f() { switch (true) { default: function g() {} }", SyntaxError);
diff --git a/test/mjsunit/harmony/block-let-semantics.js b/test/mjsunit/harmony/block-let-semantics.js
index 198c3b4f..d14e7cd3 100644
--- a/test/mjsunit/harmony/block-let-semantics.js
+++ b/test/mjsunit/harmony/block-let-semantics.js
@@ -25,7 +25,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --harmony-block-scoping
+// Flags: --harmony-scoping
+
+// TODO(ES6): properly activate extended mode
+"use strict";
// Test temporal dead zone semantics of let bound variables in
// function and block scopes.
@@ -61,6 +64,7 @@ TestAll('let x = x + 1');
TestAll('let x = x += 1');
TestAll('let x = x++');
TestAll('let x = ++x');
+TestAll('const x = x + 1');
// Use before initialization in prior statement.
TestAll('x + 1; let x;');
@@ -68,25 +72,36 @@ TestAll('x = 1; let x;');
TestAll('x += 1; let x;');
TestAll('++x; let x;');
TestAll('x++; let x;');
+TestAll('let y = x; const x = 1;');
TestAll('f(); let x; function f() { return x + 1; }');
TestAll('f(); let x; function f() { x = 1; }');
TestAll('f(); let x; function f() { x += 1; }');
TestAll('f(); let x; function f() { ++x; }');
TestAll('f(); let x; function f() { x++; }');
+TestAll('f(); const x = 1; function f() { return x; }');
TestAll('f()(); let x; function f() { return function() { return x + 1; } }');
TestAll('f()(); let x; function f() { return function() { x = 1; } }');
TestAll('f()(); let x; function f() { return function() { x += 1; } }');
TestAll('f()(); let x; function f() { return function() { ++x; } }');
TestAll('f()(); let x; function f() { return function() { x++; } }');
+TestAll('f()(); const x = 1; function f() { return function() { return x; } }');
-// Use in before initialization with a dynamic lookup.
+// Use before initialization with a dynamic lookup.
TestAll('eval("x + 1;"); let x;');
TestAll('eval("x = 1;"); let x;');
TestAll('eval("x += 1;"); let x;');
TestAll('eval("++x;"); let x;');
TestAll('eval("x++;"); let x;');
+TestAll('eval("x"); const x = 1;');
+
+// Use before initialization with check for eval-shadowed bindings.
+TestAll('function f() { eval("var y = 2;"); x + 1; }; f(); let x;');
+TestAll('function f() { eval("var y = 2;"); x = 1; }; f(); let x;');
+TestAll('function f() { eval("var y = 2;"); x += 1; }; f(); let x;');
+TestAll('function f() { eval("var y = 2;"); ++x; }; f(); let x;');
+TestAll('function f() { eval("var y = 2;"); x++; }; f(); let x;');
// Test that variables introduced by function declarations are created and
// initialized upon entering a function / block scope.
@@ -115,7 +130,7 @@ TestAll('{ function k() { return 0; } }; k(); ');
// Test that a function declaration sees the scope it resides in.
function f2() {
- let m, n;
+ let m, n, o, p;
{
m = g;
function g() {
@@ -132,7 +147,44 @@ function f2() {
function h() {
return b + c;
}
- let b = 3;
+ let c = 3;
}
assertEquals(5, n());
+
+ {
+ o = i;
+ function i() {
+ return d;
+ }
+ let d = 4;
+ }
+ assertEquals(4, o());
+
+ try {
+ throw 5;
+ } catch(e) {
+ p = j;
+ function j() {
+ return e + f;
+ }
+ let f = 6;
+ }
+ assertEquals(11, p());
+}
+f2();
+
+// Test that resolution of let bound variables works with scopes that call eval.
+function outer() {
+ function middle() {
+ function inner() {
+ return x;
+ }
+ eval("1 + 1");
+ return x + inner();
+ }
+
+ let x = 1;
+ return middle();
}
+
+assertEquals(2, outer());
diff --git a/test/mjsunit/harmony/block-scoping.js b/test/mjsunit/harmony/block-scoping.js
index 266e3807..31194d99 100644
--- a/test/mjsunit/harmony/block-scoping.js
+++ b/test/mjsunit/harmony/block-scoping.js
@@ -25,9 +25,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --allow-natives-syntax --harmony-block-scoping
+// Flags: --allow-natives-syntax --harmony-scoping
// Test functionality of block scopes.
+// TODO(ES6): properly activate extended mode
+"use strict";
+
// Hoisting of var declarations.
function f1() {
{
@@ -44,12 +47,16 @@ f1();
function f2(one) {
var x = one + 1;
let y = one + 2;
+ const u = one + 4;
{
let z = one + 3;
+ const v = one + 5;
assertEquals(1, eval('one'));
assertEquals(2, eval('x'));
assertEquals(3, eval('y'));
assertEquals(4, eval('z'));
+ assertEquals(5, eval('u'));
+ assertEquals(6, eval('v'));
}
}
f2(1);
@@ -59,12 +66,17 @@ f2(1);
function f3(one) {
var x = one + 1;
let y = one + 2;
+ const u = one + 4;
{
let z = one + 3;
+ const v = one + 5;
assertEquals(1, one);
assertEquals(2, x);
assertEquals(3, y);
assertEquals(4, z);
+ assertEquals(5, u);
+ assertEquals(6, v);
+
}
}
f3(1);
@@ -74,13 +86,17 @@ f3(1);
function f4(one) {
var x = one + 1;
let y = one + 2;
+ const u = one + 4;
{
let z = one + 3;
+ const v = one + 5;
function f() {
assertEquals(1, eval('one'));
assertEquals(2, eval('x'));
assertEquals(3, eval('y'));
assertEquals(4, eval('z'));
+ assertEquals(5, eval('u'));
+ assertEquals(6, eval('v'));
};
}
}
@@ -91,13 +107,17 @@ f4(1);
function f5(one) {
var x = one + 1;
let y = one + 2;
+ const u = one + 4;
{
let z = one + 3;
+ const v = one + 5;
function f() {
assertEquals(1, one);
assertEquals(2, x);
assertEquals(3, y);
assertEquals(4, z);
+ assertEquals(5, u);
+ assertEquals(6, v);
};
}
}
@@ -107,8 +127,10 @@ f5(1);
// Return from block.
function f6() {
let x = 1;
+ const u = 3;
{
let y = 2;
+ const v = 4;
return x + y;
}
}
@@ -120,13 +142,26 @@ function f7(a) {
let b = 1;
var c = 1;
var d = 1;
- { // let variables shadowing argument, let and var variables
+ const e = 1;
+ { // let variables shadowing argument, let, const and var variables
let a = 2;
let b = 2;
let c = 2;
+ let e = 2;
+ assertEquals(2,a);
+ assertEquals(2,b);
+ assertEquals(2,c);
+ assertEquals(2,e);
+ }
+ { // const variables shadowing argument, let, const and var variables
+ const a = 2;
+ const b = 2;
+ const c = 2;
+ const e = 2;
assertEquals(2,a);
assertEquals(2,b);
assertEquals(2,c);
+ assertEquals(2,e);
}
try {
throw 'stuff1';
@@ -156,6 +191,12 @@ function f7(a) {
} catch (c) {
// catch variable shadowing var variable
assertEquals('stuff3',c);
+ {
+ // const variable shadowing catch variable
+ const c = 3;
+ assertEquals(3,c);
+ }
+ assertEquals('stuff3',c);
try {
throw 'stuff4';
} catch(c) {
@@ -178,14 +219,16 @@ function f7(a) {
c = 2;
}
assertEquals(1,c);
- (function(a,b,c) {
- // arguments shadowing argument, let and var variable
+ (function(a,b,c,e) {
+ // arguments shadowing argument, let, const and var variable
a = 2;
b = 2;
c = 2;
+ e = 2;
assertEquals(2,a);
assertEquals(2,b);
assertEquals(2,c);
+ assertEquals(2,e);
// var variable shadowing var variable
var d = 2;
})(1,1);
@@ -193,24 +236,30 @@ function f7(a) {
assertEquals(1,b);
assertEquals(1,c);
assertEquals(1,d);
+ assertEquals(1,e);
}
f7(1);
-// Ensure let variables are block local and var variables function local.
+// Ensure let and const variables are block local
+// and var variables function local.
function f8() {
var let_accessors = [];
var var_accessors = [];
+ var const_accessors = [];
for (var i = 0; i < 10; i++) {
let x = i;
var y = i;
+ const z = i;
let_accessors[i] = function() { return x; }
var_accessors[i] = function() { return y; }
+ const_accessors[i] = function() { return z; }
}
for (var j = 0; j < 10; j++) {
y = j + 10;
assertEquals(j, let_accessors[j]());
assertEquals(y, var_accessors[j]());
+ assertEquals(j, const_accessors[j]());
}
}
f8();
diff --git a/test/mjsunit/harmony/collections.js b/test/mjsunit/harmony/collections.js
new file mode 100644
index 00000000..412e6f14
--- /dev/null
+++ b/test/mjsunit/harmony/collections.js
@@ -0,0 +1,314 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-collections --expose-gc
+
+
+// Test valid getter and setter calls on Sets.
+function TestValidSetCalls(m) {
+ assertDoesNotThrow(function () { m.add(new Object) });
+ assertDoesNotThrow(function () { m.has(new Object) });
+ assertDoesNotThrow(function () { m.delete(new Object) });
+}
+TestValidSetCalls(new Set);
+
+
+// Test valid getter and setter calls on Maps and WeakMaps
+function TestValidMapCalls(m) {
+ assertDoesNotThrow(function () { m.get(new Object) });
+ assertDoesNotThrow(function () { m.set(new Object) });
+ assertDoesNotThrow(function () { m.has(new Object) });
+ assertDoesNotThrow(function () { m.delete(new Object) });
+}
+TestValidMapCalls(new Map);
+TestValidMapCalls(new WeakMap);
+
+
+// Test invalid getter and setter calls for WeakMap only
+function TestInvalidCalls(m) {
+ assertThrows(function () { m.get(undefined) }, TypeError);
+ assertThrows(function () { m.set(undefined, 0) }, TypeError);
+ assertThrows(function () { m.get(null) }, TypeError);
+ assertThrows(function () { m.set(null, 0) }, TypeError);
+ assertThrows(function () { m.get(0) }, TypeError);
+ assertThrows(function () { m.set(0, 0) }, TypeError);
+ assertThrows(function () { m.get('a-key') }, TypeError);
+ assertThrows(function () { m.set('a-key', 0) }, TypeError);
+}
+TestInvalidCalls(new WeakMap);
+
+
+// Test expected behavior for Sets
+function TestSet(set, key) {
+ assertFalse(set.has(key));
+ set.add(key);
+ assertTrue(set.has(key));
+ set.delete(key);
+ assertFalse(set.has(key));
+}
+function TestSetBehavior(set) {
+ for (var i = 0; i < 20; i++) {
+ TestSet(set, new Object);
+ TestSet(set, i);
+ TestSet(set, i / 100);
+ TestSet(set, 'key-' + i);
+ }
+ var keys = [ +0, -0, +Infinity, -Infinity, true, false, null, undefined ];
+ for (var i = 0; i < keys.length; i++) {
+ TestSet(set, keys[i]);
+ }
+}
+TestSetBehavior(new Set);
+
+
+// Test expected mapping behavior for Maps and WeakMaps
+function TestMapping(map, key, value) {
+ map.set(key, value);
+ assertSame(value, map.get(key));
+}
+function TestMapBehavior1(m) {
+ TestMapping(m, new Object, 23);
+ TestMapping(m, new Object, 'the-value');
+ TestMapping(m, new Object, new Object);
+}
+TestMapBehavior1(new Map);
+TestMapBehavior1(new WeakMap);
+
+
+// Test expected mapping behavior for Maps only
+function TestMapBehavior2(m) {
+ for (var i = 0; i < 20; i++) {
+ TestMapping(m, i, new Object);
+ TestMapping(m, i / 10, new Object);
+ TestMapping(m, 'key-' + i, new Object);
+ }
+ var keys = [ +0, -0, +Infinity, -Infinity, true, false, null, undefined ];
+ for (var i = 0; i < keys.length; i++) {
+ TestMapping(m, keys[i], new Object);
+ }
+}
+TestMapBehavior2(new Map);
+
+
+// Test expected querying behavior of Maps and WeakMaps
+function TestQuery(m) {
+ var key = new Object;
+ TestMapping(m, key, 'to-be-present');
+ assertTrue(m.has(key));
+ assertFalse(m.has(new Object));
+ TestMapping(m, key, undefined);
+ assertFalse(m.has(key));
+ assertFalse(m.has(new Object));
+}
+TestQuery(new Map);
+TestQuery(new WeakMap);
+
+
+// Test expected deletion behavior of Maps and WeakMaps
+function TestDelete(m) {
+ var key = new Object;
+ TestMapping(m, key, 'to-be-deleted');
+ assertTrue(m.delete(key));
+ assertFalse(m.delete(key));
+ assertFalse(m.delete(new Object));
+ assertSame(m.get(key), undefined);
+}
+TestDelete(new Map);
+TestDelete(new WeakMap);
+
+
+// Test GC of Maps and WeakMaps with entry
+function TestGC1(m) {
+ var key = new Object;
+ m.set(key, 'not-collected');
+ gc();
+ assertSame('not-collected', m.get(key));
+}
+TestGC1(new Map);
+TestGC1(new WeakMap);
+
+
+// Test GC of Maps and WeakMaps with chained entries
+function TestGC2(m) {
+ var head = new Object;
+ for (key = head, i = 0; i < 10; i++, key = m.get(key)) {
+ m.set(key, new Object);
+ }
+ gc();
+ var count = 0;
+ for (key = head; key != undefined; key = m.get(key)) {
+ count++;
+ }
+ assertEquals(11, count);
+}
+TestGC2(new Map);
+TestGC2(new WeakMap);
+
+
+// Test property attribute [[Enumerable]]
+function TestEnumerable(func) {
+ function props(x) {
+ var array = [];
+ for (var p in x) array.push(p);
+ return array.sort();
+ }
+ assertArrayEquals([], props(func));
+ assertArrayEquals([], props(func.prototype));
+ assertArrayEquals([], props(new func()));
+}
+TestEnumerable(Set);
+TestEnumerable(Map);
+TestEnumerable(WeakMap);
+
+
+// Test arbitrary properties on Maps and WeakMaps
+function TestArbitrary(m) {
+ function TestProperty(map, property, value) {
+ map[property] = value;
+ assertEquals(value, map[property]);
+ }
+ for (var i = 0; i < 20; i++) {
+ TestProperty(m, i, 'val' + i);
+ TestProperty(m, 'foo' + i, 'bar' + i);
+ }
+ TestMapping(m, new Object, 'foobar');
+}
+TestArbitrary(new Map);
+TestArbitrary(new WeakMap);
+
+
+// Test direct constructor call
+assertTrue(Set() instanceof Set);
+assertTrue(Map() instanceof Map);
+assertTrue(WeakMap() instanceof WeakMap);
+
+
+// Test whether NaN values as keys are treated correctly.
+var s = new Set;
+assertFalse(s.has(NaN));
+assertFalse(s.has(NaN + 1));
+assertFalse(s.has(23));
+s.add(NaN);
+assertTrue(s.has(NaN));
+assertTrue(s.has(NaN + 1));
+assertFalse(s.has(23));
+var m = new Map;
+assertFalse(m.has(NaN));
+assertFalse(m.has(NaN + 1));
+assertFalse(m.has(23));
+m.set(NaN, 'a-value');
+assertTrue(m.has(NaN));
+assertTrue(m.has(NaN + 1));
+assertFalse(m.has(23));
+
+
+// Test some common JavaScript idioms for Sets
+var s = new Set;
+assertTrue(s instanceof Set);
+assertTrue(Set.prototype.add instanceof Function)
+assertTrue(Set.prototype.has instanceof Function)
+assertTrue(Set.prototype.delete instanceof Function)
+
+
+// Test some common JavaScript idioms for Maps
+var m = new Map;
+assertTrue(m instanceof Map);
+assertTrue(Map.prototype.set instanceof Function)
+assertTrue(Map.prototype.get instanceof Function)
+assertTrue(Map.prototype.has instanceof Function)
+assertTrue(Map.prototype.delete instanceof Function)
+
+
+// Test some common JavaScript idioms for WeakMaps
+var m = new WeakMap;
+assertTrue(m instanceof WeakMap);
+assertTrue(WeakMap.prototype.set instanceof Function)
+assertTrue(WeakMap.prototype.get instanceof Function)
+assertTrue(WeakMap.prototype.has instanceof Function)
+assertTrue(WeakMap.prototype.delete instanceof Function)
+
+
+// Regression test for WeakMap prototype.
+assertTrue(WeakMap.prototype.constructor === WeakMap)
+assertTrue(Object.getPrototypeOf(WeakMap.prototype) === Object.prototype)
+
+
+// Regression test for issue 1617: The prototype of the WeakMap constructor
+// needs to be unique (i.e. different from the one of the Object constructor).
+assertFalse(WeakMap.prototype === Object.prototype);
+var o = Object.create({});
+assertFalse("get" in o);
+assertFalse("set" in o);
+assertEquals(undefined, o.get);
+assertEquals(undefined, o.set);
+var o = Object.create({}, { myValue: {
+ value: 10,
+ enumerable: false,
+ configurable: true,
+ writable: true
+}});
+assertEquals(10, o.myValue);
+
+
+// Regression test for issue 1884: Invoking any of the methods for Harmony
+// maps, sets, or weak maps, with a wrong type of receiver should be throwing
+// a proper TypeError.
+var alwaysBogus = [ undefined, null, true, "x", 23, {} ];
+var bogusReceiversTestSet = [
+ { proto: Set.prototype,
+ funcs: [ 'add', 'has', 'delete' ],
+ receivers: alwaysBogus.concat([ new Map, new WeakMap ]),
+ },
+ { proto: Map.prototype,
+ funcs: [ 'get', 'set', 'has', 'delete' ],
+ receivers: alwaysBogus.concat([ new Set, new WeakMap ]),
+ },
+ { proto: WeakMap.prototype,
+ funcs: [ 'get', 'set', 'has', 'delete' ],
+ receivers: alwaysBogus.concat([ new Set, new Map ]),
+ },
+];
+function TestBogusReceivers(testSet) {
+ for (var i = 0; i < testSet.length; i++) {
+ var proto = testSet[i].proto;
+ var funcs = testSet[i].funcs;
+ var receivers = testSet[i].receivers;
+ for (var j = 0; j < funcs.length; j++) {
+ var func = proto[funcs[j]];
+ for (var k = 0; k < receivers.length; k++) {
+ assertThrows(function () { func.call(receivers[k], {}) }, TypeError);
+ }
+ }
+ }
+}
+TestBogusReceivers(bogusReceiversTestSet);
+
+
+// Stress Test
+// There is a proposed stress-test available at the es-discuss mailing list
+// which cannot be reasonably automated. Check it out by hand if you like:
+// https://mail.mozilla.org/pipermail/es-discuss/2011-May/014096.html \ No newline at end of file
diff --git a/test/mjsunit/harmony/debug-blockscopes.js b/test/mjsunit/harmony/debug-blockscopes.js
index 0230e84b..10aac2db 100644
--- a/test/mjsunit/harmony/debug-blockscopes.js
+++ b/test/mjsunit/harmony/debug-blockscopes.js
@@ -25,13 +25,15 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --expose-debug-as debug --harmony-block-scoping
+// Flags: --expose-debug-as debug --harmony-scoping
// The functions used for testing backtraces. They are at the top to make the
// testing of source line/column easier.
+// TODO(ES6): properly activate extended mode
+"use strict";
// Get the Debug object exposed from the debug context global object.
-Debug = debug.Debug;
+var Debug = debug.Debug;
var test_name;
var listener_delegate;
@@ -76,6 +78,7 @@ function EndTest() {
end_test_count++;
}
+var global_object = this;
// Check that the scope chain contains the expected types of scopes.
function CheckScopeChain(scopes, exec_state) {
@@ -89,7 +92,7 @@ function CheckScopeChain(scopes, exec_state) {
if (scopes[i] == debug.ScopeType.Global) {
// Objects don't have same class (one is "global", other is "Object",
// so just check the properties directly.
- assertPropertiesEqual(this, scope.scopeObject().value());
+ assertPropertiesEqual(global_object, scope.scopeObject().value());
}
}
@@ -329,138 +332,139 @@ local_7(1);
EndTest();
-// Single empty with block.
-BeginTest("With block 1");
+// Simple closure formed by returning an inner function referering to an outer
+// block local variable and an outer function's parameter.
+BeginTest("Closure 1");
-function with_block_1() {
- with({}) {
- debugger;
+function closure_1(a) {
+ var x = 2;
+ let y = 3;
+ if (true) {
+ let z = 4;
+ function f() {
+ debugger;
+ return a + x + y + z;
+ };
+ return f;
}
}
listener_delegate = function(exec_state) {
- CheckScopeChain([debug.ScopeType.With,
- debug.ScopeType.Local,
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Block,
+ debug.ScopeType.Closure,
debug.ScopeType.Global], exec_state);
CheckScopeContent({}, 0, exec_state);
- CheckScopeContent({}, 1, exec_state);
+ CheckScopeContent({a:1,x:2,y:3}, 2, exec_state);
};
-with_block_1();
+closure_1(1)();
EndTest();
-// Nested empty with blocks.
-BeginTest("With block 2");
+// Simple for-in loop over the keys of an object.
+BeginTest("For loop 1");
-function with_block_2() {
- with({}) {
- with({}) {
- debugger;
- }
+function for_loop_1() {
+ for (let x in {y:undefined}) {
+ debugger;
}
}
listener_delegate = function(exec_state) {
- CheckScopeChain([debug.ScopeType.With,
- debug.ScopeType.With,
+ CheckScopeChain([debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Global], exec_state);
- CheckScopeContent({}, 0, exec_state);
- CheckScopeContent({}, 1, exec_state);
- CheckScopeContent({}, 2, exec_state);
+ CheckScopeContent({x:'y'}, 0, exec_state);
+ // The function scope contains a temporary iteration variable.
+ CheckScopeContent({x:'y'}, 1, exec_state);
};
-with_block_2();
+for_loop_1();
EndTest();
-// With block using an in-place object literal.
-BeginTest("With block 3");
+// For-in loop over the keys of an object with a block scoped let variable
+// shadowing the iteration variable.
+BeginTest("For loop 2");
-function with_block_3() {
- with({a:1,b:2}) {
+function for_loop_2() {
+ for (let x in {y:undefined}) {
+ let x = 3;
debugger;
}
}
listener_delegate = function(exec_state) {
- CheckScopeChain([debug.ScopeType.With,
+ CheckScopeChain([debug.ScopeType.Block,
+ debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Global], exec_state);
- CheckScopeContent({a:1,b:2}, 0, exec_state);
+ CheckScopeContent({x:3}, 0, exec_state);
+ CheckScopeContent({x:'y'}, 1, exec_state);
+ // The function scope contains a temporary iteration variable.
+ CheckScopeContent({x:'y'}, 2, exec_state);
};
-with_block_3();
+for_loop_2();
EndTest();
-// Nested with blocks using in-place object literals.
-BeginTest("With block 4");
+// Simple for loop.
+BeginTest("For loop 3");
-function with_block_4() {
- with({a:1,b:2}) {
- with({a:2,b:1}) {
- debugger;
- }
+function for_loop_3() {
+ for (let x = 3; x < 4; ++x) {
+ debugger;
}
}
listener_delegate = function(exec_state) {
- CheckScopeChain([debug.ScopeType.With,
- debug.ScopeType.With,
+ CheckScopeChain([debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Global], exec_state);
- CheckScopeContent({a:2,b:1}, 0, exec_state);
- CheckScopeContent({a:1,b:2}, 1, exec_state);
+ CheckScopeContent({x:3}, 0, exec_state);
+ CheckScopeContent({}, 1, exec_state);
};
-with_block_4();
+for_loop_3();
EndTest();
-// With block and a block local variable.
-BeginTest("With block 5");
+// For loop with a block scoped let variable shadowing the iteration variable.
+BeginTest("For loop 4");
-function with_block_5() {
- with({a:1}) {
- let a = 2;
+function for_loop_4() {
+ for (let x = 3; x < 4; ++x) {
+ let x = 5;
debugger;
}
}
listener_delegate = function(exec_state) {
CheckScopeChain([debug.ScopeType.Block,
- debug.ScopeType.With,
+ debug.ScopeType.Block,
debug.ScopeType.Local,
debug.ScopeType.Global], exec_state);
- CheckScopeContent({a:2}, 0, exec_state);
- CheckScopeContent({a:1}, 1, exec_state);
+ CheckScopeContent({x:5}, 0, exec_state);
+ CheckScopeContent({x:3}, 1, exec_state);
+ CheckScopeContent({}, 2, exec_state);
};
-with_block_5();
+for_loop_4();
EndTest();
-// Simple closure formed by returning an inner function referering to an outer
-// block local variable and an outer function's parameter.
-BeginTest("Closure 1");
+// For loop with two variable declarations.
+BeginTest("For loop 5");
-function closure_1(a) {
- var x = 2;
- let y = 3;
- if (true) {
- let z = 4;
- function f() {
- debugger;
- return a + x + y + z;
- };
- return f;
+function for_loop_5() {
+ for (let x = 3, y = 5; x < 4; ++x) {
+ debugger;
}
}
listener_delegate = function(exec_state) {
- CheckScopeChain([debug.ScopeType.Local,
- debug.ScopeType.Block,
- debug.ScopeType.Closure,
+ CheckScopeChain([debug.ScopeType.Block,
+ debug.ScopeType.Local,
debug.ScopeType.Global], exec_state);
- CheckScopeContent({}, 0, exec_state);
- CheckScopeContent({a:1,x:2,y:3}, 2, exec_state);
+ CheckScopeContent({x:3,y:5}, 0, exec_state);
+ CheckScopeContent({}, 1, exec_state);
};
-closure_1(1)();
+for_loop_5();
EndTest();
diff --git a/test/mjsunit/harmony/debug-evaluate-blockscopes.js b/test/mjsunit/harmony/debug-evaluate-blockscopes.js
index 549960a2..d6ce8b2b 100644
--- a/test/mjsunit/harmony/debug-evaluate-blockscopes.js
+++ b/test/mjsunit/harmony/debug-evaluate-blockscopes.js
@@ -25,11 +25,17 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --expose-debug-as debug --harmony-block-scoping
+// Flags: --expose-debug-as debug --harmony-scoping
// Test debug evaluation for functions without local context, but with
// nested catch contexts.
+// TODO(ES6): properly activate extended mode
+"use strict";
+
+var x;
+var result;
+
function f() {
{ // Line 1.
let i = 1; // Line 2.
@@ -42,7 +48,7 @@ function f() {
};
// Get the Debug object exposed from the debug context global object.
-Debug = debug.Debug
+var Debug = debug.Debug
// Set breakpoint on line 6.
var bp = Debug.setBreakPoint(f, 6);
diff --git a/test/mjsunit/harmony/module-parsing.js b/test/mjsunit/harmony/module-parsing.js
new file mode 100644
index 00000000..93e69e3a
--- /dev/null
+++ b/test/mjsunit/harmony/module-parsing.js
@@ -0,0 +1,159 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-modules
+
+// Test basic module syntax, with and without automatic semicolon insertion.
+
+module A {}
+
+module A1 = A
+module A2 = A;
+module A3 = A2
+
+module B {
+ export vx
+ export vy, lz, c, f
+
+ var vx
+ var vx, vy;
+ var vx = 0, vy
+ let lx, ly
+ let lz = 1
+ const c = 9
+ function f() {}
+
+ module C0 {}
+
+ export module C {
+ let x
+ export module D { export let x }
+ let y
+ }
+
+ let zz = ""
+
+ export var x0
+ export var x1, x2 = 6, x3
+ export let y0
+ export let y1 = 0, y2
+ export const z0 = 0
+ export const z1 = 2, z2 = 3
+ export function f0() {}
+ export module M1 {}
+ export module M2 = C.D
+ export module M3 at "http://where"
+
+ import i0 from I
+ import i1, i2, i3, M from I
+ import i4, i5 from "http://where"
+}
+
+module I {
+ export let i0, i1, i2, i3;
+ export module M {}
+}
+
+module C1 = B.C;
+module D1 = B.C.D
+module D2 = C1.D
+module D3 = D2
+
+module E1 at "http://where"
+module E2 at "http://where";
+module E3 = E1.F
+
+// Check that ASI does not interfere.
+
+module X
+{
+let x
+}
+
+module Y
+=
+X
+
+module Z
+at
+"file://local"
+
+import
+x
+,
+y
+from
+"file://local"
+
+
+module Wrap {
+export
+x
+,
+y
+
+export
+var
+v1 = 1
+
+export
+let
+v2 = 2
+
+export
+const
+v3 = 3
+
+export
+function
+f
+(
+)
+{
+}
+
+export
+module V
+{
+}
+}
+
+export A, A1, A2, A3, B, I, C1, D1, D2, D3, E1, E2, E3, X, Y, Z, Wrap, x, y, UU
+
+
+
+// Check that 'module' still works as an identifier.
+
+var module
+module = {}
+module["a"] = 6
+function module() {}
+function f(module) { return module }
+try {} catch (module) {}
+
+module
+v = 20
diff --git a/test/mjsunit/harmony/module-resolution.js b/test/mjsunit/harmony/module-resolution.js
new file mode 100644
index 00000000..f9f492cf
--- /dev/null
+++ b/test/mjsunit/harmony/module-resolution.js
@@ -0,0 +1,139 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-modules --harmony-scoping
+
+// Test basic module interface inference.
+
+"use strict";
+
+print("begin.")
+
+export let x = print("0")
+
+export module B = A.B
+
+export module A {
+ export let x = print("1")
+ export let f = function() { return B.x }
+ export module B {
+ module BB = B
+ export BB, x
+ let x = print("2")
+ let y = print("3")
+ let Ax = A.x
+ let ABx = A.B.x
+ let Ay = A.y
+ let BBx = BB.x
+ let Af = A.f
+ function f(x,y) { return x }
+ }
+ export let y = print("4")
+ let Ax = A.x
+ let Bx = B.x
+ let ABx = A.B.x
+ module C {
+ export let z = print("5")
+ export module D = B
+ // TODO(rossberg): turn these into proper negative test cases once we have
+ // suitable error messages.
+ // import C.z // multiple declarations
+ import x from B
+ }
+ module D {
+ // TODO(rossberg): Handle import *.
+ // import A.* // invalid forward import
+ }
+ module M {}
+ // TODO(rossberg): Handle import *.
+ // import M.* // invalid forward import
+ let Cz = C.z
+ let CDx = C.D.x
+}
+
+export module Imports {
+ module A1 {
+ export module A2 {}
+ }
+ module B {
+ // TODO(rossberg): Handle import *.
+ // import A1.*
+ // import A2.* // unbound variable A2
+ }
+}
+
+export module E {
+ export let xx = x
+ export y, B
+ let Bx = B.x
+ // TODO(rossberg): Handle import *.
+ // import A.*
+}
+
+export module M1 {
+ export module A2 = M2
+}
+export module M2 {
+ export module A1 = M1
+}
+
+// TODO(rossberg): turn these into proper negative test cases once we have
+// suitable error messages.
+// module W1 = W2.W
+// module W2 = { export module W = W3 }
+// module W3 = W1 // cyclic module definition
+
+// module W1 = W2.W3
+// module W2 = {
+// export module W3 = W4
+// export module W4 = W1
+// } // cyclic module definition
+
+// TODO(rossberg): Handle import *.
+//module M3B = M3.B
+//export module M3 {
+// export module B { export let x = "" }
+// module C1 = { import M3.* }
+// module C2 = { import M3.B.* }
+// module C3 = { import M3B.* }
+// module C4 = { export x import B.* }
+//// TODO(rossberg): turn these into proper negative test cases once we have
+//// suitable error messages.
+//// export module C5 = { import C5.* } // invalid forward import
+//// export module C6 = { import M3.C6.* } // invalid forward import
+//}
+
+export module External at "external.js"
+export module External1 = External
+export module ExternalA = External.A
+export module InnerExternal {
+ export module E at "external.js"
+}
+export module External2 = InnerExternal.E
+//export let xxx = InnerExternal.E.A.x
+
+print("end.")
diff --git a/test/mjsunit/harmony/proxies-example-membrane.js b/test/mjsunit/harmony/proxies-example-membrane.js
new file mode 100644
index 00000000..c6e7f9f9
--- /dev/null
+++ b/test/mjsunit/harmony/proxies-example-membrane.js
@@ -0,0 +1,512 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony
+
+
+// A simple no-op handler. Adapted from:
+// http://wiki.ecmascript.org/doku.php?id=harmony:proxies#examplea_no-op_forwarding_proxy
+
+function createHandler(obj) {
+ return {
+ getOwnPropertyDescriptor: function(name) {
+ var desc = Object.getOwnPropertyDescriptor(obj, name);
+ if (desc !== undefined) desc.configurable = true;
+ return desc;
+ },
+ getPropertyDescriptor: function(name) {
+ var desc = Object.getOwnPropertyDescriptor(obj, name);
+ //var desc = Object.getPropertyDescriptor(obj, name); // not in ES5
+ if (desc !== undefined) desc.configurable = true;
+ return desc;
+ },
+ getOwnPropertyNames: function() {
+ return Object.getOwnPropertyNames(obj);
+ },
+ getPropertyNames: function() {
+ return Object.getOwnPropertyNames(obj);
+ //return Object.getPropertyNames(obj); // not in ES5
+ },
+ defineProperty: function(name, desc) {
+ Object.defineProperty(obj, name, desc);
+ },
+ delete: function(name) {
+ return delete obj[name];
+ },
+ fix: function() {
+ if (Object.isFrozen(obj)) {
+ var result = {};
+ Object.getOwnPropertyNames(obj).forEach(function(name) {
+ result[name] = Object.getOwnPropertyDescriptor(obj, name);
+ });
+ return result;
+ }
+ // As long as obj is not frozen, the proxy won't allow itself to be fixed
+ return undefined; // will cause a TypeError to be thrown
+ },
+ has: function(name) { return name in obj; },
+ hasOwn: function(name) { return ({}).hasOwnProperty.call(obj, name); },
+ get: function(receiver, name) { return obj[name]; },
+ set: function(receiver, name, val) {
+ obj[name] = val; // bad behavior when set fails in non-strict mode
+ return true;
+ },
+ enumerate: function() {
+ var result = [];
+ for (var name in obj) { result.push(name); };
+ return result;
+ },
+ keys: function() { return Object.keys(obj); }
+ };
+}
+
+
+
+// Auxiliary definitions enabling tracking of object identity in output.
+
+var objectMap = new WeakMap;
+var objectCounter = 0;
+
+function registerObject(x, s) {
+ if (x === Object(x) && !objectMap.has(x))
+ objectMap.set(x, ++objectCounter + (s == undefined ? "" : ":" + s));
+}
+
+registerObject(this, "global");
+registerObject(Object.prototype, "Object.prototype");
+
+function str(x) {
+ if (x === Object(x)) return "[" + typeof x + " " + objectMap.get(x) + "]";
+ if (typeof x == "string") return "\"" + x + "\"";
+ return "" + x;
+}
+
+
+
+// A simple membrane. Adapted from:
+// http://wiki.ecmascript.org/doku.php?id=harmony:proxies#a_simple_membrane
+
+function createSimpleMembrane(target) {
+ var enabled = true;
+
+ function wrap(obj) {
+ registerObject(obj);
+ print("wrap enter", str(obj));
+ try {
+ var x = wrap2(obj);
+ registerObject(x, "wrapped");
+ print("wrap exit", str(obj), "as", str(x));
+ return x;
+ } catch(e) {
+ print("wrap exception", str(e));
+ throw e;
+ }
+ }
+
+ function wrap2(obj) {
+ if (obj !== Object(obj)) {
+ return obj;
+ }
+
+ function wrapCall(fun, that, args) {
+ registerObject(that);
+ print("wrapCall enter", fun, str(that));
+ try {
+ var x = wrapCall2(fun, that, args);
+ print("wrapCall exit", fun, str(that), "returning", str(x));
+ return x;
+ } catch(e) {
+ print("wrapCall exception", fun, str(that), str(e));
+ throw e;
+ }
+ }
+
+ function wrapCall2(fun, that, args) {
+ if (!enabled) { throw new Error("disabled"); }
+ try {
+ return wrap(fun.apply(that, Array.prototype.map.call(args, wrap)));
+ } catch (e) {
+ throw wrap(e);
+ }
+ }
+
+ var baseHandler = createHandler(obj);
+ var handler = Proxy.create(Object.freeze({
+ get: function(receiver, name) {
+ return function() {
+ var arg = (name === "get" || name == "set") ? arguments[1] : "";
+ print("handler enter", name, arg);
+ var x = wrapCall(baseHandler[name], baseHandler, arguments);
+ print("handler exit", name, arg, "returning", str(x));
+ return x;
+ }
+ }
+ }));
+ registerObject(baseHandler, "basehandler");
+ registerObject(handler, "handler");
+
+ if (typeof obj === "function") {
+ function callTrap() {
+ print("call trap enter", str(obj), str(this));
+ var x = wrapCall(obj, wrap(this), arguments);
+ print("call trap exit", str(obj), str(this), "returning", str(x));
+ return x;
+ }
+ function constructTrap() {
+ if (!enabled) { throw new Error("disabled"); }
+ try {
+ function forward(args) { return obj.apply(this, args) }
+ return wrap(new forward(Array.prototype.map.call(arguments, wrap)));
+ } catch (e) {
+ throw wrap(e);
+ }
+ }
+ return Proxy.createFunction(handler, callTrap, constructTrap);
+ } else {
+ var prototype = wrap(Object.getPrototypeOf(obj));
+ return Proxy.create(handler, prototype);
+ }
+ }
+
+ var gate = Object.freeze({
+ enable: function() { enabled = true; },
+ disable: function() { enabled = false; }
+ });
+
+ return Object.freeze({
+ wrapper: wrap(target),
+ gate: gate
+ });
+}
+
+
+var o = {
+ a: 6,
+ b: {bb: 8},
+ f: function(x) { return x },
+ g: function(x) { return x.a },
+ h: function(x) { this.q = x }
+};
+o[2] = {c: 7};
+var m = createSimpleMembrane(o);
+var w = m.wrapper;
+print("o =", str(o))
+print("w =", str(w));
+
+var f = w.f;
+var x = f(66);
+var x = f({a: 1});
+var x = w.f({a: 1});
+var a = x.a;
+assertEquals(6, w.a);
+assertEquals(8, w.b.bb);
+assertEquals(7, w[2]["c"]);
+assertEquals(undefined, w.c);
+assertEquals(1, w.f(1));
+assertEquals(1, w.f({a: 1}).a);
+assertEquals(2, w.g({a: 2}));
+assertEquals(3, (w.r = {a: 3}).a);
+assertEquals(3, w.r.a);
+assertEquals(3, o.r.a);
+w.h(3);
+assertEquals(3, w.q);
+assertEquals(3, o.q);
+assertEquals(4, (new w.h(4)).q);
+
+var wb = w.b;
+var wr = w.r;
+var wf = w.f;
+var wf3 = w.f(3);
+var wfx = w.f({a: 6});
+var wgx = w.g({a: {aa: 7}});
+var wh4 = new w.h(4);
+m.gate.disable();
+assertEquals(3, wf3);
+assertThrows(function() { w.a }, Error);
+assertThrows(function() { w.r }, Error);
+assertThrows(function() { w.r = {a: 4} }, Error);
+assertThrows(function() { o.r.a }, Error);
+assertEquals("object", typeof o.r);
+assertEquals(5, (o.r = {a: 5}).a);
+assertEquals(5, o.r.a);
+assertThrows(function() { w[1] }, Error);
+assertThrows(function() { w.c }, Error);
+assertThrows(function() { wb.bb }, Error);
+assertThrows(function() { wr.a }, Error);
+assertThrows(function() { wf(4) }, Error);
+assertThrows(function() { wfx.a }, Error);
+assertThrows(function() { wgx.aa }, Error);
+assertThrows(function() { wh4.q }, Error);
+
+m.gate.enable();
+assertEquals(6, w.a);
+assertEquals(5, w.r.a);
+assertEquals(5, o.r.a);
+assertEquals(7, w.r = 7);
+assertEquals(7, w.r);
+assertEquals(7, o.r);
+assertEquals(8, w.b.bb);
+assertEquals(7, w[2]["c"]);
+assertEquals(undefined, w.c);
+assertEquals(8, wb.bb);
+assertEquals(3, wr.a);
+assertEquals(4, wf(4));
+assertEquals(3, wf3);
+assertEquals(6, wfx.a);
+assertEquals(7, wgx.aa);
+assertEquals(4, wh4.q);
+
+
+// An identity-preserving membrane. Adapted from:
+// http://wiki.ecmascript.org/doku.php?id=harmony:proxies#an_identity-preserving_membrane
+
+function createMembrane(wetTarget) {
+ var wet2dry = WeakMap();
+ var dry2wet = WeakMap();
+
+ function asDry(obj) {
+ registerObject(obj)
+ print("asDry enter", str(obj))
+ try {
+ var x = asDry2(obj);
+ registerObject(x, "dry");
+ print("asDry exit", str(obj), "as", str(x));
+ return x;
+ } catch(e) {
+ print("asDry exception", str(e));
+ throw e;
+ }
+ }
+ function asDry2(wet) {
+ if (wet !== Object(wet)) {
+ // primitives provide only irrevocable knowledge, so don't
+ // bother wrapping it.
+ return wet;
+ }
+ var dryResult = wet2dry.get(wet);
+ if (dryResult) { return dryResult; }
+
+ var wetHandler = createHandler(wet);
+ var dryRevokeHandler = Proxy.create(Object.freeze({
+ get: function(receiver, name) {
+ return function() {
+ var arg = (name === "get" || name == "set") ? arguments[1] : "";
+ print("dry handler enter", name, arg);
+ var optWetHandler = dry2wet.get(dryRevokeHandler);
+ try {
+ var x = asDry(optWetHandler[name].apply(
+ optWetHandler, Array.prototype.map.call(arguments, asWet)));
+ print("dry handler exit", name, arg, "returning", str(x));
+ return x;
+ } catch (eWet) {
+ var x = asDry(eWet);
+ print("dry handler exception", name, arg, "throwing", str(x));
+ throw x;
+ }
+ };
+ }
+ }));
+ dry2wet.set(dryRevokeHandler, wetHandler);
+
+ if (typeof wet === "function") {
+ function callTrap() {
+ print("dry call trap enter", str(this));
+ var x = asDry(wet.apply(
+ asWet(this), Array.prototype.map.call(arguments, asWet)));
+ print("dry call trap exit", str(this), "returning", str(x));
+ return x;
+ }
+ function constructTrap() {
+ function forward(args) { return wet.apply(this, args) }
+ return asDry(new forward(Array.prototype.map.call(arguments, asWet)));
+ }
+ dryResult =
+ Proxy.createFunction(dryRevokeHandler, callTrap, constructTrap);
+ } else {
+ dryResult =
+ Proxy.create(dryRevokeHandler, asDry(Object.getPrototypeOf(wet)));
+ }
+ wet2dry.set(wet, dryResult);
+ dry2wet.set(dryResult, wet);
+ return dryResult;
+ }
+
+ function asWet(obj) {
+ registerObject(obj)
+ print("asWet enter", str(obj))
+ try {
+ var x = asWet2(obj)
+ registerObject(x, "wet")
+ print("asWet exit", str(obj), "as", str(x))
+ return x
+ } catch(e) {
+ print("asWet exception", str(e))
+ throw e
+ }
+ }
+ function asWet2(dry) {
+ if (dry !== Object(dry)) {
+ // primitives provide only irrevocable knowledge, so don't
+ // bother wrapping it.
+ return dry;
+ }
+ var wetResult = dry2wet.get(dry);
+ if (wetResult) { return wetResult; }
+
+ var dryHandler = createHandler(dry);
+ var wetRevokeHandler = Proxy.create(Object.freeze({
+ get: function(receiver, name) {
+ return function() {
+ var arg = (name === "get" || name == "set") ? arguments[1] : "";
+ print("wet handler enter", name, arg);
+ var optDryHandler = wet2dry.get(wetRevokeHandler);
+ try {
+ var x = asWet(optDryHandler[name].apply(
+ optDryHandler, Array.prototype.map.call(arguments, asDry)));
+ print("wet handler exit", name, arg, "returning", str(x));
+ return x;
+ } catch (eDry) {
+ var x = asWet(eDry);
+ print("wet handler exception", name, arg, "throwing", str(x));
+ throw x;
+ }
+ };
+ }
+ }));
+ wet2dry.set(wetRevokeHandler, dryHandler);
+
+ if (typeof dry === "function") {
+ function callTrap() {
+ print("wet call trap enter", str(this));
+ var x = asWet(dry.apply(
+ asDry(this), Array.prototype.map.call(arguments, asDry)));
+ print("wet call trap exit", str(this), "returning", str(x));
+ return x;
+ }
+ function constructTrap() {
+ function forward(args) { return dry.apply(this, args) }
+ return asWet(new forward(Array.prototype.map.call(arguments, asDry)));
+ }
+ wetResult =
+ Proxy.createFunction(wetRevokeHandler, callTrap, constructTrap);
+ } else {
+ wetResult =
+ Proxy.create(wetRevokeHandler, asWet(Object.getPrototypeOf(dry)));
+ }
+ dry2wet.set(dry, wetResult);
+ wet2dry.set(wetResult, dry);
+ return wetResult;
+ }
+
+ var gate = Object.freeze({
+ revoke: function() {
+ dry2wet = wet2dry = Object.freeze({
+ get: function(key) { throw new Error("revoked"); },
+ set: function(key, val) { throw new Error("revoked"); }
+ });
+ }
+ });
+
+ return Object.freeze({ wrapper: asDry(wetTarget), gate: gate });
+}
+
+
+var receiver
+var argument
+var o = {
+ a: 6,
+ b: {bb: 8},
+ f: function(x) { receiver = this; argument = x; return x },
+ g: function(x) { receiver = this; argument = x; return x.a },
+ h: function(x) { receiver = this; argument = x; this.q = x },
+ s: function(x) { receiver = this; argument = x; this.x = {y: x}; return this }
+}
+o[2] = {c: 7}
+var m = createMembrane(o)
+var w = m.wrapper
+print("o =", str(o))
+print("w =", str(w))
+
+var f = w.f
+var x = f(66)
+var x = f({a: 1})
+var x = w.f({a: 1})
+var a = x.a
+assertEquals(6, w.a)
+assertEquals(8, w.b.bb)
+assertEquals(7, w[2]["c"])
+assertEquals(undefined, w.c)
+assertEquals(1, w.f(1))
+assertSame(o, receiver)
+assertEquals(1, w.f({a: 1}).a)
+assertSame(o, receiver)
+assertEquals(2, w.g({a: 2}))
+assertSame(o, receiver)
+assertSame(w, w.f(w))
+assertSame(o, receiver)
+assertSame(o, argument)
+assertSame(o, w.f(o))
+assertSame(o, receiver)
+// Note that argument !== o, since o isn't dry, so gets wrapped wet again.
+assertEquals(3, (w.r = {a: 3}).a)
+assertEquals(3, w.r.a)
+assertEquals(3, o.r.a)
+w.h(3)
+assertEquals(3, w.q)
+assertEquals(3, o.q)
+assertEquals(4, (new w.h(4)).q)
+assertEquals(5, w.s(5).x.y)
+assertSame(o, receiver)
+
+var wb = w.b
+var wr = w.r
+var wf = w.f
+var wf3 = w.f(3)
+var wfx = w.f({a: 6})
+var wgx = w.g({a: {aa: 7}})
+var wh4 = new w.h(4)
+var ws5 = w.s(5)
+var ws5x = ws5.x
+m.gate.revoke()
+assertEquals(3, wf3)
+assertThrows(function() { w.a }, Error)
+assertThrows(function() { w.r }, Error)
+assertThrows(function() { w.r = {a: 4} }, Error)
+assertThrows(function() { o.r.a }, Error)
+assertEquals("object", typeof o.r)
+assertEquals(5, (o.r = {a: 5}).a)
+assertEquals(5, o.r.a)
+assertThrows(function() { w[1] }, Error)
+assertThrows(function() { w.c }, Error)
+assertThrows(function() { wb.bb }, Error)
+assertEquals(3, wr.a)
+assertThrows(function() { wf(4) }, Error)
+assertEquals(6, wfx.a)
+assertEquals(7, wgx.aa)
+assertThrows(function() { wh4.q }, Error)
+assertThrows(function() { ws5.x }, Error)
+assertThrows(function() { ws5x.y }, Error)
diff --git a/test/mjsunit/harmony/proxies-for.js b/test/mjsunit/harmony/proxies-for.js
new file mode 100644
index 00000000..3d419c6d
--- /dev/null
+++ b/test/mjsunit/harmony/proxies-for.js
@@ -0,0 +1,168 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-proxies
+
+
+// Helper.
+
+function TestWithProxies(test, x, y, z) {
+ test(Proxy.create, x, y, z)
+ test(function(h) {return Proxy.createFunction(h, function() {})}, x, y, z)
+}
+
+
+// Iterate over a proxy.
+
+function TestForIn(properties, handler) {
+ TestWithProxies(TestForIn2, properties, handler)
+}
+
+function TestForIn2(create, properties, handler) {
+ var p = create(handler)
+ var found = []
+ for (var x in p) found.push(x)
+ assertArrayEquals(properties, found)
+}
+
+TestForIn(["0", "a"], {
+ enumerate: function() { return [0, "a"] }
+})
+
+TestForIn(["null", "a"], {
+ enumerate: function() { return this.enumerate2() },
+ enumerate2: function() { return [null, "a"] }
+})
+
+TestForIn(["b", "d"], {
+ getPropertyNames: function() { return ["a", "b", "c", "d", "e"] },
+ getPropertyDescriptor: function(k) {
+ switch (k) {
+ case "a": return {enumerable: false, value: "3"};
+ case "b": return {enumerable: true, get get() {}};
+ case "c": return {value: 4};
+ case "d": return {get enumerable() { return true }};
+ default: return undefined;
+ }
+ }
+})
+
+TestForIn(["b", "a", "0", "c"], Proxy.create({
+ get: function(pr, pk) {
+ return function() { return ["b", "a", 0, "c"] }
+ }
+}))
+
+
+
+// Iterate over an object with a proxy prototype.
+
+function TestForInDerived(properties, handler) {
+ TestWithProxies(TestForInDerived2, properties, handler)
+}
+
+function TestForInDerived2(create, properties, handler) {
+ var p = create(handler)
+ var o = Object.create(p)
+ o.z = 0
+ var found = []
+ for (var x in o) found.push(x)
+ assertArrayEquals(["z"].concat(properties), found)
+
+ var oo = Object.create(o)
+ oo.y = 0
+ var found = []
+ for (var x in oo) found.push(x)
+ assertArrayEquals(["y", "z"].concat(properties), found)
+}
+
+TestForInDerived(["0", "a"], {
+ enumerate: function() { return [0, "a"] },
+ getPropertyDescriptor: function(k) {
+ return k == "0" || k == "a" ? {} : undefined
+ }
+})
+
+TestForInDerived(["null", "a"], {
+ enumerate: function() { return this.enumerate2() },
+ enumerate2: function() { return [null, "a"] },
+ getPropertyDescriptor: function(k) {
+ return k == "null" || k == "a" ? {} : undefined
+ }
+})
+
+TestForInDerived(["b", "d"], {
+ getPropertyNames: function() { return ["a", "b", "c", "d", "e"] },
+ getPropertyDescriptor: function(k) {
+ switch (k) {
+ case "a": return {enumerable: false, value: "3"};
+ case "b": return {enumerable: true, get get() {}};
+ case "c": return {value: 4};
+ case "d": return {get enumerable() { return true }};
+ default: return undefined;
+ }
+ }
+})
+
+
+
+// Throw exception in enumerate trap.
+
+function TestForInThrow(handler) {
+ TestWithProxies(TestForInThrow2, handler)
+}
+
+function TestForInThrow2(create, handler) {
+ var p = create(handler)
+ var o = Object.create(p)
+ assertThrows(function(){ for (var x in p) {} }, "myexn")
+ assertThrows(function(){ for (var x in o) {} }, "myexn")
+}
+
+TestForInThrow({
+ enumerate: function() { throw "myexn" }
+})
+
+TestForInThrow({
+ enumerate: function() { return this.enumerate2() },
+ enumerate2: function() { throw "myexn" }
+})
+
+TestForInThrow({
+ getPropertyNames: function() { throw "myexn" }
+})
+
+TestForInThrow({
+ getPropertyNames: function() { return ["a"] },
+ getPropertyDescriptor: function() { throw "myexn" }
+})
+
+TestForInThrow(Proxy.create({
+ get: function(pr, pk) {
+ return function() { throw "myexn" }
+ }
+}))
diff --git a/test/mjsunit/harmony/proxies-function.js b/test/mjsunit/harmony/proxies-function.js
new file mode 100644
index 00000000..6b8d0984
--- /dev/null
+++ b/test/mjsunit/harmony/proxies-function.js
@@ -0,0 +1,748 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-proxies --allow-natives-syntax
+
+
+// Helper.
+
+function CreateFrozen(handler, callTrap, constructTrap) {
+ if (handler.fix === undefined) handler.fix = function() { return {} }
+ var f = Proxy.createFunction(handler, callTrap, constructTrap)
+ Object.freeze(f)
+ return f
+}
+
+
+// Ensures that checking the "length" property of a function proxy doesn't
+// crash due to lack of a [[Get]] method.
+var handler = {
+ get : function(r, n) { return n == "length" ? 2 : undefined }
+}
+
+
+// Calling (call, Function.prototype.call, Function.prototype.apply,
+// Function.prototype.bind).
+
+var global_object = this
+var receiver
+
+function TestCall(isStrict, callTrap) {
+ assertEquals(42, callTrap(5, 37))
+ // TODO(rossberg): strict mode seems to be broken on x64...
+ // assertSame(isStrict ? undefined : global_object, receiver)
+
+ var handler = {
+ get: function(r, k) {
+ return k == "length" ? 2 : Function.prototype[k]
+ }
+ }
+ var f = Proxy.createFunction(handler, callTrap)
+ var o = {f: f}
+ global_object.f = f
+
+ receiver = 333
+ assertEquals(42, f(11, 31))
+ // TODO(rossberg): strict mode seems to be broken on x64...
+ // assertSame(isStrict ? undefined : global_object, receiver)
+ receiver = 333
+ assertEquals(42, o.f(10, 32))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, o["f"](9, 33))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, (1, o).f(8, 34))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, (1, o)["f"](7, 35))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, f.call(o, 32, 10))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, f.call(undefined, 33, 9))
+ assertSame(isStrict ? undefined : global_object, receiver)
+ receiver = 333
+ assertEquals(42, f.call(null, 33, 9))
+ assertSame(isStrict ? null : global_object, receiver)
+ receiver = 333
+ assertEquals(44, f.call(2, 21, 23))
+ assertSame(2, receiver.valueOf())
+ receiver = 333
+ assertEquals(42, Function.prototype.call.call(f, o, 20, 22))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(43, Function.prototype.call.call(f, null, 20, 23))
+ assertSame(isStrict ? null : global_object, receiver)
+ assertEquals(44, Function.prototype.call.call(f, 2, 21, 23))
+ assertEquals(2, receiver.valueOf())
+ receiver = 333
+ assertEquals(32, f.apply(o, [16, 16]))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(32, Function.prototype.apply.call(f, o, [17, 15]))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, %Call(o, 11, 31, f))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, %Call(null, 11, 31, f))
+ assertSame(isStrict ? null : global_object, receiver)
+ receiver = 333
+ assertEquals(42, %Apply(f, o, [11, 31], 0, 2))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, %Apply(f, null, [11, 31], 0, 2))
+ assertSame(isStrict ? null : global_object, receiver)
+ receiver = 333
+ assertEquals(42, %_CallFunction(o, 11, 31, f))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, %_CallFunction(null, 11, 31, f))
+ assertSame(isStrict ? null : global_object, receiver)
+
+ var ff = Function.prototype.bind.call(f, o, 12)
+ assertTrue(ff.length <= 1) // TODO(rossberg): Not spec'ed yet, be lax.
+ receiver = 333
+ assertEquals(42, ff(30))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(33, Function.prototype.call.call(ff, {}, 21))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(32, Function.prototype.apply.call(ff, {}, [20]))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(23, %Call({}, 11, ff))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(23, %Call({}, 11, 3, ff))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(24, %Apply(ff, {}, [12, 13], 0, 1))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(24, %Apply(ff, {}, [12, 13], 0, 2))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(34, %_CallFunction({}, 22, ff))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(34, %_CallFunction({}, 22, 3, ff))
+ assertSame(o, receiver)
+
+ var fff = Function.prototype.bind.call(ff, o, 30)
+ assertEquals(0, fff.length)
+ receiver = 333
+ assertEquals(42, fff())
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, Function.prototype.call.call(fff, {}))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, Function.prototype.apply.call(fff, {}))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, %Call({}, fff))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, %Call({}, 11, 3, fff))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, %Apply(fff, {}, [], 0, 0))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, %Apply(fff, {}, [12, 13], 0, 0))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, %Apply(fff, {}, [12, 13], 0, 2))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, %_CallFunction({}, fff))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, %_CallFunction({}, 3, 4, 5, fff))
+ assertSame(o, receiver)
+
+ var f = CreateFrozen({}, callTrap)
+ receiver = 333
+ assertEquals(42, f(11, 31))
+ assertSame(isStrict ? undefined : global_object, receiver)
+ var o = {f: f}
+ receiver = 333
+ assertEquals(42, o.f(10, 32))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, o["f"](9, 33))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, (1, o).f(8, 34))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, (1, o)["f"](7, 35))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, Function.prototype.call.call(f, o, 20, 22))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(32, Function.prototype.apply.call(f, o, [17, 15]))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(23, %Call(o, 11, 12, f))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(27, %Apply(f, o, [12, 13, 14], 1, 2))
+ assertSame(o, receiver)
+ receiver = 333
+ assertEquals(42, %_CallFunction(o, 18, 24, f))
+ assertSame(o, receiver)
+}
+
+TestCall(false, function(x, y) {
+ receiver = this
+ return x + y
+})
+
+TestCall(true, function(x, y) {
+ "use strict"
+ receiver = this
+ return x + y
+})
+
+TestCall(false, function() {
+ receiver = this
+ return arguments[0] + arguments[1]
+})
+
+TestCall(false, Proxy.createFunction(handler, function(x, y) {
+ receiver = this
+ return x + y
+}))
+
+TestCall(true, Proxy.createFunction(handler, function(x, y) {
+ "use strict"
+ receiver = this
+ return x + y
+}))
+
+TestCall(false, CreateFrozen(handler, function(x, y) {
+ receiver = this
+ return x + y
+}))
+
+
+
+// Using intrinsics as call traps.
+
+function TestCallIntrinsic(type, callTrap) {
+ var f = Proxy.createFunction({}, callTrap)
+ var x = f()
+ assertTrue(typeof x == type)
+}
+
+TestCallIntrinsic("boolean", Boolean)
+TestCallIntrinsic("number", Number)
+TestCallIntrinsic("string", String)
+TestCallIntrinsic("object", Object)
+TestCallIntrinsic("function", Function)
+
+
+
+// Throwing from call trap.
+
+function TestCallThrow(callTrap) {
+ var f = Proxy.createFunction({}, callTrap)
+ assertThrows(function(){ f(11) }, "myexn")
+ assertThrows(function(){ ({x: f}).x(11) }, "myexn")
+ assertThrows(function(){ ({x: f})["x"](11) }, "myexn")
+ assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn")
+ assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn")
+ assertThrows(function(){ %Call({}, f) }, "myexn")
+ assertThrows(function(){ %Call({}, 1, 2, f) }, "myexn")
+ assertThrows(function(){ %Apply({}, f, [], 3, 0) }, "myexn")
+ assertThrows(function(){ %Apply({}, f, [3, 4], 0, 1) }, "myexn")
+ assertThrows(function(){ %_CallFunction({}, f) }, "myexn")
+ assertThrows(function(){ %_CallFunction({}, 1, 2, f) }, "myexn")
+
+ var f = CreateFrozen({}, callTrap)
+ assertThrows(function(){ f(11) }, "myexn")
+ assertThrows(function(){ ({x: f}).x(11) }, "myexn")
+ assertThrows(function(){ ({x: f})["x"](11) }, "myexn")
+ assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn")
+ assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn")
+ assertThrows(function(){ %Call({}, f) }, "myexn")
+ assertThrows(function(){ %Call({}, 1, 2, f) }, "myexn")
+ assertThrows(function(){ %Apply({}, f, [], 3, 0) }, "myexn")
+ assertThrows(function(){ %Apply({}, f, [3, 4], 0, 1) }, "myexn")
+ assertThrows(function(){ %_CallFunction({}, f) }, "myexn")
+ assertThrows(function(){ %_CallFunction({}, 1, 2, f) }, "myexn")
+}
+
+TestCallThrow(function() { throw "myexn" })
+TestCallThrow(Proxy.createFunction({}, function() { throw "myexn" }))
+TestCallThrow(CreateFrozen({}, function() { throw "myexn" }))
+
+
+
+// Construction (new).
+
+var prototype = {myprop: 0}
+var receiver
+
+var handlerWithPrototype = {
+ fix: function() { return { prototype: { value: prototype } }; },
+ get: function(r, n) {
+ if (n == "length") return 2;
+ assertEquals("prototype", n);
+ return prototype;
+ }
+}
+
+var handlerSansPrototype = {
+ fix: function() { return { length: { value: 2 } } },
+ get: function(r, n) {
+ if (n == "length") return 2;
+ assertEquals("prototype", n);
+ return undefined;
+ }
+}
+
+function ReturnUndef(x, y) {
+ "use strict";
+ receiver = this;
+ this.sum = x + y;
+}
+
+function ReturnThis(x, y) {
+ "use strict";
+ receiver = this;
+ this.sum = x + y;
+ return this;
+}
+
+function ReturnNew(x, y) {
+ "use strict";
+ receiver = this;
+ return {sum: x + y};
+}
+
+function ReturnNewWithProto(x, y) {
+ "use strict";
+ receiver = this;
+ var result = Object.create(prototype);
+ result.sum = x + y;
+ return result;
+}
+
+function TestConstruct(proto, constructTrap) {
+ TestConstruct2(proto, constructTrap, handlerWithPrototype)
+ TestConstruct2(proto, constructTrap, handlerSansPrototype)
+}
+
+function TestConstruct2(proto, constructTrap, handler) {
+ var f = Proxy.createFunction(handler, function() {}, constructTrap)
+ var o = new f(11, 31)
+ assertEquals(undefined, receiver)
+ assertEquals(42, o.sum)
+ assertSame(proto, Object.getPrototypeOf(o))
+
+ var f = CreateFrozen(handler, function() {}, constructTrap)
+ var o = new f(11, 32)
+ assertEquals(undefined, receiver)
+ assertEquals(43, o.sum)
+ assertSame(proto, Object.getPrototypeOf(o))
+}
+
+TestConstruct(Object.prototype, ReturnNew)
+TestConstruct(prototype, ReturnNewWithProto)
+
+TestConstruct(Object.prototype, Proxy.createFunction(handler, ReturnNew))
+TestConstruct(prototype, Proxy.createFunction(handler, ReturnNewWithProto))
+
+TestConstruct(Object.prototype, CreateFrozen(handler, ReturnNew))
+TestConstruct(prototype, CreateFrozen(handler, ReturnNewWithProto))
+
+
+
+// Construction with derived construct trap.
+
+function TestConstructFromCall(proto, returnsThis, callTrap) {
+ TestConstructFromCall2(prototype, returnsThis, callTrap, handlerWithPrototype)
+ TestConstructFromCall2(proto, returnsThis, callTrap, handlerSansPrototype)
+}
+
+function TestConstructFromCall2(proto, returnsThis, callTrap, handler) {
+ // TODO(rossberg): handling of prototype for derived construct trap will be
+ // fixed in a separate change. Commenting out checks below for now.
+ var f = Proxy.createFunction(handler, callTrap)
+ var o = new f(11, 31)
+ if (returnsThis) assertEquals(o, receiver)
+ assertEquals(42, o.sum)
+ // assertSame(proto, Object.getPrototypeOf(o))
+
+ var g = CreateFrozen(handler, callTrap)
+ // assertSame(f.prototype, g.prototype)
+ var o = new g(11, 32)
+ if (returnsThis) assertEquals(o, receiver)
+ assertEquals(43, o.sum)
+ // assertSame(proto, Object.getPrototypeOf(o))
+}
+
+TestConstructFromCall(Object.prototype, true, ReturnUndef)
+TestConstructFromCall(Object.prototype, true, ReturnThis)
+TestConstructFromCall(Object.prototype, false, ReturnNew)
+TestConstructFromCall(prototype, false, ReturnNewWithProto)
+
+TestConstructFromCall(Object.prototype, true,
+ Proxy.createFunction(handler, ReturnUndef))
+TestConstructFromCall(Object.prototype, true,
+ Proxy.createFunction(handler, ReturnThis))
+TestConstructFromCall(Object.prototype, false,
+ Proxy.createFunction(handler, ReturnNew))
+TestConstructFromCall(prototype, false,
+ Proxy.createFunction(handler, ReturnNewWithProto))
+
+TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnUndef))
+TestConstructFromCall(Object.prototype, true, CreateFrozen({}, ReturnThis))
+TestConstructFromCall(Object.prototype, false, CreateFrozen({}, ReturnNew))
+TestConstructFromCall(prototype, false, CreateFrozen({}, ReturnNewWithProto))
+
+ReturnUndef.prototype = prototype
+ReturnThis.prototype = prototype
+ReturnNew.prototype = prototype
+ReturnNewWithProto.prototype = prototype
+
+TestConstructFromCall(prototype, true, ReturnUndef)
+TestConstructFromCall(prototype, true, ReturnThis)
+TestConstructFromCall(Object.prototype, false, ReturnNew)
+TestConstructFromCall(prototype, false, ReturnNewWithProto)
+
+TestConstructFromCall(Object.prototype, true,
+ Proxy.createFunction(handler, ReturnUndef))
+TestConstructFromCall(Object.prototype, true,
+ Proxy.createFunction(handler, ReturnThis))
+TestConstructFromCall(Object.prototype, false,
+ Proxy.createFunction(handler, ReturnNew))
+TestConstructFromCall(prototype, false,
+ Proxy.createFunction(handler, ReturnNewWithProto))
+
+TestConstructFromCall(prototype, true,
+ Proxy.createFunction(handlerWithPrototype, ReturnUndef))
+TestConstructFromCall(prototype, true,
+ Proxy.createFunction(handlerWithPrototype, ReturnThis))
+TestConstructFromCall(Object.prototype, false,
+ Proxy.createFunction(handlerWithPrototype, ReturnNew))
+TestConstructFromCall(prototype, false,
+ Proxy.createFunction(handlerWithPrototype,
+ ReturnNewWithProto))
+
+TestConstructFromCall(prototype, true,
+ CreateFrozen(handlerWithPrototype, ReturnUndef))
+TestConstructFromCall(prototype, true,
+ CreateFrozen(handlerWithPrototype, ReturnThis))
+TestConstructFromCall(Object.prototype, false,
+ CreateFrozen(handlerWithPrototype, ReturnNew))
+TestConstructFromCall(prototype, false,
+ CreateFrozen(handlerWithPrototype, ReturnNewWithProto))
+
+
+
+// Throwing from the construct trap.
+
+function TestConstructThrow(trap) {
+ TestConstructThrow2(Proxy.createFunction({ fix: function() {return {};} },
+ trap))
+ TestConstructThrow2(Proxy.createFunction({ fix: function() {return {};} },
+ function() {},
+ trap))
+}
+
+function TestConstructThrow2(f) {
+ assertThrows(function(){ new f(11) }, "myexn")
+ Object.freeze(f)
+ assertThrows(function(){ new f(11) }, "myexn")
+}
+
+TestConstructThrow(function() { throw "myexn" })
+TestConstructThrow(Proxy.createFunction({}, function() { throw "myexn" }))
+TestConstructThrow(CreateFrozen({}, function() { throw "myexn" }))
+
+
+
+// Using function proxies as getters and setters.
+
+var value
+var receiver
+
+function TestAccessorCall(getterCallTrap, setterCallTrap) {
+ var handler = { fix: function() { return {} } }
+ var pgetter = Proxy.createFunction(handler, getterCallTrap)
+ var psetter = Proxy.createFunction(handler, setterCallTrap)
+
+ var o = {}
+ var oo = Object.create(o)
+ Object.defineProperty(o, "a", {get: pgetter, set: psetter})
+ Object.defineProperty(o, "b", {get: pgetter})
+ Object.defineProperty(o, "c", {set: psetter})
+ Object.defineProperty(o, "3", {get: pgetter, set: psetter})
+ Object.defineProperty(oo, "a", {value: 43})
+
+ receiver = ""
+ assertEquals(42, o.a)
+ assertSame(o, receiver)
+ receiver = ""
+ assertEquals(42, o.b)
+ assertSame(o, receiver)
+ receiver = ""
+ assertEquals(undefined, o.c)
+ assertEquals("", receiver)
+ receiver = ""
+ assertEquals(42, o["a"])
+ assertSame(o, receiver)
+ receiver = ""
+ assertEquals(42, o[3])
+ assertSame(o, receiver)
+
+ receiver = ""
+ assertEquals(43, oo.a)
+ assertEquals("", receiver)
+ receiver = ""
+ assertEquals(42, oo.b)
+ assertSame(oo, receiver)
+ receiver = ""
+ assertEquals(undefined, oo.c)
+ assertEquals("", receiver)
+ receiver = ""
+ assertEquals(43, oo["a"])
+ assertEquals("", receiver)
+ receiver = ""
+ assertEquals(42, oo[3])
+ assertSame(oo, receiver)
+
+ receiver = ""
+ assertEquals(50, o.a = 50)
+ assertSame(o, receiver)
+ assertEquals(50, value)
+ receiver = ""
+ assertEquals(51, o.b = 51)
+ assertEquals("", receiver)
+ assertEquals(50, value) // no setter
+ assertThrows(function() { "use strict"; o.b = 51 }, TypeError)
+ receiver = ""
+ assertEquals(52, o.c = 52)
+ assertSame(o, receiver)
+ assertEquals(52, value)
+ receiver = ""
+ assertEquals(53, o["a"] = 53)
+ assertSame(o, receiver)
+ assertEquals(53, value)
+ receiver = ""
+ assertEquals(54, o[3] = 54)
+ assertSame(o, receiver)
+ assertEquals(54, value)
+
+ value = 0
+ receiver = ""
+ assertEquals(60, oo.a = 60)
+ assertEquals("", receiver)
+ assertEquals(0, value) // oo has own 'a'
+ assertEquals(61, oo.b = 61)
+ assertSame("", receiver)
+ assertEquals(0, value) // no setter
+ assertThrows(function() { "use strict"; oo.b = 61 }, TypeError)
+ receiver = ""
+ assertEquals(62, oo.c = 62)
+ assertSame(oo, receiver)
+ assertEquals(62, value)
+ receiver = ""
+ assertEquals(63, oo["c"] = 63)
+ assertSame(oo, receiver)
+ assertEquals(63, value)
+ receiver = ""
+ assertEquals(64, oo[3] = 64)
+ assertSame(oo, receiver)
+ assertEquals(64, value)
+}
+
+TestAccessorCall(
+ function() { receiver = this; return 42 },
+ function(x) { receiver = this; value = x }
+)
+
+TestAccessorCall(
+ function() { "use strict"; receiver = this; return 42 },
+ function(x) { "use strict"; receiver = this; value = x }
+)
+
+TestAccessorCall(
+ Proxy.createFunction({}, function() { receiver = this; return 42 }),
+ Proxy.createFunction({}, function(x) { receiver = this; value = x })
+)
+
+TestAccessorCall(
+ CreateFrozen({}, function() { receiver = this; return 42 }),
+ CreateFrozen({}, function(x) { receiver = this; value = x })
+)
+
+
+
+// Passing a proxy function to higher-order library functions.
+
+function TestHigherOrder(f) {
+ assertEquals(6, [6, 2].map(f)[0])
+ assertEquals(4, [5, 2].reduce(f, 4))
+ assertTrue([1, 2].some(f))
+ assertEquals("a.b.c", "a.b.c".replace(".", f))
+}
+
+TestHigherOrder(function(x) { return x })
+TestHigherOrder(function(x) { "use strict"; return x })
+TestHigherOrder(Proxy.createFunction({}, function(x) { return x }))
+TestHigherOrder(CreateFrozen({}, function(x) { return x }))
+
+
+
+// TODO(rossberg): Ultimately, I want to have the following test function
+// run through, but it currently fails on so many cases (some not even
+// involving proxies), that I leave that for later...
+/*
+function TestCalls() {
+ var handler = {
+ get: function(r, k) {
+ return k == "length" ? 2 : Function.prototype[k]
+ }
+ }
+ var bind = Function.prototype.bind
+ var o = {}
+
+ var traps = [
+ function(x, y) {
+ return {receiver: this, result: x + y, strict: false}
+ },
+ function(x, y) { "use strict";
+ return {receiver: this, result: x + y, strict: true}
+ },
+ function() {
+ var x = arguments[0], y = arguments[1]
+ return {receiver: this, result: x + y, strict: false}
+ },
+ Proxy.createFunction(handler, function(x, y) {
+ return {receiver: this, result: x + y, strict: false}
+ }),
+ Proxy.createFunction(handler, function() {
+ var x = arguments[0], y = arguments[1]
+ return {receiver: this, result: x + y, strict: false}
+ }),
+ Proxy.createFunction(handler, function(x, y) { "use strict"
+ return {receiver: this, result: x + y, strict: true}
+ }),
+ CreateFrozen(handler, function(x, y) {
+ return {receiver: this, result: x + y, strict: false}
+ }),
+ CreateFrozen(handler, function(x, y) { "use strict"
+ return {receiver: this, result: x + y, strict: true}
+ }),
+ ]
+ var creates = [
+ function(trap) { return trap },
+ function(trap) { return CreateFrozen({}, callTrap) },
+ function(trap) { return Proxy.createFunction(handler, callTrap) },
+ function(trap) {
+ return Proxy.createFunction(handler, CreateFrozen({}, callTrap))
+ },
+ function(trap) {
+ return Proxy.createFunction(handler, Proxy.createFunction(handler, callTrap))
+ },
+ ]
+ var binds = [
+ function(f, o, x, y) { return f },
+ function(f, o, x, y) { return bind.call(f, o) },
+ function(f, o, x, y) { return bind.call(f, o, x) },
+ function(f, o, x, y) { return bind.call(f, o, x, y) },
+ function(f, o, x, y) { return bind.call(f, o, x, y, 5) },
+ function(f, o, x, y) { return bind.call(bind.call(f, o), {}, x, y) },
+ function(f, o, x, y) { return bind.call(bind.call(f, o, x), {}, y) },
+ function(f, o, x, y) { return bind.call(bind.call(f, o, x, y), {}, 5) },
+ ]
+ var calls = [
+ function(f, x, y) { return f(x, y) },
+ function(f, x, y) { var g = f; return g(x, y) },
+ function(f, x, y) { with ({}) return f(x, y) },
+ function(f, x, y) { var g = f; with ({}) return g(x, y) },
+ function(f, x, y, o) { with (o) return f(x, y) },
+ function(f, x, y, o) { return f.call(o, x, y) },
+ function(f, x, y, o) { return f.apply(o, [x, y]) },
+ function(f, x, y, o) { return Function.prototype.call.call(f, o, x, y) },
+ function(f, x, y, o) { return Function.prototype.apply.call(f, o, [x, y]) },
+ function(f, x, y, o) { return %_CallFunction(o, x, y, f) },
+ function(f, x, y, o) { return %Call(o, x, y, f) },
+ function(f, x, y, o) { return %Apply(f, o, [null, x, y, null], 1, 2) },
+ function(f, x, y, o) { return %Apply(f, o, arguments, 2, 2) },
+ function(f, x, y, o) { if (typeof o == "object") return o.f(x, y) },
+ function(f, x, y, o) { if (typeof o == "object") return o["f"](x, y) },
+ function(f, x, y, o) { if (typeof o == "object") return (1, o).f(x, y) },
+ function(f, x, y, o) { if (typeof o == "object") return (1, o)["f"](x, y) },
+ ]
+ var receivers = [o, global_object, undefined, null, 2, "bla", true]
+ var expectedNonStricts = [o, global_object, global_object, global_object]
+
+ for (var t = 0; t < traps.length; ++t) {
+ for (var i = 0; i < creates.length; ++i) {
+ for (var j = 0; j < binds.length; ++j) {
+ for (var k = 0; k < calls.length; ++k) {
+ for (var m = 0; m < receivers.length; ++m) {
+ for (var n = 0; n < receivers.length; ++n) {
+ var bound = receivers[m]
+ var receiver = receivers[n]
+ var func = binds[j](creates[i](traps[t]), bound, 31, 11)
+ var expected = j > 0 ? bound : receiver
+ var expectedNonStrict = expectedNonStricts[j > 0 ? m : n]
+ o.f = func
+ global_object.f = func
+ var x = calls[k](func, 11, 31, receiver)
+ if (x !== undefined) {
+ assertEquals(42, x.result)
+ if (calls[k].length < 4)
+ assertSame(x.strict ? undefined : global_object, x.receiver)
+ else if (x.strict)
+ assertSame(expected, x.receiver)
+ else if (expectedNonStrict === undefined)
+ assertSame(expected, x.receiver.valueOf())
+ else
+ assertSame(expectedNonStrict, x.receiver)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+TestCalls()
+*/
diff --git a/test/mjsunit/harmony/proxies-hash.js b/test/mjsunit/harmony/proxies-hash.js
new file mode 100644
index 00000000..abfc0f5f
--- /dev/null
+++ b/test/mjsunit/harmony/proxies-hash.js
@@ -0,0 +1,122 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --harmony-proxies --harmony-collections
+
+
+// Helper.
+
+function TestWithProxies(test, construct, handler) {
+ test(construct, handler, Proxy.create)
+ test(construct, handler, function(h) {
+ return Proxy.createFunction(h, function() {})
+ })
+}
+
+
+// Sets.
+
+function TestSet(construct, fix) {
+ TestWithProxies(TestSet2, construct, fix)
+}
+
+function TestSet2(construct, fix, create) {
+ var handler = {fix: function() { return {} }}
+ var p1 = create(handler)
+ var p2 = create(handler)
+ var p3 = create(handler)
+ fix(p3)
+
+ var s = construct();
+ s.add(p1);
+ s.add(p2);
+ assertTrue(s.has(p1));
+ assertTrue(s.has(p2));
+ assertFalse(s.has(p3));
+
+ fix(p1)
+ fix(p2)
+ assertTrue(s.has(p1));
+ assertTrue(s.has(p2));
+ assertFalse(s.has(p3));
+
+ s.delete(p2);
+ assertTrue(s.has(p1));
+ assertFalse(s.has(p2));
+ assertFalse(s.has(p3));
+}
+
+TestSet(Set, Object.seal)
+TestSet(Set, Object.freeze)
+TestSet(Set, Object.preventExtensions)
+
+
+// Maps and weak maps.
+
+function TestMap(construct, fix) {
+ TestWithProxies(TestMap2, construct, fix)
+}
+
+function TestMap2(construct, fix, create) {
+ var handler = {fix: function() { return {} }}
+ var p1 = create(handler)
+ var p2 = create(handler)
+ var p3 = create(handler)
+ fix(p3)
+
+ var m = construct();
+ m.set(p1, 123);
+ m.set(p2, 321);
+ assertTrue(m.has(p1));
+ assertTrue(m.has(p2));
+ assertFalse(m.has(p3));
+ assertSame(123, m.get(p1));
+ assertSame(321, m.get(p2));
+
+ fix(p1)
+ fix(p2)
+ assertTrue(m.has(p1));
+ assertTrue(m.has(p2));
+ assertFalse(m.has(p3));
+ assertSame(123, m.get(p1));
+ assertSame(321, m.get(p2));
+
+ m.delete(p2);
+ assertTrue(m.has(p1));
+ assertFalse(m.has(p2));
+ assertFalse(m.has(p3));
+ assertSame(123, m.get(p1));
+ assertSame(undefined, m.get(p2));
+}
+
+TestMap(Map, Object.seal)
+TestMap(Map, Object.freeze)
+TestMap(Map, Object.preventExtensions)
+
+TestMap(WeakMap, Object.seal)
+TestMap(WeakMap, Object.freeze)
+TestMap(WeakMap, Object.preventExtensions)
diff --git a/test/mjsunit/harmony/proxies.js b/test/mjsunit/harmony/proxies.js
index 3c4e5f61..8d8f8399 100644
--- a/test/mjsunit/harmony/proxies.js
+++ b/test/mjsunit/harmony/proxies.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// 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:
@@ -28,70 +28,167 @@
// Flags: --harmony-proxies
-// TODO(rossberg): for-in for proxies not implemented.
-// TODO(rossberg): inheritance from proxies not implemented.
-// TODO(rossberg): function proxies as constructors not implemented.
+// Helper.
+function TestWithProxies(test, x, y, z) {
+ test(Proxy.create, x, y, z)
+ test(function(h) {return Proxy.createFunction(h, function() {})}, x, y, z)
+}
-// Helper.
-function TestWithProxies(test, handler) {
- test(handler, Proxy.create)
- test(handler, function(h) {return Proxy.createFunction(h, function() {})})
+
+// Getting property descriptors (Object.getOwnPropertyDescriptor).
+
+var key
+
+function TestGetOwnProperty(handler) {
+ TestWithProxies(TestGetOwnProperty2, handler)
+}
+
+function TestGetOwnProperty2(create, handler) {
+ var p = create(handler)
+ assertEquals(42, Object.getOwnPropertyDescriptor(p, "a").value)
+ assertEquals("a", key)
+ assertEquals(42, Object.getOwnPropertyDescriptor(p, 99).value)
+ assertEquals("99", key)
}
+TestGetOwnProperty({
+ getOwnPropertyDescriptor: function(k) {
+ key = k
+ return {value: 42, configurable: true}
+ }
+})
+
+TestGetOwnProperty({
+ getOwnPropertyDescriptor: function(k) {
+ return this.getOwnPropertyDescriptor2(k)
+ },
+ getOwnPropertyDescriptor2: function(k) {
+ key = k
+ return {value: 42, configurable: true}
+ }
+})
+
+TestGetOwnProperty({
+ getOwnPropertyDescriptor: function(k) {
+ key = k
+ return {get value() { return 42 }, get configurable() { return true }}
+ }
+})
+
+TestGetOwnProperty(Proxy.create({
+ get: function(pr, pk) {
+ return function(k) { key = k; return {value: 42, configurable: true} }
+ }
+}))
-// Getters.
+
+function TestGetOwnPropertyThrow(handler) {
+ TestWithProxies(TestGetOwnPropertyThrow2, handler)
+}
+
+function TestGetOwnPropertyThrow2(create, handler) {
+ var p = create(handler)
+ assertThrows(function(){ Object.getOwnPropertyDescriptor(p, "a") }, "myexn")
+ assertThrows(function(){ Object.getOwnPropertyDescriptor(p, 77) }, "myexn")
+}
+
+TestGetOwnPropertyThrow({
+ getOwnPropertyDescriptor: function(k) { throw "myexn" }
+})
+
+TestGetOwnPropertyThrow({
+ getOwnPropertyDescriptor: function(k) {
+ return this.getPropertyDescriptor2(k)
+ },
+ getOwnPropertyDescriptor2: function(k) { throw "myexn" }
+})
+
+TestGetOwnPropertyThrow({
+ getOwnPropertyDescriptor: function(k) {
+ return {get value() { throw "myexn" }}
+ }
+})
+
+TestGetOwnPropertyThrow(Proxy.create({
+ get: function(pr, pk) {
+ return function(k) { throw "myexn" }
+ }
+}))
+
+
+
+// Getters (dot, brackets).
+
+var key
function TestGet(handler) {
TestWithProxies(TestGet2, handler)
}
-function TestGet2(handler, create) {
+function TestGet2(create, handler) {
var p = create(handler)
assertEquals(42, p.a)
+ assertEquals("a", key)
assertEquals(42, p["b"])
+ assertEquals("b", key)
+ assertEquals(42, p[99])
+ assertEquals("99", key)
+ assertEquals(42, (function(n) { return p[n] })("c"))
+ assertEquals("c", key)
+ assertEquals(42, (function(n) { return p[n] })(101))
+ assertEquals("101", key)
- // TODO(rossberg): inheritance from proxies not yet implemented.
- // var o = Object.create(p, {x: {value: 88}})
- // assertEquals(42, o.a)
- // assertEquals(42, o["b"])
- // assertEquals(88, o.x)
- // assertEquals(88, o["x"])
+ var o = Object.create(p, {x: {value: 88}})
+ assertEquals(42, o.a)
+ assertEquals("a", key)
+ assertEquals(42, o["b"])
+ assertEquals("b", key)
+ assertEquals(42, o[99])
+ assertEquals("99", key)
+ assertEquals(88, o.x)
+ assertEquals(88, o["x"])
+ assertEquals(42, (function(n) { return o[n] })("c"))
+ assertEquals("c", key)
+ assertEquals(42, (function(n) { return o[n] })(101))
+ assertEquals("101", key)
+ assertEquals(88, (function(n) { return o[n] })("x"))
}
TestGet({
- get: function(r, k) { return 42 }
+ get: function(r, k) { key = k; return 42 }
})
TestGet({
get: function(r, k) { return this.get2(r, k) },
- get2: function(r, k) { return 42 }
+ get2: function(r, k) { key = k; return 42 }
})
TestGet({
- getPropertyDescriptor: function(k) { return {value: 42} }
+ getPropertyDescriptor: function(k) { key = k; return {value: 42} }
})
TestGet({
getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
- getPropertyDescriptor2: function(k) { return {value: 42} }
+ getPropertyDescriptor2: function(k) { key = k; return {value: 42} }
})
TestGet({
getPropertyDescriptor: function(k) {
+ key = k;
return {get value() { return 42 }}
}
})
TestGet({
get: undefined,
- getPropertyDescriptor: function(k) { return {value: 42} }
+ getPropertyDescriptor: function(k) { key = k; return {value: 42} }
})
TestGet(Proxy.create({
get: function(pr, pk) {
- return function(r, k) { return 42 }
+ return function(r, k) { key = k; return 42 }
}
}))
@@ -100,14 +197,43 @@ function TestGetCall(handler) {
TestWithProxies(TestGetCall2, handler)
}
-function TestGetCall2(handler, create) {
+function TestGetCall2(create, handler) {
var p = create(handler)
assertEquals(55, p.f())
+ assertEquals(55, p["f"]())
assertEquals(55, p.f("unused", "arguments"))
assertEquals(55, p.f.call(p))
+ assertEquals(55, p["f"].call(p))
+ assertEquals(55, p[101].call(p))
assertEquals(55, p.withargs(45, 5))
assertEquals(55, p.withargs.call(p, 11, 22))
+ assertEquals(55, (function(n) { return p[n]() })("f"))
+ assertEquals(55, (function(n) { return p[n].call(p) })("f"))
+ assertEquals(55, (function(n) { return p[n](15, 20) })("withargs"))
+ assertEquals(55, (function(n) { return p[n].call(p, 13, 21) })("withargs"))
assertEquals("6655", "66" + p) // calls p.toString
+
+ var o = Object.create(p, {g: {value: function(x) { return x + 88 }}})
+ assertEquals(55, o.f())
+ assertEquals(55, o["f"]())
+ assertEquals(55, o.f("unused", "arguments"))
+ assertEquals(55, o.f.call(o))
+ assertEquals(55, o.f.call(p))
+ assertEquals(55, o["f"].call(p))
+ assertEquals(55, o[101].call(p))
+ assertEquals(55, o.withargs(45, 5))
+ assertEquals(55, o.withargs.call(p, 11, 22))
+ assertEquals(90, o.g(2))
+ assertEquals(91, o.g.call(o, 3))
+ assertEquals(92, o.g.call(p, 4))
+ assertEquals(55, (function(n) { return o[n]() })("f"))
+ assertEquals(55, (function(n) { return o[n].call(o) })("f"))
+ assertEquals(55, (function(n) { return o[n](15, 20) })("withargs"))
+ assertEquals(55, (function(n) { return o[n].call(o, 13, 21) })("withargs"))
+ assertEquals(93, (function(n) { return o[n](5) })("g"))
+ assertEquals(94, (function(n) { return o[n].call(o, 6) })("g"))
+ assertEquals(95, (function(n) { return o[n].call(p, 7) })("g"))
+ assertEquals("6655", "66" + o) // calls o.toString
}
TestGetCall({
@@ -168,10 +294,20 @@ function TestGetThrow(handler) {
TestWithProxies(TestGetThrow2, handler)
}
-function TestGetThrow2(handler, create) {
+function TestGetThrow2(create, handler) {
var p = create(handler)
assertThrows(function(){ p.a }, "myexn")
assertThrows(function(){ p["b"] }, "myexn")
+ assertThrows(function(){ p[3] }, "myexn")
+ assertThrows(function(){ (function(n) { p[n] })("c") }, "myexn")
+ assertThrows(function(){ (function(n) { p[n] })(99) }, "myexn")
+
+ var o = Object.create(p, {x: {value: 88}, '4': {value: 89}})
+ assertThrows(function(){ o.a }, "myexn")
+ assertThrows(function(){ o["b"] }, "myexn")
+ assertThrows(function(){ o[3] }, "myexn")
+ assertThrows(function(){ (function(n) { o[n] })("c") }, "myexn")
+ assertThrows(function(){ (function(n) { o[n] })(99) }, "myexn")
}
TestGetThrow({
@@ -220,11 +356,11 @@ TestGetThrow(Proxy.create({
var key
var val
-function TestSet(handler, create) {
+function TestSet(handler) {
TestWithProxies(TestSet2, handler)
}
-function TestSet2(handler, create) {
+function TestSet2(create, handler) {
var p = create(handler)
assertEquals(42, p.a = 42)
assertEquals("a", key)
@@ -232,6 +368,16 @@ function TestSet2(handler, create) {
assertEquals(43, p["b"] = 43)
assertEquals("b", key)
assertEquals(43, val)
+ assertEquals(44, p[77] = 44)
+ assertEquals("77", key)
+ assertEquals(44, val)
+
+ assertEquals(45, (function(n) { return p[n] = 45 })("c"))
+ assertEquals("c", key)
+ assertEquals(45, val)
+ assertEquals(46, (function(n) { return p[n] = 46 })(99))
+ assertEquals("99", key)
+ assertEquals(46, val)
}
TestSet({
@@ -304,15 +450,17 @@ TestSet(Proxy.create({
}))
-
-function TestSetThrow(handler, create) {
+function TestSetThrow(handler) {
TestWithProxies(TestSetThrow2, handler)
}
-function TestSetThrow2(handler, create) {
+function TestSetThrow2(create, handler) {
var p = create(handler)
assertThrows(function(){ p.a = 42 }, "myexn")
assertThrows(function(){ p["b"] = 42 }, "myexn")
+ assertThrows(function(){ p[22] = 42 }, "myexn")
+ assertThrows(function(){ (function(n) { p[n] = 45 })("c") }, "myexn")
+ assertThrows(function(){ (function(n) { p[n] = 46 })(99) }, "myexn")
}
TestSetThrow({
@@ -424,6 +572,124 @@ TestSetThrow(Proxy.create({
}))
+var key
+var val
+
+function TestSetForDerived(handler) {
+ TestWithProxies(TestSetForDerived2, handler)
+}
+
+function TestSetForDerived2(create, handler) {
+ var p = create(handler)
+ var o = Object.create(p, {x: {value: 88, writable: true},
+ '1': {value: 89, writable: true}})
+
+ key = ""
+ assertEquals(48, o.x = 48)
+ assertEquals("", key) // trap not invoked
+ assertEquals(48, o.x)
+
+ assertEquals(47, o[1] = 47)
+ assertEquals("", key) // trap not invoked
+ assertEquals(47, o[1])
+
+ assertEquals(49, o.y = 49)
+ assertEquals("y", key)
+ assertEquals(49, o.y)
+
+ assertEquals(50, o[2] = 50)
+ assertEquals("2", key)
+ assertEquals(50, o[2])
+
+ assertEquals(44, o.p_writable = 44)
+ assertEquals("p_writable", key)
+ assertEquals(44, o.p_writable)
+
+ assertEquals(45, o.p_nonwritable = 45)
+ assertEquals("p_nonwritable", key)
+ assertEquals(45, o.p_nonwritable)
+
+ assertEquals(46, o.p_setter = 46)
+ assertEquals("p_setter", key)
+ assertEquals(46, val) // written to parent
+ assertFalse(Object.prototype.hasOwnProperty.call(o, "p_setter"))
+
+ val = ""
+ assertEquals(47, o.p_nosetter = 47)
+ assertEquals("p_nosetter", key)
+ assertEquals("", val) // not written at all
+ assertFalse(Object.prototype.hasOwnProperty.call(o, "p_nosetter"));
+
+ key = ""
+ assertThrows(function(){ "use strict"; o.p_nosetter = 50 }, TypeError)
+ assertEquals("p_nosetter", key)
+ assertEquals("", val) // not written at all
+
+ assertThrows(function(){ o.p_nonconf = 53 }, TypeError)
+ assertEquals("p_nonconf", key)
+
+ assertThrows(function(){ o.p_throw = 51 }, "myexn")
+ assertEquals("p_throw", key)
+
+ assertThrows(function(){ o.p_setterthrow = 52 }, "myexn")
+ assertEquals("p_setterthrow", key)
+}
+
+TestSetForDerived({
+ getPropertyDescriptor: function(k) {
+ key = k;
+ switch (k) {
+ case "p_writable": return {writable: true, configurable: true}
+ case "p_nonwritable": return {writable: false, configurable: true}
+ case "p_setter":return {set: function(x) { val = x }, configurable: true}
+ case "p_nosetter": return {get: function() { return 1 }, configurable: true}
+ case "p_nonconf":return {}
+ case "p_throw": throw "myexn"
+ case "p_setterthrow": return {set: function(x) { throw "myexn" }}
+ default: return undefined
+ }
+ }
+})
+
+
+// Evil proxy-induced side-effects shouldn't crash.
+// TODO(rossberg): proper behaviour isn't really spec'ed yet, so ignore results.
+
+TestWithProxies(function(create) {
+ var calls = 0
+ var handler = {
+ getPropertyDescriptor: function() {
+ ++calls
+ return (calls % 2 == 1)
+ ? {get: function() { return 5 }, configurable: true}
+ : {set: function() { return false }, configurable: true}
+ }
+ }
+ var p = create(handler)
+ var o = Object.create(p)
+ // Make proxy prototype property read-only after CanPut check.
+ try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestWithProxies(function(create) {
+ var handler = {
+ getPropertyDescriptor: function() {
+ Object.defineProperty(o, "x", {get: function() { return 5 }});
+ return {set: function() {}}
+ }
+ }
+ var p = create(handler)
+ var o = Object.create(p)
+ // Make object property read-only after CanPut check.
+ try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
+})
+
+
+
+// TODO(rossberg): TestSetReject, returning false
+// TODO(rossberg): TestGetProperty, TestSetProperty
+
+
// Property definition (Object.defineProperty and Object.defineProperties).
@@ -434,7 +700,7 @@ function TestDefine(handler) {
TestWithProxies(TestDefine2, handler)
}
-function TestDefine2(handler, create) {
+function TestDefine2(create, handler) {
var p = create(handler)
assertEquals(p, Object.defineProperty(p, "a", {value: 44}))
assertEquals("a", key)
@@ -453,6 +719,12 @@ function TestDefine2(handler, create) {
assertEquals(46, desc.value)
assertEquals(false, desc.enumerable)
+ assertEquals(p, Object.defineProperty(p, 101, {value: 47, enumerable: false}))
+ assertEquals("101", key)
+ assertEquals(2, Object.getOwnPropertyNames(desc).length)
+ assertEquals(47, desc.value)
+ assertEquals(false, desc.enumerable)
+
var attributes = {configurable: true, mine: 66, minetoo: 23}
assertEquals(p, Object.defineProperty(p, "d", attributes))
assertEquals("d", key)
@@ -474,20 +746,20 @@ function TestDefine2(handler, create) {
assertEquals("zzz", key)
assertEquals(0, Object.getOwnPropertyNames(desc).length)
-// TODO(rossberg): This test requires for-in on proxies.
-// var d = create({
-// get: function(r, k) { return (k === "value") ? 77 : void 0 },
-// getOwnPropertyNames: function() { return ["value"] }
-// })
-// assertEquals(1, Object.getOwnPropertyNames(d).length)
-// assertEquals(77, d.value)
-// assertEquals(p, Object.defineProperty(p, "p", d))
-// assertEquals("p", key)
-// assertEquals(1, Object.getOwnPropertyNames(desc).length)
-// assertEquals(77, desc.value)
+ var d = create({
+ get: function(r, k) { return (k === "value") ? 77 : void 0 },
+ getOwnPropertyNames: function() { return ["value"] },
+ enumerate: function() { return ["value"] }
+ })
+ assertEquals(1, Object.getOwnPropertyNames(d).length)
+ assertEquals(77, d.value)
+ assertEquals(p, Object.defineProperty(p, "p", d))
+ assertEquals("p", key)
+ assertEquals(1, Object.getOwnPropertyNames(desc).length)
+ assertEquals(77, desc.value)
var props = {
- 'bla': {},
+ '11': {},
blub: {get: function() { return true }},
'': {get value() { return 20 }},
last: {value: 21, configurable: true, mine: "eyes"}
@@ -524,21 +796,21 @@ function TestDefineThrow(handler) {
TestWithProxies(TestDefineThrow2, handler)
}
-function TestDefineThrow2(handler, create) {
+function TestDefineThrow2(create, handler) {
var p = create(handler)
assertThrows(function(){ Object.defineProperty(p, "a", {value: 44})}, "myexn")
-
-// TODO(rossberg): These tests require for-in on proxies.
-// var d1 = create({
-// get: function(r, k) { throw "myexn" },
-// getOwnPropertyNames: function() { return ["value"] }
-// })
-// assertThrows(function(){ Object.defineProperty(p, "p", d1) }, "myexn")
-// var d2 = create({
-// get: function(r, k) { return 77 },
-// getOwnPropertyNames: function() { throw "myexn" }
-// })
-// assertThrows(function(){ Object.defineProperty(p, "p", d2) }, "myexn")
+ assertThrows(function(){ Object.defineProperty(p, 0, {value: 44})}, "myexn")
+
+ var d1 = create({
+ get: function(r, k) { throw "myexn" },
+ getOwnPropertyNames: function() { return ["value"] }
+ })
+ assertThrows(function(){ Object.defineProperty(p, "p", d1) }, "myexn")
+ var d2 = create({
+ get: function(r, k) { return 77 },
+ getOwnPropertyNames: function() { throw "myexn" }
+ })
+ assertThrows(function(){ Object.defineProperty(p, "p", d2) }, "myexn")
var props = {bla: {get value() { throw "otherexn" }}}
assertThrows(function(){ Object.defineProperties(p, props) }, "otherexn")
@@ -573,12 +845,14 @@ function TestDelete(handler) {
TestWithProxies(TestDelete2, handler)
}
-function TestDelete2(handler, create) {
+function TestDelete2(create, handler) {
var p = create(handler)
assertEquals(true, delete p.a)
assertEquals("a", key)
assertEquals(true, delete p["b"])
assertEquals("b", key)
+ assertEquals(true, delete p[1])
+ assertEquals("1", key)
assertEquals(false, delete p.z1)
assertEquals("z1", key)
@@ -591,6 +865,8 @@ function TestDelete2(handler, create) {
assertEquals("c", key)
assertEquals(true, delete p["d"])
assertEquals("d", key)
+ assertEquals(true, delete p[2])
+ assertEquals("2", key)
assertThrows(function(){ delete p.z3 }, TypeError)
assertEquals("z3", key)
@@ -619,15 +895,17 @@ function TestDeleteThrow(handler) {
TestWithProxies(TestDeleteThrow2, handler)
}
-function TestDeleteThrow2(handler, create) {
+function TestDeleteThrow2(create, handler) {
var p = create(handler)
assertThrows(function(){ delete p.a }, "myexn")
assertThrows(function(){ delete p["b"] }, "myexn");
+ assertThrows(function(){ delete p[3] }, "myexn");
(function() {
"use strict"
assertThrows(function(){ delete p.c }, "myexn")
assertThrows(function(){ delete p["d"] }, "myexn")
+ assertThrows(function(){ delete p[4] }, "myexn");
})()
}
@@ -658,7 +936,7 @@ function TestDescriptor(handler) {
TestWithProxies(TestDescriptor2, handler)
}
-function TestDescriptor2(handler, create) {
+function TestDescriptor2(create, handler) {
var p = create(handler)
var descs = [
{configurable: true},
@@ -697,7 +975,7 @@ function TestDescriptorThrow(handler) {
TestWithProxies(TestDescriptorThrow2, handler)
}
-function TestDescriptorThrow2(handler, create) {
+function TestDescriptorThrow2(create, handler) {
var p = create(handler)
assertThrows(function(){ Object.getOwnPropertyDescriptor(p, "a") }, "myexn")
}
@@ -721,7 +999,7 @@ function TestComparison(eq) {
TestWithProxies(TestComparison2, eq)
}
-function TestComparison2(eq, create) {
+function TestComparison2(create, eq) {
var p1 = create({})
var p2 = create({})
@@ -764,7 +1042,7 @@ function TestIn(handler) {
TestWithProxies(TestIn2, handler)
}
-function TestIn2(handler, create) {
+function TestIn2(create, handler) {
var p = create(handler)
assertTrue("a" in p)
assertEquals("a", key)
@@ -778,6 +1056,7 @@ function TestIn2(handler, create) {
assertEquals(0, ("zzz" in p) ? 2 : 0)
assertEquals(2, !("zzz" in p) ? 2 : 0)
+ // Test compilation in conditionals.
if ("b" in p) {
} else {
assertTrue(false)
@@ -830,7 +1109,7 @@ TestIn({
})
TestIn({
- get: undefined,
+ has: undefined,
getPropertyDescriptor: function(k) {
key = k; return k < "z" ? {value: 42} : void 0
}
@@ -847,9 +1126,10 @@ function TestInThrow(handler) {
TestWithProxies(TestInThrow2, handler)
}
-function TestInThrow2(handler, create) {
+function TestInThrow2(create, handler) {
var p = create(handler)
assertThrows(function(){ return "a" in o }, "myexn")
+ assertThrows(function(){ return 99 in o }, "myexn")
assertThrows(function(){ return !("a" in o) }, "myexn")
assertThrows(function(){ return ("a" in o) ? 2 : 3 }, "myexn")
assertThrows(function(){ if ("b" in o) {} }, "myexn")
@@ -876,7 +1156,7 @@ TestInThrow({
})
TestInThrow({
- get: undefined,
+ has: undefined,
getPropertyDescriptor: function(k) { throw "myexn" }
})
@@ -891,6 +1171,158 @@ TestInThrow(Proxy.create({
}))
+function TestInForDerived(handler) {
+ TestWithProxies(TestInForDerived2, handler)
+}
+
+function TestInForDerived2(create, handler) {
+ var p = create(handler)
+ var o = Object.create(p)
+
+ assertTrue("a" in o)
+ assertEquals("a", key)
+ assertTrue(99 in o)
+ assertEquals("99", key)
+ assertFalse("z" in o)
+ assertEquals("z", key)
+
+ assertEquals(2, ("a" in o) ? 2 : 0)
+ assertEquals(0, !("a" in o) ? 2 : 0)
+ assertEquals(0, ("zzz" in o) ? 2 : 0)
+ assertEquals(2, !("zzz" in o) ? 2 : 0)
+
+ if ("b" in o) {
+ } else {
+ assertTrue(false)
+ }
+ assertEquals("b", key)
+
+ if ("zz" in o) {
+ assertTrue(false)
+ }
+ assertEquals("zz", key)
+
+ if (!("c" in o)) {
+ assertTrue(false)
+ }
+ assertEquals("c", key)
+
+ if (!("zzz" in o)) {
+ } else {
+ assertTrue(false)
+ }
+ assertEquals("zzz", key)
+}
+
+TestInForDerived({
+ getPropertyDescriptor: function(k) {
+ key = k; return k < "z" ? {value: 42, configurable: true} : void 0
+ }
+})
+
+TestInForDerived({
+ getPropertyDescriptor: function(k) { return this.getPropertyDescriptor2(k) },
+ getPropertyDescriptor2: function(k) {
+ key = k; return k < "z" ? {value: 42, configurable: true} : void 0
+ }
+})
+
+TestInForDerived({
+ getPropertyDescriptor: function(k) {
+ key = k;
+ return k < "z" ? {get value() { return 42 }, configurable: true} : void 0
+ }
+})
+
+/* TODO(rossberg): this will work once we implement the newest proposal
+ * regarding default traps for getPropertyDescriptor.
+TestInForDerived({
+ getOwnPropertyDescriptor: function(k) {
+ key = k; return k < "z" ? {value: 42, configurable: true} : void 0
+ }
+})
+
+TestInForDerived({
+ getOwnPropertyDescriptor: function(k) {
+ return this.getOwnPropertyDescriptor2(k)
+ },
+ getOwnPropertyDescriptor2: function(k) {
+ key = k; return k < "z" ? {value: 42, configurable: true} : void 0
+ }
+})
+
+TestInForDerived({
+ getOwnPropertyDescriptor: function(k) {
+ key = k;
+ return k < "z" ? {get value() { return 42 }, configurable: true} : void 0
+ }
+})
+*/
+
+TestInForDerived(Proxy.create({
+ get: function(pr, pk) {
+ return function(k) {
+ key = k; return k < "z" ? {value: 42, configurable: true} : void 0
+ }
+ }
+}))
+
+
+
+// Property descriptor conversion.
+
+var descget
+
+function TestDescriptorGetOrder(handler) {
+ var p = Proxy.create(handler)
+ var o = Object.create(p, {b: {value: 0}})
+ TestDescriptorGetOrder2(function(n) { return p[n] }, "vV")
+ TestDescriptorGetOrder2(function(n) { return n in p }, "")
+ TestDescriptorGetOrder2(function(n) { return o[n] }, "vV")
+ TestDescriptorGetOrder2(function(n) { return n in o }, "eEcCvVwWgs")
+}
+
+function TestDescriptorGetOrder2(f, access) {
+ descget = ""
+ assertTrue(f("a"))
+ assertEquals(access, descget)
+ descget = ""
+ assertTrue(f(99))
+ assertEquals(access, descget)
+ descget = ""
+ assertFalse(!!f("z"))
+ assertEquals("", descget)
+}
+
+TestDescriptorGetOrder({
+ getPropertyDescriptor: function(k) {
+ if (k >= "z") return void 0
+ // Return a proxy as property descriptor, so that we can log accesses.
+ return Proxy.create({
+ get: function(r, attr) {
+ descget += attr[0].toUpperCase()
+ return true
+ },
+ has: function(attr) {
+ descget += attr[0]
+ switch (attr) {
+ case "writable":
+ case "enumerable":
+ case "configurable":
+ case "value":
+ return true
+ case "get":
+ case "set":
+ return false
+ default:
+ assertUnreachable()
+ }
+ }
+ })
+ }
+})
+
+
// Own Properties (Object.prototype.hasOwnProperty).
@@ -900,7 +1332,7 @@ function TestHasOwn(handler) {
TestWithProxies(TestHasOwn2, handler)
}
-function TestHasOwn2(handler, create) {
+function TestHasOwn2(create, handler) {
var p = create(handler)
assertTrue(Object.prototype.hasOwnProperty.call(p, "a"))
assertEquals("a", key)
@@ -958,7 +1390,7 @@ function TestHasOwnThrow(handler) {
TestWithProxies(TestHasOwnThrow2, handler)
}
-function TestHasOwnThrow2(handler, create) {
+function TestHasOwnThrow2(create, handler) {
var p = create(handler)
assertThrows(function(){ Object.prototype.hasOwnProperty.call(p, "a")},
"myexn")
@@ -1005,84 +1437,173 @@ TestHasOwnThrow(Proxy.create({
// Instanceof (instanceof)
-function TestInstanceof() {
- var o = {}
+function TestProxyInstanceof() {
+ var o1 = {}
var p1 = Proxy.create({})
- var p2 = Proxy.create({}, o)
+ var p2 = Proxy.create({}, o1)
var p3 = Proxy.create({}, p2)
+ var o2 = Object.create(p2)
var f0 = function() {}
- f0.prototype = o
+ f0.prototype = o1
var f1 = function() {}
f1.prototype = p1
var f2 = function() {}
f2.prototype = p2
-
- assertTrue(o instanceof Object)
- assertFalse(o instanceof f0)
- assertFalse(o instanceof f1)
- assertFalse(o instanceof f2)
+ var f3 = function() {}
+ f3.prototype = o2
+
+ assertTrue(o1 instanceof Object)
+ assertFalse(o1 instanceof f0)
+ assertFalse(o1 instanceof f1)
+ assertFalse(o1 instanceof f2)
+ assertFalse(o1 instanceof f3)
assertFalse(p1 instanceof Object)
assertFalse(p1 instanceof f0)
assertFalse(p1 instanceof f1)
assertFalse(p1 instanceof f2)
+ assertFalse(p1 instanceof f3)
assertTrue(p2 instanceof Object)
assertTrue(p2 instanceof f0)
assertFalse(p2 instanceof f1)
assertFalse(p2 instanceof f2)
+ assertFalse(p2 instanceof f3)
assertTrue(p3 instanceof Object)
assertTrue(p3 instanceof f0)
assertFalse(p3 instanceof f1)
assertTrue(p3 instanceof f2)
+ assertFalse(p3 instanceof f3)
+ assertTrue(o2 instanceof Object)
+ assertTrue(o2 instanceof f0)
+ assertFalse(o2 instanceof f1)
+ assertTrue(o2 instanceof f2)
+ assertFalse(o2 instanceof f3)
var f = Proxy.createFunction({}, function() {})
assertTrue(f instanceof Function)
}
-TestInstanceof()
+TestProxyInstanceof()
+
+
+function TestInstanceofProxy() {
+ var o0 = Object.create(null)
+ var o1 = {}
+ var o2 = Object.create(o0)
+ var o3 = Object.create(o1)
+ var o4 = Object.create(o2)
+ var o5 = Object.create(o3)
+
+ function handler(o) { return {get: function() { return o } } }
+ var f0 = Proxy.createFunction(handler(o0), function() {})
+ var f1 = Proxy.createFunction(handler(o1), function() {})
+ var f2 = Proxy.createFunction(handler(o2), function() {})
+ var f3 = Proxy.createFunction(handler(o3), function() {})
+ var f4 = Proxy.createFunction(handler(o4), function() {})
+ var f5 = Proxy.createFunction(handler(o4), function() {})
+
+ assertFalse(null instanceof f0)
+ assertFalse(o0 instanceof f0)
+ assertFalse(o0 instanceof f1)
+ assertFalse(o0 instanceof f2)
+ assertFalse(o0 instanceof f3)
+ assertFalse(o0 instanceof f4)
+ assertFalse(o0 instanceof f5)
+ assertFalse(o1 instanceof f0)
+ assertFalse(o1 instanceof f1)
+ assertFalse(o1 instanceof f2)
+ assertFalse(o1 instanceof f3)
+ assertFalse(o1 instanceof f4)
+ assertFalse(o1 instanceof f5)
+ assertTrue(o2 instanceof f0)
+ assertFalse(o2 instanceof f1)
+ assertFalse(o2 instanceof f2)
+ assertFalse(o2 instanceof f3)
+ assertFalse(o2 instanceof f4)
+ assertFalse(o2 instanceof f5)
+ assertFalse(o3 instanceof f0)
+ assertTrue(o3 instanceof f1)
+ assertFalse(o3 instanceof f2)
+ assertFalse(o3 instanceof f3)
+ assertFalse(o3 instanceof f4)
+ assertFalse(o3 instanceof f5)
+ assertTrue(o4 instanceof f0)
+ assertFalse(o4 instanceof f1)
+ assertTrue(o4 instanceof f2)
+ assertFalse(o4 instanceof f3)
+ assertFalse(o4 instanceof f4)
+ assertFalse(o4 instanceof f5)
+ assertFalse(o5 instanceof f0)
+ assertTrue(o5 instanceof f1)
+ assertFalse(o5 instanceof f2)
+ assertTrue(o5 instanceof f3)
+ assertFalse(o5 instanceof f4)
+ assertFalse(o5 instanceof f5)
+
+ var f = Proxy.createFunction({}, function() {})
+ var ff = Proxy.createFunction(handler(Function), function() {})
+ assertTrue(f instanceof Function)
+ assertFalse(f instanceof ff)
+}
+
+TestInstanceofProxy()
// Prototype (Object.getPrototypeOf, Object.prototype.isPrototypeOf).
function TestPrototype() {
- var o = {}
+ var o1 = {}
var p1 = Proxy.create({})
- var p2 = Proxy.create({}, o)
+ var p2 = Proxy.create({}, o1)
var p3 = Proxy.create({}, p2)
- var p4 = Proxy.create({}, 666)
+ var p4 = Proxy.create({}, null)
+ var o2 = Object.create(p3)
- assertSame(Object.getPrototypeOf(o), Object.prototype)
+ assertSame(Object.getPrototypeOf(o1), Object.prototype)
assertSame(Object.getPrototypeOf(p1), null)
- assertSame(Object.getPrototypeOf(p2), o)
+ assertSame(Object.getPrototypeOf(p2), o1)
assertSame(Object.getPrototypeOf(p3), p2)
assertSame(Object.getPrototypeOf(p4), null)
+ assertSame(Object.getPrototypeOf(o2), p3)
- assertTrue(Object.prototype.isPrototypeOf(o))
+ assertTrue(Object.prototype.isPrototypeOf(o1))
assertFalse(Object.prototype.isPrototypeOf(p1))
assertTrue(Object.prototype.isPrototypeOf(p2))
assertTrue(Object.prototype.isPrototypeOf(p3))
assertFalse(Object.prototype.isPrototypeOf(p4))
- assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o))
+ assertTrue(Object.prototype.isPrototypeOf(o2))
+ assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o1))
assertFalse(Object.prototype.isPrototypeOf.call(Object.prototype, p1))
assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p2))
assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, p3))
assertFalse(Object.prototype.isPrototypeOf.call(Object.prototype, p4))
- assertFalse(Object.prototype.isPrototypeOf.call(o, o))
- assertFalse(Object.prototype.isPrototypeOf.call(o, p1))
- assertTrue(Object.prototype.isPrototypeOf.call(o, p2))
- assertTrue(Object.prototype.isPrototypeOf.call(o, p3))
- assertFalse(Object.prototype.isPrototypeOf.call(o, p4))
+ assertTrue(Object.prototype.isPrototypeOf.call(Object.prototype, o2))
+ assertFalse(Object.prototype.isPrototypeOf.call(o1, o1))
+ assertFalse(Object.prototype.isPrototypeOf.call(o1, p1))
+ assertTrue(Object.prototype.isPrototypeOf.call(o1, p2))
+ assertTrue(Object.prototype.isPrototypeOf.call(o1, p3))
+ assertFalse(Object.prototype.isPrototypeOf.call(o1, p4))
+ assertTrue(Object.prototype.isPrototypeOf.call(o1, o2))
assertFalse(Object.prototype.isPrototypeOf.call(p1, p1))
- assertFalse(Object.prototype.isPrototypeOf.call(p1, o))
+ assertFalse(Object.prototype.isPrototypeOf.call(p1, o1))
assertFalse(Object.prototype.isPrototypeOf.call(p1, p2))
assertFalse(Object.prototype.isPrototypeOf.call(p1, p3))
assertFalse(Object.prototype.isPrototypeOf.call(p1, p4))
+ assertFalse(Object.prototype.isPrototypeOf.call(p1, o2))
assertFalse(Object.prototype.isPrototypeOf.call(p2, p1))
assertFalse(Object.prototype.isPrototypeOf.call(p2, p2))
assertTrue(Object.prototype.isPrototypeOf.call(p2, p3))
assertFalse(Object.prototype.isPrototypeOf.call(p2, p4))
+ assertTrue(Object.prototype.isPrototypeOf.call(p2, o2))
assertFalse(Object.prototype.isPrototypeOf.call(p3, p2))
+ assertTrue(Object.prototype.isPrototypeOf.call(p3, o2))
+ assertFalse(Object.prototype.isPrototypeOf.call(o2, o1))
+ assertFalse(Object.prototype.isPrototypeOf.call(o2, p1))
+ assertFalse(Object.prototype.isPrototypeOf.call(o2, p2))
+ assertFalse(Object.prototype.isPrototypeOf.call(o2, p3))
+ assertFalse(Object.prototype.isPrototypeOf.call(o2, p4))
+ assertFalse(Object.prototype.isPrototypeOf.call(o2, o2))
var f = Proxy.createFunction({}, function() {})
assertSame(Object.getPrototypeOf(f), Function.prototype)
@@ -1097,12 +1618,12 @@ TestPrototype()
// Property names (Object.getOwnPropertyNames, Object.keys).
function TestPropertyNames(names, handler) {
- TestWithProxies(TestPropertyNames2, [names, handler])
+ TestWithProxies(TestPropertyNames2, handler, names)
}
-function TestPropertyNames2(names_handler, create) {
- var p = create(names_handler[1])
- assertArrayEquals(names_handler[0], Object.getOwnPropertyNames(p))
+function TestPropertyNames2(create, handler, names) {
+ var p = create(handler)
+ assertArrayEquals(names, Object.getOwnPropertyNames(p))
}
TestPropertyNames([], {
@@ -1129,7 +1650,7 @@ function TestPropertyNamesThrow(handler) {
TestWithProxies(TestPropertyNamesThrow2, handler)
}
-function TestPropertyNamesThrow2(handler, create) {
+function TestPropertyNamesThrow2(create, handler) {
var p = create(handler)
assertThrows(function(){ Object.getOwnPropertyNames(p) }, "myexn")
}
@@ -1145,12 +1666,12 @@ TestPropertyNamesThrow({
function TestKeys(names, handler) {
- TestWithProxies(TestKeys2, [names, handler])
+ TestWithProxies(TestKeys2, handler, names)
}
-function TestKeys2(names_handler, create) {
- var p = create(names_handler[1])
- assertArrayEquals(names_handler[0], Object.keys(p))
+function TestKeys2(create, handler, names) {
+ var p = create(handler)
+ assertArrayEquals(names, Object.keys(p))
}
TestKeys([], {
@@ -1174,7 +1695,9 @@ TestKeys(["[object Object]"], {
TestKeys(["a", "0"], {
getOwnPropertyNames: function() { return ["a", 23, "zz", "", 0] },
- getOwnPropertyDescriptor: function(k) { return {enumerable: k.length == 1} }
+ getOwnPropertyDescriptor: function(k) {
+ return k == "" ? undefined : {enumerable: k.length == 1}
+ }
})
TestKeys(["23", "zz", ""], {
@@ -1188,10 +1711,12 @@ TestKeys(["23", "zz", ""], {
TestKeys(["a", "b", "c", "5"], {
get getOwnPropertyNames() {
- return function() { return ["0", 4, "a", "b", "c", 5] }
+ return function() { return ["0", 4, "a", "b", "c", 5, "ety"] }
},
get getOwnPropertyDescriptor() {
- return function(k) { return {enumerable: k >= "44"} }
+ return function(k) {
+ return k == "ety" ? undefined : {enumerable: k >= "44"}
+ }
}
})
@@ -1207,7 +1732,7 @@ function TestKeysThrow(handler) {
TestWithProxies(TestKeysThrow2, handler)
}
-function TestKeysThrow2(handler, create) {
+function TestKeysThrow2(create, handler) {
var p = create(handler)
assertThrows(function(){ Object.keys(p) }, "myexn")
}
@@ -1267,7 +1792,6 @@ TestKeysThrow([], {
// Fixing (Object.freeze, Object.seal, Object.preventExtensions,
// Object.isFrozen, Object.isSealed, Object.isExtensible)
-// TODO(rossberg): use TestWithProxies to include funciton proxies
function TestFix(names, handler) {
var proto = {p: 77}
var assertFixing = function(o, s, f, e) {
@@ -1314,19 +1838,27 @@ function TestFix(names, handler) {
Object.keys(p3).sort())
assertEquals(proto, Object.getPrototypeOf(p3))
assertEquals(77, p3.p)
+
+ var p = Proxy.create(handler, proto)
+ var o = Object.create(p)
+ assertFixing(p, false, false, true)
+ assertFixing(o, false, false, true)
+ Object.freeze(o)
+ assertFixing(p, false, false, true)
+ assertFixing(o, true, true, false)
}
TestFix([], {
fix: function() { return {} }
})
-TestFix(["a", "b", "c", "d", "zz"], {
+TestFix(["a", "b", "c", "3", "zz"], {
fix: function() {
return {
a: {value: "a", writable: true, configurable: false, enumerable: true},
b: {value: 33, writable: false, configurable: false, enumerable: true},
c: {value: 0, writable: true, configurable: true, enumerable: true},
- d: {value: true, writable: false, configurable: true, enumerable: true},
+ '3': {value: true, writable: false, configurable: true, enumerable: true},
zz: {value: 0, enumerable: false}
}
}
@@ -1377,8 +1909,8 @@ function TestFixThrow(handler) {
TestWithProxies(TestFixThrow2, handler)
}
-function TestFixThrow2(handler) {
- var p = Proxy.create(handler, {})
+function TestFixThrow2(create, handler) {
+ var p = create(handler, {})
assertThrows(function(){ Object.seal(p) }, "myexn")
assertThrows(function(){ Object.freeze(p) }, "myexn")
assertThrows(function(){ Object.preventExtensions(p) }, "myexn")
@@ -1404,6 +1936,135 @@ TestFixThrow({
})
+// Freeze a proxy in the middle of operations on it.
+// TODO(rossberg): actual behaviour not specified consistently at the moment,
+// just make sure that we do not crash.
+function TestReentrantFix(f) {
+ TestWithProxies(f, Object.freeze)
+ TestWithProxies(f, Object.seal)
+ TestWithProxies(f, Object.preventExtensions)
+}
+
+TestReentrantFix(function(create, freeze) {
+ var handler = {
+ get get() { freeze(p); return undefined },
+ fix: function() { return {} }
+ }
+ var p = create(handler)
+ // Freeze while getting get trap.
+ try { p.x } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+ var handler = {
+ get: function() { freeze(p); return 3 },
+ fix: function() { return {} }
+ }
+ var p = create(handler)
+ // Freeze while executing get trap.
+ try { p.x } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+ var handler = {
+ getPropertyDescriptor: function() { freeze(p); return undefined },
+ fix: function() { return {} }
+ }
+ var p = create(handler)
+ // Freeze while executing default get trap.
+ try { p.x } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+ var handler = {
+ getPropertyDescriptor: function() { freeze(p); return {get: function(){}} },
+ fix: function() { return {} }
+ }
+ var p = create(handler)
+ var o = Object.create(p)
+ // Freeze while getting a property from prototype.
+ try { o.x } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+ var handler = {
+ get set() { freeze(p); return undefined },
+ fix: function() { return {} }
+ }
+ var p = create(handler)
+ // Freeze while getting set trap.
+ try { p.x = 4 } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+ var handler = {
+ set: function() { freeze(p); return true },
+ fix: function() { return {} }
+ }
+ var p = create(handler)
+ // Freeze while executing set trap.
+ try { p.x = 4 } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+ var handler = {
+ getOwnPropertyDescriptor: function() { freeze(p); return undefined },
+ fix: function() { return {} }
+ }
+ var p = create(handler)
+ // Freeze while executing default set trap.
+ try { p.x } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+ var handler = {
+ getPropertyDescriptor: function() { freeze(p); return {set: function(){}} },
+ fix: function() { return {} }
+ }
+ var p = create(handler)
+ var o = Object.create(p)
+ // Freeze while setting a property in prototype, dropping the property!
+ try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+ var handler = {
+ getPropertyDescriptor: function() { freeze(p); return {set: function(){}} },
+ fix: function() { return {x: {get: function(){}}} }
+ }
+ var p = create(handler)
+ var o = Object.create(p)
+ // Freeze while setting a property in prototype, making it read-only!
+ try { o.x = 4 } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+ var handler = {
+ get fix() { freeze(p); return function(){} }
+ }
+ var p = create(handler)
+ // Freeze while getting fix trap.
+ try { Object.freeze(p) } catch (e) { assertInstanceof(e, Error) }
+ p = create(handler)
+ try { Object.seal(p) } catch (e) { assertInstanceof(e, Error) }
+ p = create(handler)
+ try { Object.preventExtensions(p) } catch (e) { assertInstanceof(e, Error) }
+})
+
+TestReentrantFix(function(create, freeze) {
+ var handler = {
+ fix: function() { freeze(p); return {} }
+ }
+ var p = create(handler)
+ // Freeze while executing fix trap.
+ try { Object.freeze(p) } catch (e) { assertInstanceof(e, Error) }
+ p = create(handler)
+ try { Object.seal(p) } catch (e) { assertInstanceof(e, Error) }
+ p = create(handler)
+ try { Object.preventExtensions(p) } catch (e) { assertInstanceof(e, Error) }
+})
+
+
// String conversion (Object.prototype.toString,
// Object.prototype.toLocaleString,
@@ -1426,6 +2087,13 @@ function TestToString(handler) {
assertEquals("my_proxy", Object.prototype.toLocaleString.call(f))
assertEquals("toString", key)
assertDoesNotThrow(function(){ Function.prototype.toString.call(f) })
+
+ var o = Object.create(p)
+ key = ""
+ assertEquals("[object Object]", Object.prototype.toString.call(o))
+ assertEquals("", key)
+ assertEquals("my_proxy", Object.prototype.toLocaleString.call(o))
+ assertEquals("toString", key)
}
TestToString({
@@ -1452,6 +2120,10 @@ function TestToStringThrow(handler) {
var f = Proxy.createFunction(handler, function() {})
assertEquals("[object Function]", Object.prototype.toString.call(f))
assertThrows(function(){ Object.prototype.toLocaleString.call(f) }, "myexn")
+
+ var o = Object.create(p)
+ assertEquals("[object Object]", Object.prototype.toString.call(o))
+ assertThrows(function(){ Object.prototype.toLocaleString.call(o) }, "myexn")
}
TestToStringThrow({
@@ -1485,7 +2157,7 @@ function TestValueOf(handler) {
TestWithProxies(TestValueOf2, handler)
}
-function TestValueOf2(handler, create) {
+function TestValueOf2(create, handler) {
var p = create(handler)
assertSame(p, Object.prototype.valueOf.call(p))
}
@@ -1502,7 +2174,7 @@ function TestIsEnumerable(handler) {
TestWithProxies(TestIsEnumerable2, handler)
}
-function TestIsEnumerable2(handler, create) {
+function TestIsEnumerable2(create, handler) {
var p = create(handler)
assertTrue(Object.prototype.propertyIsEnumerable.call(p, "a"))
assertEquals("a", key)
@@ -1510,6 +2182,11 @@ function TestIsEnumerable2(handler, create) {
assertEquals("2", key)
assertFalse(Object.prototype.propertyIsEnumerable.call(p, "z"))
assertEquals("z", key)
+
+ var o = Object.create(p)
+ key = ""
+ assertFalse(Object.prototype.propertyIsEnumerable.call(o, "a"))
+ assertEquals("", key) // trap not invoked
}
TestIsEnumerable({
@@ -1546,7 +2223,7 @@ function TestIsEnumerableThrow(handler) {
TestWithProxies(TestIsEnumerableThrow2, handler)
}
-function TestIsEnumerableThrow2(handler, create) {
+function TestIsEnumerableThrow2(create, handler) {
var p = create(handler)
assertThrows(function(){ Object.prototype.propertyIsEnumerable.call(p, "a") },
"myexn")
@@ -1583,100 +2260,19 @@ TestIsEnumerableThrow(Proxy.create({
-// Calling (call, Function.prototype.call, Function.prototype.apply,
-// Function.prototype.bind).
-
-var global = this
-var receiver
-
-function TestCall(isStrict, callTrap) {
- assertEquals(42, callTrap(5, 37))
-// TODO(rossberg): unrelated bug: this does not succeed for optimized code.
-// assertEquals(isStrict ? undefined : global, receiver)
-
- var f = Proxy.createFunction({fix: function() { return {} }}, callTrap)
- receiver = 333
- assertEquals(42, f(11, 31))
- assertEquals(isStrict ? undefined : global, receiver)
- var o = {}
- assertEquals(42, Function.prototype.call.call(f, o, 20, 22))
- assertEquals(o, receiver)
- assertEquals(43, Function.prototype.call.call(f, null, 20, 23))
- assertEquals(isStrict ? null : global, receiver)
- assertEquals(44, Function.prototype.call.call(f, 2, 21, 23))
- assertEquals(2, receiver.valueOf())
- receiver = 333
- assertEquals(32, Function.prototype.apply.call(f, o, [17, 15]))
- assertEquals(o, receiver)
- var ff = Function.prototype.bind.call(f, o, 12)
- receiver = 333
- assertEquals(42, ff(30))
- assertEquals(o, receiver)
- receiver = 333
- assertEquals(32, Function.prototype.apply.call(ff, {}, [20]))
- assertEquals(o, receiver)
-
- Object.freeze(f)
- receiver = 333
- assertEquals(42, f(11, 31))
-// TODO(rossberg): unrelated bug: this does not succeed for optimized code.
-// assertEquals(isStrict ? undefined : global, receiver)
- receiver = 333
- assertEquals(42, Function.prototype.call.call(f, o, 20, 22))
- assertEquals(o, receiver)
- receiver = 333
- assertEquals(32, Function.prototype.apply.call(f, o, [17, 15]))
- assertEquals(o, receiver)
- receiver = 333
- assertEquals(42, ff(30))
- assertEquals(o, receiver)
- receiver = 333
- assertEquals(32, Function.prototype.apply.call(ff, {}, [20]))
- assertEquals(o, receiver)
-}
-
-TestCall(false, function(x, y) {
- receiver = this; return x + y
-})
-
-TestCall(true, function(x, y) {
- "use strict";
- receiver = this; return x + y
-})
-
-TestCall(false, Proxy.createFunction({}, function(x, y) {
- receiver = this; return x + y
-}))
-
-TestCall(true, Proxy.createFunction({}, function(x, y) {
- "use strict";
- receiver = this; return x + y
-}))
-
-var p = Proxy.createFunction({fix: function() {return {}}}, function(x, y) {
- receiver = this; return x + y
-})
-TestCall(false, p)
-Object.freeze(p)
-TestCall(false, p)
+// Constructor functions with proxy prototypes.
+function TestConstructorWithProxyPrototype() {
+ TestWithProxies(TestConstructorWithProxyPrototype2, {})
+}
-function TestCallThrow(callTrap) {
- var f = Proxy.createFunction({fix: function() {return {}}}, callTrap)
- assertThrows(function(){ f(11) }, "myexn")
- assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn")
- assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn")
+function TestConstructorWithProxyPrototype2(create, handler) {
+ function C() {};
+ C.prototype = create(handler);
- Object.freeze(f)
- assertThrows(function(){ f(11) }, "myexn")
- assertThrows(function(){ Function.prototype.call.call(f, {}, 2) }, "myexn")
- assertThrows(function(){ Function.prototype.apply.call(f, {}, [1]) }, "myexn")
+ var o = new C;
+ assertSame(C.prototype, o.__proto__);
+ assertSame(C.prototype, Object.getPrototypeOf(o));
}
-TestCallThrow(function() { throw "myexn" })
-TestCallThrow(Proxy.createFunction({}, function() { throw "myexn" }))
-
-var p = Proxy.createFunction(
- {fix: function() {return {}}}, function() { throw "myexn" })
-Object.freeze(p)
-TestCallThrow(p)
+TestConstructorWithProxyPrototype();
diff --git a/test/mjsunit/harmony/weakmaps.js b/test/mjsunit/harmony/weakmaps.js
deleted file mode 100644
index 7b5dcaf0..00000000
--- a/test/mjsunit/harmony/weakmaps.js
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --harmony-weakmaps --expose-gc
-
-
-// Test valid getter and setter calls
-var m = new WeakMap;
-assertDoesNotThrow(function () { m.get(new Object) });
-assertDoesNotThrow(function () { m.set(new Object) });
-assertDoesNotThrow(function () { m.has(new Object) });
-assertDoesNotThrow(function () { m.delete(new Object) });
-
-
-// Test invalid getter and setter calls
-var m = new WeakMap;
-assertThrows(function () { m.get(undefined) }, TypeError);
-assertThrows(function () { m.set(undefined, 0) }, TypeError);
-assertThrows(function () { m.get(0) }, TypeError);
-assertThrows(function () { m.set(0, 0) }, TypeError);
-assertThrows(function () { m.get('a-key') }, TypeError);
-assertThrows(function () { m.set('a-key', 0) }, TypeError);
-
-
-// Test expected mapping behavior
-var m = new WeakMap;
-function TestMapping(map, key, value) {
- map.set(key, value);
- assertSame(value, map.get(key));
-}
-TestMapping(m, new Object, 23);
-TestMapping(m, new Object, 'the-value');
-TestMapping(m, new Object, new Object);
-
-
-// Test expected querying behavior
-var m = new WeakMap;
-var key = new Object;
-TestMapping(m, key, 'to-be-present');
-assertTrue(m.has(key));
-assertFalse(m.has(new Object));
-TestMapping(m, key, undefined);
-assertFalse(m.has(key));
-assertFalse(m.has(new Object));
-
-
-// Test expected deletion behavior
-var m = new WeakMap;
-var key = new Object;
-TestMapping(m, key, 'to-be-deleted');
-assertTrue(m.delete(key));
-assertFalse(m.delete(key));
-assertFalse(m.delete(new Object));
-assertSame(m.get(key), undefined);
-
-
-// Test GC of map with entry
-var m = new WeakMap;
-var key = new Object;
-m.set(key, 'not-collected');
-gc();
-assertSame('not-collected', m.get(key));
-
-
-// Test GC of map with chained entries
-var m = new WeakMap;
-var head = new Object;
-for (key = head, i = 0; i < 10; i++, key = m.get(key)) {
- m.set(key, new Object);
-}
-gc();
-var count = 0;
-for (key = head; key != undefined; key = m.get(key)) {
- count++;
-}
-assertEquals(11, count);
-
-
-// Test property attribute [[Enumerable]]
-var m = new WeakMap;
-function props(x) {
- var array = [];
- for (var p in x) array.push(p);
- return array.sort();
-}
-assertArrayEquals([], props(WeakMap));
-assertArrayEquals([], props(WeakMap.prototype));
-assertArrayEquals([], props(m));
-
-
-// Test arbitrary properties on weak maps
-var m = new WeakMap;
-function TestProperty(map, property, value) {
- map[property] = value;
- assertEquals(value, map[property]);
-}
-for (i = 0; i < 20; i++) {
- TestProperty(m, i, 'val' + i);
- TestProperty(m, 'foo' + i, 'bar' + i);
-}
-TestMapping(m, new Object, 'foobar');
-
-
-// Test direct constructor call
-var m = WeakMap();
-assertTrue(m instanceof WeakMap);
-
-
-// Test some common JavaScript idioms
-var m = new WeakMap;
-assertTrue(m instanceof WeakMap);
-assertTrue(WeakMap.prototype.set instanceof Function)
-assertTrue(WeakMap.prototype.get instanceof Function)
-assertTrue(WeakMap.prototype.has instanceof Function)
-assertTrue(WeakMap.prototype.delete instanceof Function)
-
-
-// Regression test for WeakMap prototype.
-assertTrue(WeakMap.prototype.constructor === WeakMap)
-assertTrue(Object.getPrototypeOf(WeakMap.prototype) === Object.prototype)
-
-
-// Regression test for issue 1617: The prototype of the WeakMap constructor
-// needs to be unique (i.e. different from the one of the Object constructor).
-assertFalse(WeakMap.prototype === Object.prototype);
-var o = Object.create({});
-assertFalse("get" in o);
-assertFalse("set" in o);
-assertEquals(undefined, o.get);
-assertEquals(undefined, o.set);
-var o = Object.create({}, { myValue: {
- value: 10,
- enumerable: false,
- configurable: true,
- writable: true
-}});
-assertEquals(10, o.myValue);
-
-
-// Stress Test
-// There is a proposed stress-test available at the es-discuss mailing list
-// which cannot be reasonably automated. Check it out by hand if you like:
-// https://mail.mozilla.org/pipermail/es-discuss/2011-May/014096.html
diff --git a/test/mjsunit/math-min-max.js b/test/mjsunit/math-min-max.js
index 0833c5c8..e4fd3135 100644
--- a/test/mjsunit/math-min-max.js
+++ b/test/mjsunit/math-min-max.js
@@ -115,3 +115,75 @@ assertEquals(NaN, Math.max(1, 'oxen'));
assertEquals(Infinity, 1/Math.max(ZERO, -0));
assertEquals(Infinity, 1/Math.max(-0, ZERO));
+
+function run(crankshaft_test) {
+ crankshaft_test(1);
+ crankshaft_test(1);
+ %OptimizeFunctionOnNextCall(crankshaft_test);
+ crankshaft_test(-0);
+}
+
+function crankshaft_test_1(arg) {
+ var v1 = 1;
+ var v2 = 5;
+ var v3 = 1.5;
+ var v4 = 5.5;
+ var v5 = 2;
+ var v6 = 6;
+ var v7 = 0;
+ var v8 = -0;
+
+ var v9 = 9.9;
+ var v0 = 10.1;
+ // Integer32 representation.
+ assertEquals(v2, Math.max(v1++, v2++));
+ assertEquals(v1, Math.min(v1++, v2++));
+ // Tagged representation.
+ assertEquals(v4, Math.max(v3, v4));
+ assertEquals(v3, Math.min(v3, v4));
+ assertEquals(v6, Math.max(v5, v6));
+ assertEquals(v5, Math.min(v5, v6));
+ // Double representation.
+ assertEquals(v0, Math.max(v0++, v9++));
+ assertEquals(v9, Math.min(v0++, v9++));
+ // Mixed representation.
+ assertEquals(v1, Math.min(v1++, v9++)); // int32, double
+ assertEquals(v0, Math.max(v0++, v2++)); // double, int32
+ assertEquals(v1, Math.min(v1++, v6)); // int32, tagged
+ assertEquals(v2, Math.max(v5, v2++)); // tagged, int32
+ assertEquals(v6, Math.min(v6, v9++)); // tagged, double
+ assertEquals(v0, Math.max(v0++, v5)); // double, tagged
+
+ // Minus zero.
+ assertEquals(Infinity, 1/Math.max(v7, v8));
+ assertEquals(-Infinity, 1/Math.min(v7, v8));
+ // NaN.
+ assertEquals(NaN, Math.max(NaN, v8));
+ assertEquals(NaN, Math.min(NaN, v9));
+ assertEquals(NaN, Math.max(v8, NaN));
+ assertEquals(NaN, Math.min(v9, NaN));
+ // Minus zero as Integer32.
+ assertEquals((arg === -0) ? -Infinity : 1, 1/Math.min(arg, v2));
+}
+
+run(crankshaft_test_1);
+
+function crankshaft_test_2() {
+ var v9 = {};
+ v9.valueOf = function() { return 6; }
+ // Deopt expected due to non-heapnumber objects.
+ assertEquals(6, Math.min(v9, 12));
+}
+
+run(crankshaft_test_2);
+
+// Test overriding Math.min and Math.max
+Math.min = function(a, b) { return a + b; }
+Math.max = function(a, b) { return a - b; }
+
+function crankshaft_test_3() {
+ assertEquals(8, Math.min(3, 5));
+ assertEquals(3, Math.max(5, 2));
+}
+
+run(crankshaft_test_3);
diff --git a/test/mjsunit/math-pow.js b/test/mjsunit/math-pow.js
index 30d0cbdc..fb5f8a1f 100644
--- a/test/mjsunit/math-pow.js
+++ b/test/mjsunit/math-pow.js
@@ -25,118 +25,149 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
// Tests the special cases specified by ES 15.8.2.13
-// Simple sanity check
-assertEquals(4, Math.pow(2, 2));
-assertEquals(2147483648, Math.pow(2, 31));
-assertEquals(0.25, Math.pow(2, -2));
-assertEquals(0.0625, Math.pow(2, -4));
-assertEquals(1, Math.pow(1, 100));
-assertEquals(0, Math.pow(0, 1000));
-
-// Spec tests
-assertEquals(NaN, Math.pow(2, NaN));
-assertEquals(NaN, Math.pow(+0, NaN));
-assertEquals(NaN, Math.pow(-0, NaN));
-assertEquals(NaN, Math.pow(Infinity, NaN));
-assertEquals(NaN, Math.pow(-Infinity, NaN));
-
-assertEquals(1, Math.pow(NaN, +0));
-assertEquals(1, Math.pow(NaN, -0));
-
-assertEquals(NaN, Math.pow(NaN, NaN));
-assertEquals(NaN, Math.pow(NaN, 2.2));
-assertEquals(NaN, Math.pow(NaN, 1));
-assertEquals(NaN, Math.pow(NaN, -1));
-assertEquals(NaN, Math.pow(NaN, -2.2));
-assertEquals(NaN, Math.pow(NaN, Infinity));
-assertEquals(NaN, Math.pow(NaN, -Infinity));
-
-assertEquals(Infinity, Math.pow(1.1, Infinity));
-assertEquals(Infinity, Math.pow(-1.1, Infinity));
-assertEquals(Infinity, Math.pow(2, Infinity));
-assertEquals(Infinity, Math.pow(-2, Infinity));
-
-// Because +0 == -0, we need to compare 1/{+,-}0 to {+,-}Infinity
-assertEquals(+Infinity, 1/Math.pow(1.1, -Infinity));
-assertEquals(+Infinity, 1/Math.pow(-1.1, -Infinity));
-assertEquals(+Infinity, 1/Math.pow(2, -Infinity));
-assertEquals(+Infinity, 1/Math.pow(-2, -Infinity));
-
-assertEquals(NaN, Math.pow(1, Infinity));
-assertEquals(NaN, Math.pow(1, -Infinity));
-assertEquals(NaN, Math.pow(-1, Infinity));
-assertEquals(NaN, Math.pow(-1, -Infinity));
-
-assertEquals(+0, Math.pow(0.1, Infinity));
-assertEquals(+0, Math.pow(-0.1, Infinity));
-assertEquals(+0, Math.pow(0.999, Infinity));
-assertEquals(+0, Math.pow(-0.999, Infinity));
-
-assertEquals(Infinity, Math.pow(0.1, -Infinity));
-assertEquals(Infinity, Math.pow(-0.1, -Infinity));
-assertEquals(Infinity, Math.pow(0.999, -Infinity));
-assertEquals(Infinity, Math.pow(-0.999, -Infinity));
-
-assertEquals(Infinity, Math.pow(Infinity, 0.1));
-assertEquals(Infinity, Math.pow(Infinity, 2));
-
-assertEquals(+Infinity, 1/Math.pow(Infinity, -0.1));
-assertEquals(+Infinity, 1/Math.pow(Infinity, -2));
-
-assertEquals(-Infinity, Math.pow(-Infinity, 3));
-assertEquals(-Infinity, Math.pow(-Infinity, 13));
-
-assertEquals(Infinity, Math.pow(-Infinity, 3.1));
-assertEquals(Infinity, Math.pow(-Infinity, 2));
-
-assertEquals(-Infinity, 1/Math.pow(-Infinity, -3));
-assertEquals(-Infinity, 1/Math.pow(-Infinity, -13));
-
-assertEquals(+Infinity, 1/Math.pow(-Infinity, -3.1));
-assertEquals(+Infinity, 1/Math.pow(-Infinity, -2));
-
-assertEquals(+Infinity, 1/Math.pow(+0, 1.1));
-assertEquals(+Infinity, 1/Math.pow(+0, 2));
-
-assertEquals(Infinity, Math.pow(+0, -1.1));
-assertEquals(Infinity, Math.pow(+0, -2));
-
-assertEquals(-Infinity, 1/Math.pow(-0, 3));
-assertEquals(-Infinity, 1/Math.pow(-0, 13));
-
-assertEquals(+Infinity, 1/Math.pow(-0, 3.1));
-assertEquals(+Infinity, 1/Math.pow(-0, 2));
-
-assertEquals(-Infinity, Math.pow(-0, -3));
-assertEquals(-Infinity, Math.pow(-0, -13));
-
-assertEquals(Infinity, Math.pow(-0, -3.1));
-assertEquals(Infinity, Math.pow(-0, -2));
-
-assertEquals(NaN, Math.pow(-0.00001, 1.1));
-assertEquals(NaN, Math.pow(-0.00001, -1.1));
-assertEquals(NaN, Math.pow(-1.1, 1.1));
-assertEquals(NaN, Math.pow(-1.1, -1.1));
-assertEquals(NaN, Math.pow(-2, 1.1));
-assertEquals(NaN, Math.pow(-2, -1.1));
-assertEquals(NaN, Math.pow(-1000, 1.1));
-assertEquals(NaN, Math.pow(-1000, -1.1));
-
-assertEquals(+Infinity, 1/Math.pow(-0, 0.5));
-assertEquals(+Infinity, 1/Math.pow(-0, 0.6));
-assertEquals(-Infinity, 1/Math.pow(-0, 1));
-assertEquals(-Infinity, 1/Math.pow(-0, 10000000001));
-
-assertEquals(+Infinity, Math.pow(-0, -0.5));
-assertEquals(+Infinity, Math.pow(-0, -0.6));
-assertEquals(-Infinity, Math.pow(-0, -1));
-assertEquals(-Infinity, Math.pow(-0, -10000000001));
-
-
-
-// Tests from Sputnik S8.5_A13_T1.
-assertTrue((1*((Math.pow(2,53))-1)*(Math.pow(2,-1074))) === 4.4501477170144023e-308);
-assertTrue((1*(Math.pow(2,52))*(Math.pow(2,-1074))) === 2.2250738585072014e-308);
-assertTrue((-1*(Math.pow(2,52))*(Math.pow(2,-1074))) === -2.2250738585072014e-308);
+function test() {
+ // Simple sanity check
+ assertEquals(4, Math.pow(2, 2));
+ assertEquals(2147483648, Math.pow(2, 31));
+ assertEquals(0.25, Math.pow(2, -2));
+ assertEquals(0.0625, Math.pow(2, -4));
+ assertEquals(1, Math.pow(1, 100));
+ assertEquals(0, Math.pow(0, 1000));
+
+ // Spec tests
+ assertEquals(NaN, Math.pow(2, NaN));
+ assertEquals(NaN, Math.pow(+0, NaN));
+ assertEquals(NaN, Math.pow(-0, NaN));
+ assertEquals(NaN, Math.pow(Infinity, NaN));
+ assertEquals(NaN, Math.pow(-Infinity, NaN));
+
+ assertEquals(1, Math.pow(NaN, +0));
+ assertEquals(1, Math.pow(NaN, -0));
+
+ assertEquals(NaN, Math.pow(NaN, NaN));
+ assertEquals(NaN, Math.pow(NaN, 2.2));
+ assertEquals(NaN, Math.pow(NaN, 1));
+ assertEquals(NaN, Math.pow(NaN, -1));
+ assertEquals(NaN, Math.pow(NaN, -2.2));
+ assertEquals(NaN, Math.pow(NaN, Infinity));
+ assertEquals(NaN, Math.pow(NaN, -Infinity));
+
+ assertEquals(Infinity, Math.pow(1.1, Infinity));
+ assertEquals(Infinity, Math.pow(-1.1, Infinity));
+ assertEquals(Infinity, Math.pow(2, Infinity));
+ assertEquals(Infinity, Math.pow(-2, Infinity));
+
+ // Because +0 == -0, we need to compare 1/{+,-}0 to {+,-}Infinity
+ assertEquals(+Infinity, 1/Math.pow(1.1, -Infinity));
+ assertEquals(+Infinity, 1/Math.pow(-1.1, -Infinity));
+ assertEquals(+Infinity, 1/Math.pow(2, -Infinity));
+ assertEquals(+Infinity, 1/Math.pow(-2, -Infinity));
+
+ assertEquals(NaN, Math.pow(1, Infinity));
+ assertEquals(NaN, Math.pow(1, -Infinity));
+ assertEquals(NaN, Math.pow(-1, Infinity));
+ assertEquals(NaN, Math.pow(-1, -Infinity));
+
+ assertEquals(+0, Math.pow(0.1, Infinity));
+ assertEquals(+0, Math.pow(-0.1, Infinity));
+ assertEquals(+0, Math.pow(0.999, Infinity));
+ assertEquals(+0, Math.pow(-0.999, Infinity));
+
+ assertEquals(Infinity, Math.pow(0.1, -Infinity));
+ assertEquals(Infinity, Math.pow(-0.1, -Infinity));
+ assertEquals(Infinity, Math.pow(0.999, -Infinity));
+ assertEquals(Infinity, Math.pow(-0.999, -Infinity));
+
+ assertEquals(Infinity, Math.pow(Infinity, 0.1));
+ assertEquals(Infinity, Math.pow(Infinity, 2));
+
+ assertEquals(+Infinity, 1/Math.pow(Infinity, -0.1));
+ assertEquals(+Infinity, 1/Math.pow(Infinity, -2));
+
+ assertEquals(-Infinity, Math.pow(-Infinity, 3));
+ assertEquals(-Infinity, Math.pow(-Infinity, 13));
+
+ assertEquals(Infinity, Math.pow(-Infinity, 3.1));
+ assertEquals(Infinity, Math.pow(-Infinity, 2));
+
+ assertEquals(-Infinity, 1/Math.pow(-Infinity, -3));
+ assertEquals(-Infinity, 1/Math.pow(-Infinity, -13));
+
+ assertEquals(+Infinity, 1/Math.pow(-Infinity, -3.1));
+ assertEquals(+Infinity, 1/Math.pow(-Infinity, -2));
+
+ assertEquals(+Infinity, 1/Math.pow(+0, 1.1));
+ assertEquals(+Infinity, 1/Math.pow(+0, 2));
+
+ assertEquals(Infinity, Math.pow(+0, -1.1));
+ assertEquals(Infinity, Math.pow(+0, -2));
+
+ assertEquals(-Infinity, 1/Math.pow(-0, 3));
+ assertEquals(-Infinity, 1/Math.pow(-0, 13));
+
+ assertEquals(+Infinity, 1/Math.pow(-0, 3.1));
+ assertEquals(+Infinity, 1/Math.pow(-0, 2));
+
+ assertEquals(-Infinity, Math.pow(-0, -3));
+ assertEquals(-Infinity, Math.pow(-0, -13));
+
+ assertEquals(Infinity, Math.pow(-0, -3.1));
+ assertEquals(Infinity, Math.pow(-0, -2));
+
+ assertEquals(NaN, Math.pow(-0.00001, 1.1));
+ assertEquals(NaN, Math.pow(-0.00001, -1.1));
+ assertEquals(NaN, Math.pow(-1.1, 1.1));
+ assertEquals(NaN, Math.pow(-1.1, -1.1));
+ assertEquals(NaN, Math.pow(-2, 1.1));
+ assertEquals(NaN, Math.pow(-2, -1.1));
+ assertEquals(NaN, Math.pow(-1000, 1.1));
+ assertEquals(NaN, Math.pow(-1000, -1.1));
+
+ assertEquals(+Infinity, 1/Math.pow(-0, 0.5));
+ assertEquals(+Infinity, 1/Math.pow(-0, 0.6));
+ assertEquals(-Infinity, 1/Math.pow(-0, 1));
+ assertEquals(-Infinity, 1/Math.pow(-0, 10000000001));
+
+ assertEquals(+Infinity, Math.pow(-0, -0.5));
+ assertEquals(+Infinity, Math.pow(-0, -0.6));
+ assertEquals(-Infinity, Math.pow(-0, -1));
+ assertEquals(-Infinity, Math.pow(-0, -10000000001));
+
+ assertEquals(4, Math.pow(16, 0.5));
+ assertEquals(NaN, Math.pow(-16, 0.5));
+ assertEquals(0.25, Math.pow(16, -0.5));
+ assertEquals(NaN, Math.pow(-16, -0.5));
+
+ // Test detecting and converting integer value as double.
+ assertEquals(8, Math.pow(2, Math.sqrt(9)));
+
+ // Tests from Mozilla 15.8.2.13.
+ assertEquals(2, Math.pow.length);
+ assertEquals(NaN, Math.pow());
+ assertEquals(1, Math.pow(null, null));
+ assertEquals(NaN, Math.pow(void 0, void 0));
+ assertEquals(1, Math.pow(true, false));
+ assertEquals(0, Math.pow(false, true));
+ assertEquals(Infinity, Math.pow(-Infinity, Infinity));
+ assertEquals(0, Math.pow(-Infinity, -Infinity));
+ assertEquals(1, Math.pow(0, 0));
+ assertEquals(0, Math.pow(0, Infinity));
+ assertEquals(NaN, Math.pow(NaN, 0.5));
+ assertEquals(NaN, Math.pow(NaN, -0.5));
+
+ // Tests from Sputnik S8.5_A13_T1.
+ assertTrue(
+ (1*((Math.pow(2,53))-1)*(Math.pow(2,-1074))) === 4.4501477170144023e-308);
+ assertTrue(
+ (1*(Math.pow(2,52))*(Math.pow(2,-1074))) === 2.2250738585072014e-308);
+ assertTrue(
+ (-1*(Math.pow(2,52))*(Math.pow(2,-1074))) === -2.2250738585072014e-308);
+}
+
+test();
+test();
+%OptimizeFunctionOnNextCall(test);
+test(); \ No newline at end of file
diff --git a/test/mjsunit/mjsunit.js b/test/mjsunit/mjsunit.js
index faa5a438..033c78f4 100644
--- a/test/mjsunit/mjsunit.js
+++ b/test/mjsunit/mjsunit.js
@@ -221,9 +221,11 @@ var assertUnreachable;
assertSame = function assertSame(expected, found, name_opt) {
+ // TODO(mstarzinger): We should think about using Harmony's egal operator
+ // or the function equivalent Object.is() here.
if (found === expected) {
if (expected !== 0 || (1 / expected) == (1 / found)) return;
- } else if (isNaN(expected) && isNaN(found)) {
+ } else if ((expected !== expected) && (found !== found)) {
return;
}
fail(PrettyPrint(expected), found, name_opt);
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index bae09b4e..a1b92709 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -1,4 +1,4 @@
-# Copyright 2011 the V8 project authors. All rights reserved.
+# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
@@ -34,9 +34,10 @@ bugs: FAIL
# Fails.
regress/regress-1119: FAIL
-#############################################################################
-# Fails due to r10102 which reverts precise stepping on the 3.6 branch.
-debug-step-2: FAIL
+##############################################################################
+
+# NewGC: BUG(1719) slow to collect arrays over several contexts.
+regress/regress-524: SKIP
##############################################################################
# Too slow in debug mode with --stress-opt
@@ -46,16 +47,16 @@ regress/regress-create-exception: PASS, SKIP if $mode == debug
##############################################################################
# This one uses a built-in that's only present in debug mode. It takes
-# too long to run in debug mode on ARM.
-fuzz-natives: PASS, SKIP if ($mode == release || $arch == arm)
+# too long to run in debug mode on ARM and MIPS.
+fuzz-natives: PASS, SKIP if ($mode == release || $arch == arm || $arch == mips)
big-object-literal: PASS, SKIP if ($arch == arm)
# Issue 488: this test sometimes times out.
array-constructor: PASS || TIMEOUT
-# Very slow on ARM, contains no architecture dependent code.
-unicode-case-overoptimization: PASS, TIMEOUT if ($arch == arm)
+# Very slow on ARM and MIPS, contains no architecture dependent code.
+unicode-case-overoptimization: PASS, TIMEOUT if ($arch == arm || $arch == mips)
# Skip long running test in debug and allow it to timeout in release mode.
regress/regress-524: (PASS || TIMEOUT), SKIP if $mode == debug
@@ -64,6 +65,15 @@ regress/regress-524: (PASS || TIMEOUT), SKIP if $mode == debug
debug-liveedit-check-stack: SKIP
debug-liveedit-patch-positions-replace: SKIP
+# Test Crankshaft compilation time. Expected to take too long in debug mode.
+regress/regress-1969: PASS, SKIP if $mode == debug
+
+##############################################################################
+[ $isolates ]
+
+# This test sets the umask on a per-process basis and hence cannot be
+# used in multi-threaded runs.
+d8-os: SKIP
##############################################################################
[ $arch == arm ]
@@ -119,11 +129,23 @@ regress/regress-1132: SKIP
##############################################################################
[ $arch == mips ]
-# Run those tests, but expect them to time out.
-array-sort: PASS || TIMEOUT
+
+# Slow tests which times out in debug mode.
+try: PASS, SKIP if $mode == debug
+debug-scripts-request: PASS, SKIP if $mode == debug
+array-constructor: PASS, SKIP if $mode == debug
+
+# Times out often in release mode on MIPS.
+compiler/regress-stacktrace-methods: PASS, PASS || TIMEOUT if $mode == release
+array-splice: PASS || TIMEOUT
+
+# Long running test.
mirror-object: PASS || TIMEOUT
+string-indexof-2: PASS || TIMEOUT
-# Skip long-running tests.
+# BUG(3251035): Timeouts in long looping crankshaft optimization
+# tests. Skipping because having them timeout takes too long on the
+# buildbot.
compiler/alloc-number: SKIP
compiler/array-length: SKIP
compiler/assignment-deopt: SKIP
@@ -148,12 +170,8 @@ regress/regress-634: SKIP
regress/regress-create-exception: SKIP
regress/regress-3218915: SKIP
regress/regress-3247124: SKIP
-regress/regress-1132: SKIP
-regress/regress-1257: SKIP
-regress/regress-91008: SKIP
-##############################################################################
-[ $isolates ]
-# d8-os writes temporary files that might interfer with each other when running
-# in multible threads. Skip this if running with isolates testing.
-d8-os: SKIP
+# Requires bigger stack size in the Genesis and if stack size is increased,
+# the test requires too much time to run. However, the problem test covers
+# should be platform-independent.
+regress/regress-1132: SKIP
diff --git a/test/mjsunit/number-is.js b/test/mjsunit/number-is.js
new file mode 100644
index 00000000..1589fc64
--- /dev/null
+++ b/test/mjsunit/number-is.js
@@ -0,0 +1,58 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test Harmony Number.isFinite() and Number.isNaN() functions.
+
+assertTrue(Number.isFinite(0));
+assertTrue(Number.isFinite(Number.MIN_VALUE));
+assertTrue(Number.isFinite(Number.MAX_VALUE));
+assertFalse(Number.isFinite(Number.NaN));
+assertFalse(Number.isFinite(Number.POSITIVE_INFINITY));
+assertFalse(Number.isFinite(Number.NEGATIVE_INFINITY));
+assertFalse(Number.isFinite(new Number(0)));
+assertFalse(Number.isFinite(1/0));
+assertFalse(Number.isFinite(-1/0));
+assertFalse(Number.isFinite({}));
+assertFalse(Number.isFinite([]));
+assertFalse(Number.isFinite("s"));
+assertFalse(Number.isFinite(null));
+assertFalse(Number.isFinite(undefined));
+
+assertFalse(Number.isNaN(0));
+assertFalse(Number.isNaN(Number.MIN_VALUE));
+assertFalse(Number.isNaN(Number.MAX_VALUE));
+assertTrue(Number.isNaN(Number.NaN));
+assertFalse(Number.isNaN(Number.POSITIVE_INFINITY));
+assertFalse(Number.isNaN(Number.NEGATIVE_INFINITY));
+assertFalse(Number.isNaN(new Number(0)));
+assertFalse(Number.isNaN(1/0));
+assertFalse(Number.isNaN(-1/0));
+assertFalse(Number.isNaN({}));
+assertFalse(Number.isNaN([]));
+assertFalse(Number.isNaN("s"));
+assertFalse(Number.isNaN(null));
+assertFalse(Number.isNaN(undefined));
diff --git a/test/mjsunit/object-define-properties.js b/test/mjsunit/object-define-properties.js
index 128df694..6d5032e0 100644
--- a/test/mjsunit/object-define-properties.js
+++ b/test/mjsunit/object-define-properties.js
@@ -54,3 +54,19 @@ var x = Object.defineProperties(obj, desc);
assertEquals(x.foo, 10);
assertEquals(x.bar, 42);
+
+
+// Make sure that all property descriptors are calculated before any
+// modifications are done.
+
+var object = {};
+
+assertThrows(function() {
+ Object.defineProperties(object, {
+ foo: { value: 1 },
+ bar: { value: 2, get: function() { return 3; } }
+ });
+ }, TypeError);
+
+assertEquals(undefined, object.foo);
+assertEquals(undefined, object.bar);
diff --git a/test/mjsunit/object-define-property.js b/test/mjsunit/object-define-property.js
index ee6083a8..fdaf82d1 100644
--- a/test/mjsunit/object-define-property.js
+++ b/test/mjsunit/object-define-property.js
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -503,7 +503,7 @@ try {
// Defining properties null should fail even when we have
// other allowed values
try {
- %DefineOrRedefineAccessorProperty(null, 'foo', 0, func, 0);
+ %DefineOrRedefineAccessorProperty(null, 'foo', func, null, 0);
} catch (e) {
assertTrue(/illegal access/.test(e));
}
@@ -1053,4 +1053,35 @@ for (var i = 0; i < 1000; i++) {
// Non-enumerable property forces dictionary mode.
Object.defineProperty(o, i, {value: i, enumerable: false});
}
-assertEquals(999, o[999]); \ No newline at end of file
+assertEquals(999, o[999]);
+
+
+// Regression test: Bizzare behavior on non-strict arguments object.
+(function test(arg0) {
+ // Here arguments[0] is a fast alias on arg0.
+ Object.defineProperty(arguments, "0", {
+ value:1,
+ enumerable:false
+ });
+ // Here arguments[0] is a slow alias on arg0.
+ Object.defineProperty(arguments, "0", {
+ value:2,
+ writable:false
+ });
+ // Here arguments[0] is no alias at all.
+ Object.defineProperty(arguments, "0", {
+ value:3
+ });
+ assertEquals(2, arg0);
+ assertEquals(3, arguments[0]);
+})(0);
+
+
+// Regression test: We should never observe the hole value.
+var objectWithGetter = {};
+objectWithGetter.__defineGetter__('foo', function() {});
+assertEquals(undefined, objectWithGetter.__lookupSetter__('foo'));
+
+var objectWithSetter = {};
+objectWithSetter.__defineSetter__('foo', function(x) {});
+assertEquals(undefined, objectWithSetter.__lookupGetter__('foo'));
diff --git a/test/mjsunit/object-is.js b/test/mjsunit/object-is.js
new file mode 100644
index 00000000..b9fdc844
--- /dev/null
+++ b/test/mjsunit/object-is.js
@@ -0,0 +1,47 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test both the Harmony egal operator and it's function equivalent.
+
+function TestEgal(expected, x, y) {
+ // TODO(mstarzinger): Once we have the egal operator, we can test it here.
+ assertSame(expected, Object.is(x, y));
+}
+
+var test_set = [ {}, [], 1/0, -1/0, "s", 0, 0/-1, null, undefined ];
+print(test_set);
+for (var i = 0; i < test_set.length; i++) {
+ for (var j = 0; j < test_set.length; j++) {
+ if (i == j) {
+ assertSame(test_set[i], test_set[j]);
+ TestEgal(true, test_set[i], test_set[j]);
+ } else {
+ TestEgal(false, test_set[i], test_set[j]);
+ TestEgal(false, test_set[j], test_set[i]);
+ }
+ }
+}
diff --git a/test/mjsunit/object-prevent-extensions.js b/test/mjsunit/object-prevent-extensions.js
index 322a2cb5..6b9184d8 100644
--- a/test/mjsunit/object-prevent-extensions.js
+++ b/test/mjsunit/object-prevent-extensions.js
@@ -114,3 +114,15 @@ Object.preventExtensions(foo);
foo.x = 29;
assertEquals(undefined, foo.x);
+
+// when Object.isExtensible(o) === false
+// assignment should return right hand side value
+var o = Object.preventExtensions({});
+var v = o.v = 50;
+assertEquals(undefined, o.v);
+assertEquals(50, v);
+
+// test same behavior as above, but for integer properties
+var n = o[0] = 100;
+assertEquals(undefined, o[0]);
+assertEquals(100, n);
diff --git a/test/mjsunit/optimized-typeof.js b/test/mjsunit/optimized-typeof.js
new file mode 100644
index 00000000..b0c0725c
--- /dev/null
+++ b/test/mjsunit/optimized-typeof.js
@@ -0,0 +1,47 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function typeofDirectly() {
+ return typeof({}) === "undefined";
+}
+
+typeofDirectly();
+typeofDirectly();
+%OptimizeFunctionOnNextCall(typeofDirectly);
+typeofDirectly();
+
+function typeofViaVariable() {
+ var foo = typeof({})
+ return foo === "undefined";
+}
+
+typeofViaVariable();
+typeofViaVariable();
+%OptimizeFunctionOnNextCall(typeofViaVariable);
+typeofViaVariable();
diff --git a/test/mjsunit/pixel-array-rounding.js b/test/mjsunit/pixel-array-rounding.js
new file mode 100644
index 00000000..ef5a10bd
--- /dev/null
+++ b/test/mjsunit/pixel-array-rounding.js
@@ -0,0 +1,44 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+var pixels = new PixelArray(8);
+
+function f() {
+ for (var i = 0; i < 8; i++) {
+ pixels[i] = (i * 1.1);
+ }
+ return pixels[1] + pixels[6];
+}
+
+f();
+f();
+assertEquals(6, pixels[5]);
+%OptimizeFunctionOnNextCall(f);
+f();
+assertEquals(6, pixels[5]);
diff --git a/test/mjsunit/regexp-capture-3.js b/test/mjsunit/regexp-capture-3.js
new file mode 100644
index 00000000..50e423ff
--- /dev/null
+++ b/test/mjsunit/regexp-capture-3.js
@@ -0,0 +1,30 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"abcd".replace(/b/g, function() { });
+
+assertEquals("cd", RegExp.rightContext);
diff --git a/test/mjsunit/regexp-static.js b/test/mjsunit/regexp-static.js
index 0f849687..8f283f6c 100644
--- a/test/mjsunit/regexp-static.js
+++ b/test/mjsunit/regexp-static.js
@@ -25,18 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Test that we throw exceptions when calling test and exec with no
-// input. This is not part of the spec, but we do it for
-// compatibility with JSC.
-assertThrows("/a/.test()");
-assertThrows("/a/.exec()");
-
-// Test that we do not throw exceptions once the static RegExp.input
-// field has been set.
-RegExp.input = "a";
-assertDoesNotThrow("/a/.test()");
-assertDoesNotThrow("/a/.exec()");
-
// Test the (deprecated as of JS 1.5) properties of the RegExp function.
var re = /((\d+)\.(\d+))/;
var s = 'abc123.456def';
@@ -166,3 +154,8 @@ assertTrue(typeof RegExp.input == typeof String(), "RegExp.input coerces values
var foo = "lsdfj sldkfj sdklfj læsdfjl sdkfjlsdk fjsdl fjsdljskdj flsj flsdkj flskd regexp: /foobar/\nldkfj sdlkfj sdkl";
assertTrue(/^([a-z]+): (.*)/.test(foo.substring(foo.indexOf("regexp:"))), "regexp: setup");
assertEquals("regexp", RegExp.$1, "RegExp.$1");
+
+
+// Check that calling with no argument is the same as calling with undefined.
+assertTrue(/^undefined$/.test());
+assertEquals(["undefined"], /^undefined$/.exec());
diff --git a/test/mjsunit/regexp.js b/test/mjsunit/regexp.js
index 3c4f883b..ec82c96e 100644
--- a/test/mjsunit/regexp.js
+++ b/test/mjsunit/regexp.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -127,6 +127,17 @@ assertTrue(re.test("$"));
assertTrue(/^[Z-\c-e]*$/.test("Z[\\cde"));
+// Test that we handle \s and \S correctly on special Unicode characters.
+re = /\s/;
+assertTrue(re.test("\u2028"));
+assertTrue(re.test("\u2029"));
+assertTrue(re.test("\uFEFF"));
+
+re = /\S/;
+assertFalse(re.test("\u2028"));
+assertFalse(re.test("\u2029"));
+assertFalse(re.test("\uFEFF"));
+
// Test that we handle \s and \S correctly inside some bizarre
// character classes.
re = /[\s-:]/;
@@ -690,3 +701,7 @@ assertThrows("RegExp('(*)')");
assertThrows("RegExp('(?:*)')");
assertThrows("RegExp('(?=*)')");
assertThrows("RegExp('(?!*)')");
+
+// Test trimmed regular expression for RegExp.test().
+assertTrue(/.*abc/.test("abc"));
+assertFalse(/.*\d+/.test("q"));
diff --git a/test/mjsunit/regress/regress-100702.js b/test/mjsunit/regress/regress-100702.js
new file mode 100644
index 00000000..46494ab7
--- /dev/null
+++ b/test/mjsunit/regress/regress-100702.js
@@ -0,0 +1,44 @@
+// 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.
+
+// Regression test for correct handling of non-object receiver values
+// passed to built-in array functions.
+
+String.prototype.isThatMe = function () {
+ assertFalse(this === str);
+};
+
+var str = "abc";
+str.isThatMe();
+str.isThatMe.call(str);
+
+var arr = [1];
+arr.forEach("".isThatMe, str);
+arr.filter("".isThatMe, str);
+arr.some("".isThatMe, str);
+arr.every("".isThatMe, str);
+arr.map("".isThatMe, str);
diff --git a/test/mjsunit/regress/regress-102153.js b/test/mjsunit/regress/regress-102153.js
new file mode 100644
index 00000000..0f67656b
--- /dev/null
+++ b/test/mjsunit/regress/regress-102153.js
@@ -0,0 +1,57 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+
+// Test that the break point is set before initializing the loop variable
+// so that we break before any iteration has been run.
+
+Debug = debug.Debug;
+
+var break_hit = false;
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ break_hit = true;
+ }
+}
+
+Debug.setListener(listener);
+
+function test() {
+ for (var i = 0; i < 3; i++) { // Break here.
+ if (i == 0) break;
+ }
+}
+
+Debug.setBreakPoint(test, 1, 0);
+
+assertTrue(Debug.showBreakPoints(test).indexOf("// Break here.") >= 0);
+
+test();
+
+assertTrue(break_hit);
diff --git a/test/mjsunit/regress/regress-108296.js b/test/mjsunit/regress/regress-108296.js
new file mode 100644
index 00000000..38ecda77
--- /dev/null
+++ b/test/mjsunit/regress/regress-108296.js
@@ -0,0 +1,52 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+// This test checks that young immediates embedded into code objects
+// are referenced through a cell.
+
+function f (k, a, b) {
+ // Create control flow for a.foo. Control flow resolution will
+ // be generated as a part of a gap move. Gap move operate on immediates as
+ // a.foo is a CONSTANT_FUNCTION.
+ var x = k ? a.foo : a.foo;
+ return x.prototype;
+}
+
+var a = { };
+
+// Make sure that foo is a CONSTANT_FUNCTION but not be pretenured.
+a.foo = (function () { return function () {}; })();
+
+// Ensure that both branches of ternary operator have monomorphic type feedback.
+f(true, a, a);
+f(true, a, a);
+f(false, a, a);
+f(false, a, a);
+%OptimizeFunctionOnNextCall(f);
+f(true, a, a);
diff --git a/test/mjsunit/regress/regress-109195.js b/test/mjsunit/regress/regress-109195.js
new file mode 100644
index 00000000..97538aa1
--- /dev/null
+++ b/test/mjsunit/regress/regress-109195.js
@@ -0,0 +1,65 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+var Debug = debug.Debug;
+
+function listener(event, exec_state, event_data, data) {
+ for (var i = 0, n = exec_state.frameCount(); i < n; i++) {
+ exec_state.frame().scopeCount(i);
+ }
+ exec_state.prepareStep(Debug.StepAction.Continue, 1);
+}
+
+Debug.setListener(listener);
+
+var F = function () {
+ 1, function () {
+ var d = 0;
+ (function () { d; });
+ debugger;
+ }();
+};
+
+var src = "(" + F.toString() + ")()";
+eval(src);
+
+Function.prototype.__defineGetter__("f", function () {
+ debugger;
+ return 0;
+});
+
+var G = function () {
+ 1, function () {
+ var d = 0;
+ (function () { d; });
+ debugger;
+ }['f'];
+};
+
+var src = "(" + G.toString() + ")()";
+eval(src);
diff --git a/test/mjsunit/regress/regress-110509.js b/test/mjsunit/regress/regress-110509.js
new file mode 100644
index 00000000..132bd233
--- /dev/null
+++ b/test/mjsunit/regress/regress-110509.js
@@ -0,0 +1,41 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+// Verify that LRandom preserves rsi correctly.
+
+function foo() {
+ Math.random();
+ new Function("");
+}
+
+foo();
+foo();
+foo();
+%OptimizeFunctionOnNextCall(foo);
+foo();
diff --git a/test/mjsunit/regress/regress-1110.js b/test/mjsunit/regress/regress-1110.js
index 43b8d77a..124f520c 100644
--- a/test/mjsunit/regress/regress-1110.js
+++ b/test/mjsunit/regress/regress-1110.js
@@ -28,10 +28,9 @@
// Test that the illegal continue is thrown at parse time.
try {
- function Crash() { continue;if (Crash) {
- } }
+ eval("function Crash() { assertUnreachable(); continue;if (Crash) { } }");
Crash();
- assertTrue(false);
+ assertUnreachable();
} catch (e) {
assertTrue(e instanceof SyntaxError);
assertTrue(/continue/.test(e.message));
diff --git a/test/mjsunit/regress/regress-113924.js b/test/mjsunit/regress/regress-113924.js
new file mode 100644
index 00000000..3ecdec48
--- /dev/null
+++ b/test/mjsunit/regress/regress-113924.js
@@ -0,0 +1,31 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+var count=12000;
+while(count--) {
+ eval("var a = new Object(10); a[2] += 7;");
+}
diff --git a/test/mjsunit/regress/regress-115452.js b/test/mjsunit/regress/regress-115452.js
new file mode 100644
index 00000000..7e424ed8
--- /dev/null
+++ b/test/mjsunit/regress/regress-115452.js
@@ -0,0 +1,48 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test that a function declaration cannot overwrite a read-only property.
+
+print(0)
+function foobl() {}
+assertTrue(typeof this.foobl == "function");
+assertTrue(Object.getOwnPropertyDescriptor(this, "foobl").writable);
+
+print(1)
+Object.defineProperty(this, "foobl", {value: 1, writable: false});
+assertSame(1, this.foobl);
+assertFalse(Object.getOwnPropertyDescriptor(this, "foobl").writable);
+
+print(2)
+eval("function foobl() {}");
+assertSame(1, this.foobl);
+assertFalse(Object.getOwnPropertyDescriptor(this, "foobl").writable);
+
+print(3)
+eval("function foobl() {}");
+assertSame(1, this.foobl);
+assertFalse(Object.getOwnPropertyDescriptor(this, "foobl").writable);
diff --git a/test/mjsunit/regress/regress-1170.js b/test/mjsunit/regress/regress-1170.js
index 95684c54..66ed9f29 100644
--- a/test/mjsunit/regress/regress-1170.js
+++ b/test/mjsunit/regress/regress-1170.js
@@ -49,7 +49,7 @@ try {
exception = true;
assertTrue(/TypeError/.test(e));
}
-assertTrue(exception);
+assertFalse(exception);
exception = false;
try {
diff --git a/test/mjsunit/regress/regress-117794.js b/test/mjsunit/regress/regress-117794.js
new file mode 100644
index 00000000..5e11b400
--- /dev/null
+++ b/test/mjsunit/regress/regress-117794.js
@@ -0,0 +1,57 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Loads specialized to be from the global object should not omit the
+// smi check on the receiver. The code below should not crash.
+
+print = function() {}
+
+function constructor() {};
+
+function assertHasOwnProperties(object, limit) {
+ for (var i = 0; i < limit; i++) { }
+}
+
+try {
+ Object.keys();
+} catch(exc2) {
+ print(exc2.stack);
+}
+
+var x1 = new Object();
+
+try {
+ new Function("A Man Called Horse", x1.d);
+} catch(exc3) {
+ print(exc3.stack);
+}
+
+try {
+ (-(true)).toPrecision(0x30, 'lib1-f1');
+} catch(exc1) {
+ print(exc1.stack);
+}
diff --git a/test/mjsunit/regress/regress-119429.js b/test/mjsunit/regress/regress-119429.js
new file mode 100644
index 00000000..a8764875
--- /dev/null
+++ b/test/mjsunit/regress/regress-119429.js
@@ -0,0 +1,37 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+var d = 0;
+function recurse() {
+ if (++d == 25135) { // A magic number just below stack overflow on ia32
+ %DebugBreak();
+ }
+ recurse();
+}
+assertThrows(function() { recurse();} );
diff --git a/test/mjsunit/regress/regress-119925.js b/test/mjsunit/regress/regress-119925.js
new file mode 100644
index 00000000..67127548
--- /dev/null
+++ b/test/mjsunit/regress/regress-119925.js
@@ -0,0 +1,34 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test that the throw is not inlined if object literals cannot be
+// inlined.
+Array.prototype.__proto__ = { 77e4 : null };
+function continueWithinLoop() {
+ for (var key in [(1.2)]) { }
+};
+continueWithinLoop();
diff --git a/test/mjsunit/regress/regress-1213575.js b/test/mjsunit/regress/regress-1213575.js
index 9d82064e..f3a11dba 100644
--- a/test/mjsunit/regress/regress-1213575.js
+++ b/test/mjsunit/regress/regress-1213575.js
@@ -25,17 +25,16 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Make sure that a const definition always
-// conflicts with a defined setter. This avoid
-// trying to pass 'the hole' to the setter.
+// Make sure that a const definition does not try
+// to pass 'the hole' to a defined setter.
-this.__defineSetter__('x', function(value) { assertTrue(false); });
+this.__defineSetter__('x', function(value) { assertTrue(value === 1); });
var caught = false;
try {
- eval('const x');
+ eval('const x = 1');
} catch(e) {
assertTrue(e instanceof TypeError);
caught = true;
}
-assertTrue(caught);
+assertFalse(caught);
diff --git a/test/mjsunit/regress/regress-121407.js b/test/mjsunit/regress/regress-121407.js
new file mode 100644
index 00000000..25033fb5
--- /dev/null
+++ b/test/mjsunit/regress/regress-121407.js
@@ -0,0 +1,40 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+var a = [0,1,2,3];
+a[2000000] = 2000000;
+a.length=2000;
+for (var i = 0; i <= 256; i++) {
+ a[i] = new Object();
+}
+
+a = [0.5,1.5,2.5,3.5,4.5,5.5];
+a[2000000] = 2000000;
+a.length=2000;
+for (var i = 0; i <= 256; i++) {
+ a[i] = new Object();
+} \ No newline at end of file
diff --git a/test/mjsunit/regress/regress-1217.js b/test/mjsunit/regress/regress-1217.js
new file mode 100644
index 00000000..65305498
--- /dev/null
+++ b/test/mjsunit/regress/regress-1217.js
@@ -0,0 +1,50 @@
+// 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.
+
+// Check that RegExp.prototype is itself a RegExp object.
+
+var proto = RegExp.prototype;
+assertEquals("[object RegExp]", Object.prototype.toString.call(proto));
+
+assertEquals("", proto.source);
+assertEquals(false, proto.global);
+assertEquals(false, proto.multiline);
+assertEquals(false, proto.ignoreCase);
+assertEquals(0, proto.lastIndex);
+
+assertEquals("/(?:)/", proto.toString());
+
+var execResult = proto.exec("argle");
+assertEquals(1, execResult.length);
+assertEquals("", execResult[0]);
+assertEquals("argle", execResult.input);
+assertEquals(0, execResult.index);
+
+assertTrue(proto.test("argle"));
+
+// We disallow re-compiling the RegExp.prototype object.
+assertThrows(function(){ proto.compile("something"); }, TypeError);
diff --git a/test/mjsunit/regress/regress-1229.js b/test/mjsunit/regress/regress-1229.js
index e16d278b..5447f3f7 100644
--- a/test/mjsunit/regress/regress-1229.js
+++ b/test/mjsunit/regress/regress-1229.js
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -29,59 +29,118 @@
// Check that %NewObjectFromBound works correctly when called from optimized
// frame.
-function foo(x, y, z) {
+function foo1(x, y, z) {
assertEquals(1, x);
assertEquals(2, y);
assertEquals(3, z);
}
-var bound_arg = [1];
+function foo2(x, y, z) {
+ assertEquals(1, x);
+ assertEquals(2, y);
+ assertEquals(undefined, z);
+}
+
+function foo3(x, y, z) {
+ assertEquals(1, x);
+ assertEquals(2, y);
+ assertEquals(3, z);
+}
-function f(y, z) {
- return %NewObjectFromBound(foo, bound_arg);
+
+var foob1 = foo1.bind({}, 1);
+var foob2 = foo2.bind({}, 1);
+var foob3 = foo3.bind({}, 1);
+
+
+function f1(y, z) {
+ return %NewObjectFromBound(foob1);
+}
+
+function f2(y, z) {
+ return %NewObjectFromBound(foob2);
+}
+
+function f3(y, z) {
+ return %NewObjectFromBound(foob3);
}
// Check that %NewObjectFromBound looks at correct frame for inlined function.
-function g(z, y) {
- return f(y, z); /* f should be inlined into g, note rotated arguments */
+function g1(z, y) {
+ return f1(y, z); /* f should be inlined into g, note rotated arguments */
+}
+
+function g2(z, y, x) {
+ return f2(y); /* f should be inlined into g, note argument count mismatch */
+}
+
+function g3(z, y, x) {
+ return f3(x, y, z); /* f should be inlined into g, note argument count mismatch */
}
// Check that %NewObjectFromBound looks at correct frame for inlined function.
function ff(x) { }
-function h(z2, y2) {
+function h1(z2, y2) {
+ var local_z = z2 >> 1;
+ ff(local_z);
+ var local_y = y2 >> 1;
+ ff(local_y);
+ return f1(local_y, local_z); /* f should be inlined into h */
+}
+
+function h2(z2, y2, x2) {
+ var local_z = z2 >> 1;
+ ff(local_z);
+ var local_y = y2 >> 1;
+ ff(local_y);
+ return f2(local_y); /* f should be inlined into h */
+}
+
+function h3(z2, y2, x2) {
var local_z = z2 >> 1;
ff(local_z);
var local_y = y2 >> 1;
ff(local_y);
- return f(local_y, local_z); /* f should be inlined into h */
+ var local_x = x2 >> 1;
+ ff(local_x);
+ return f3(local_x, local_y, local_z); /* f should be inlined into h */
}
-for (var i = 0; i < 5; i++) f(2, 3);
-%OptimizeFunctionOnNextCall(f);
-f(2, 3);
-for (var i = 0; i < 5; i++) g(3, 2);
-%OptimizeFunctionOnNextCall(g);
-g(3, 2);
+function invoke(f, args) {
+ for (var i = 0; i < 5; i++) f.apply(this, args);
+ %OptimizeFunctionOnNextCall(f);
+ f.apply(this, args);
+}
-for (var i = 0; i < 5; i++) h(6, 4);
-%OptimizeFunctionOnNextCall(h);
-h(6, 4);
+invoke(f1, [2, 3]);
+invoke(f2, [2]);
+invoke(f3, [2, 3, 4]);
+invoke(g1, [3, 2]);
+invoke(g2, [3, 2, 4]);
+invoke(g3, [4, 3, 2]);
+invoke(h1, [6, 4]);
+invoke(h2, [6, 4, 8]);
+invoke(h3, [8, 6, 4]);
// Check that %_IsConstructCall returns correct value when inlined
var NON_CONSTRUCT_MARKER = {};
var CONSTRUCT_MARKER = {};
-function baz() {
+function baz(x) {
return (!%_IsConstructCall()) ? NON_CONSTRUCT_MARKER : CONSTRUCT_MARKER;
}
function bar(x, y, z) {
+ var non_construct = baz(0); /* baz should be inlined */
+ assertSame(non_construct, NON_CONSTRUCT_MARKER);
var non_construct = baz(); /* baz should be inlined */
- assertEquals(non_construct, NON_CONSTRUCT_MARKER);
- var construct = new baz();
- assertEquals(construct, CONSTRUCT_MARKER);
+ assertSame(non_construct, NON_CONSTRUCT_MARKER);
+ var non_construct = baz(0, 0); /* baz should be inlined */
+ assertSame(non_construct, NON_CONSTRUCT_MARKER);
+ var construct = new baz(0);
+ assertSame(construct, CONSTRUCT_MARKER);
+ var construct = new baz(0, 0);
+ assertSame(construct, CONSTRUCT_MARKER);
}
-for (var i = 0; i < 5; i++) new bar(1, 2, 3);
-%OptimizeFunctionOnNextCall(bar);
-bar(1, 2, 3);
+invoke(bar, [1, 2, 3]);
diff --git a/test/mjsunit/regress/regress-1415.js b/test/mjsunit/regress/regress-1415.js
new file mode 100644
index 00000000..f993e9b3
--- /dev/null
+++ b/test/mjsunit/regress/regress-1415.js
@@ -0,0 +1,42 @@
+// 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.
+
+// Surrogate pair range.
+// U+D800
+assertThrows(function(){ decodeURIComponent("%ED%A0%80"); }, URIError);
+// U+DBFF
+assertThrows(function(){ decodeURIComponent("%ED%AF%BF"); }, URIError);
+// U+DC00
+assertThrows(function(){ decodeURIComponent("%ED%B0%80"); }, URIError);
+// U+DFFF
+assertThrows(function(){ decodeURIComponent("%ED%BF%BF"); }, URIError);
+
+// Overlong encodings
+// U+007F in two bytes.
+assertThrows(function(){ decodeURIComponent("%C1%BF"); }, URIError);
+// U+07FF in three bytes.
+assertThrows(function(){ decodeURIComponent("%E0%9F%BF"); }, URIError);
diff --git a/test/mjsunit/regress/regress-1530.js b/test/mjsunit/regress/regress-1530.js
new file mode 100644
index 00000000..db211445
--- /dev/null
+++ b/test/mjsunit/regress/regress-1530.js
@@ -0,0 +1,69 @@
+// 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.
+
+// Test that redefining the 'prototype' property of a function object
+// does actually set the internal value and does not screw up any
+// shadowing between said property and the internal value.
+
+var f = function() {};
+
+// Verify that normal assignment of 'prototype' property works properly
+// and updates the internal value.
+var x = { foo: 'bar' };
+f.prototype = x;
+assertSame(f.prototype, x);
+assertSame(f.prototype.foo, 'bar');
+assertSame(new f().foo, 'bar');
+assertSame(Object.getPrototypeOf(new f()), x);
+assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, x);
+
+// Verify that 'prototype' behaves like a data property when it comes to
+// redefining with Object.defineProperty() and the internal value gets
+// updated.
+var y = { foo: 'baz' };
+Object.defineProperty(f, 'prototype', { value: y, writable: true });
+assertSame(f.prototype, y);
+assertSame(f.prototype.foo, 'baz');
+assertSame(new f().foo, 'baz');
+assertSame(Object.getPrototypeOf(new f()), y);
+assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, y);
+
+// Verify that the previous redefinition didn't screw up callbacks and
+// the internal value still gets updated.
+var z = { foo: 'other' };
+f.prototype = z;
+assertSame(f.prototype, z);
+assertSame(f.prototype.foo, 'other');
+assertSame(new f().foo, 'other');
+assertSame(Object.getPrototypeOf(new f()), z);
+assertSame(Object.getOwnPropertyDescriptor(f, 'prototype').value, z);
+
+// Verify that non-writability of other properties is respected.
+assertThrows("Object.defineProperty(f, 'name', { value: {} })");
+assertThrows("Object.defineProperty(f, 'length', { value: {} })");
+assertThrows("Object.defineProperty(f, 'caller', { value: {} })");
+assertThrows("Object.defineProperty(f, 'arguments', { value: {} })");
diff --git a/test/mjsunit/regress/regress-1624-strict.js b/test/mjsunit/regress/regress-1624-strict.js
new file mode 100644
index 00000000..8bc58d5a
--- /dev/null
+++ b/test/mjsunit/regress/regress-1624-strict.js
@@ -0,0 +1,140 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test that global eval calls of strict code (independent from whether being
+// direct or indirect) have their own lexical and variable environment.
+
+"use strict";
+var evil = eval;
+
+// Test global direct strict eval in strict script.
+// Expects new environment.
+var no_touch = 0;
+eval('"use strict"; var no_touch = 1;');
+assertSame(0, no_touch);
+
+// Test global indirect strict eval in strict script.
+// Expects new environment.
+var no_touch = 0;
+evil('"use strict"; var no_touch = 2;');
+assertSame(0, no_touch);
+
+// Test global direct non-strict eval in strict script.
+// Expects new environment.
+var no_touch = 0;
+eval('var no_touch = 3;');
+assertSame(0, no_touch);
+
+// Test global indirect non-strict eval in strict script.
+// Expects global environment.
+var no_touch = 0;
+evil('var no_touch = 4;');
+assertSame(4, no_touch);
+
+// Test non-global direct strict eval in strict script.
+// Expects new environment.
+var no_touch = 0;
+(function() {
+ var no_touch = 0;
+ eval('"use strict"; var no_touch = 5;');
+ assertSame(0, no_touch);
+})()
+assertSame(0, no_touch);
+
+// Test non-global indirect strict eval in strict script.
+// Expects new environment.
+var no_touch = 0;
+(function() {
+ var no_touch = 0;
+ evil('"use strict"; var no_touch = 6;');
+ assertSame(0, no_touch);
+})()
+assertSame(0, no_touch);
+
+// Test non-global direct non-strict eval in strict script.
+// Expects new environment.
+var no_touch = 0;
+(function() {
+ var no_touch = 0;
+ eval('var no_touch = 7;');
+ assertSame(0, no_touch);
+})()
+assertSame(0, no_touch);
+
+// Test non-global indirect non-strict eval in strict script.
+// Expects global environment.
+var no_touch = 0;
+(function() {
+ var no_touch = 0;
+ evil('var no_touch = 8;');
+ assertSame(0, no_touch);
+})()
+assertSame(8, no_touch);
+
+// Test non-global direct strict eval in strict script.
+// Expects new environment.
+var no_touch = 0;
+(function() {
+ "use strict";
+ var no_touch = 0;
+ eval('"use strict"; var no_touch = 9;');
+ assertSame(0, no_touch);
+})()
+assertSame(0, no_touch);
+
+// Test non-global indirect strict eval in strict script.
+// Expects new environment.
+var no_touch = 0;
+(function() {
+ "use strict";
+ var no_touch = 0;
+ evil('"use strict"; var no_touch = 10;');
+ assertSame(0, no_touch);
+})()
+assertSame(0, no_touch);
+
+// Test non-global direct non-strict eval in strict script.
+// Expects new environment.
+var no_touch = 0;
+(function() {
+ "use strict";
+ var no_touch = 0;
+ eval('var no_touch = 11;');
+ assertSame(0, no_touch);
+})()
+assertSame(0, no_touch);
+
+// Test non-global indirect non-strict eval in strict script.
+// Expects global environment.
+var no_touch = 0;
+(function() {
+ "use strict";
+ var no_touch = 0;
+ evil('var no_touch = 12;');
+ assertSame(0, no_touch);
+})()
+assertSame(12, no_touch);
diff --git a/test/mjsunit/regress/regress-1624.js b/test/mjsunit/regress/regress-1624.js
new file mode 100644
index 00000000..987e036d
--- /dev/null
+++ b/test/mjsunit/regress/regress-1624.js
@@ -0,0 +1,139 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test that global eval calls of strict code (independent from whether being
+// direct or indirect) have their own lexical and variable environment.
+
+var evil = eval;
+
+// Test global direct strict eval.
+// Expects new environment.
+var no_touch = 0;
+eval('"use strict"; var no_touch = 1;');
+assertSame(0, no_touch);
+
+// Test global indirect strict eval.
+// Expects new environment.
+var no_touch = 0;
+evil('"use strict"; var no_touch = 2;');
+assertSame(0, no_touch);
+
+// Test global direct non-strict eval.
+// Expects global environment.
+var no_touch = 0;
+eval('var no_touch = 3;');
+assertSame(3, no_touch);
+
+// Test global indirect non-strict eval.
+// Expects global environment.
+var no_touch = 0;
+evil('var no_touch = 4;');
+assertSame(4, no_touch);
+
+// Test non-global direct strict eval in non-strict function.
+// Expects new environment.
+var no_touch = 0;
+(function() {
+ var no_touch = 0;
+ eval('"use strict"; var no_touch = 5;');
+ assertSame(0, no_touch);
+})()
+assertSame(0, no_touch);
+
+// Test non-global indirect strict eval in non-strict function.
+// Expects new environment.
+var no_touch = 0;
+(function() {
+ var no_touch = 0;
+ evil('"use strict"; var no_touch = 6;');
+ assertSame(0, no_touch);
+})()
+assertSame(0, no_touch);
+
+// Test non-global direct non-strict eval in non-strict function.
+// Expects function environment.
+var no_touch = 0;
+(function() {
+ var no_touch = 0;
+ eval('var no_touch = 7;');
+ assertSame(7, no_touch);
+})()
+assertSame(0, no_touch);
+
+// Test non-global indirect non-strict eval in non-strict function.
+// Expects global environment.
+var no_touch = 0;
+(function() {
+ var no_touch = 0;
+ evil('var no_touch = 8;');
+ assertSame(0, no_touch);
+})()
+assertSame(8, no_touch);
+
+// Test non-global direct strict eval in strict function.
+// Expects new environment.
+var no_touch = 0;
+(function() {
+ "use strict";
+ var no_touch = 0;
+ eval('"use strict"; var no_touch = 9;');
+ assertSame(0, no_touch);
+})()
+assertSame(0, no_touch);
+
+// Test non-global indirect strict eval in strict function.
+// Expects new environment.
+var no_touch = 0;
+(function() {
+ "use strict";
+ var no_touch = 0;
+ evil('"use strict"; var no_touch = 10;');
+ assertSame(0, no_touch);
+})()
+assertSame(0, no_touch);
+
+// Test non-global direct non-strict eval in strict function.
+// Expects new environment.
+var no_touch = 0;
+(function() {
+ "use strict";
+ var no_touch = 0;
+ eval('var no_touch = 11;');
+ assertSame(0, no_touch);
+})()
+assertSame(0, no_touch);
+
+// Test non-global indirect non-strict eval in strict function.
+// Expects global environment.
+var no_touch = 0;
+(function() {
+ "use strict";
+ var no_touch = 0;
+ evil('var no_touch = 12;');
+ assertSame(0, no_touch);
+})()
+assertSame(12, no_touch);
diff --git a/test/mjsunit/regress/regress-1639-2.js b/test/mjsunit/regress/regress-1639-2.js
new file mode 100644
index 00000000..c439dd8f
--- /dev/null
+++ b/test/mjsunit/regress/regress-1639-2.js
@@ -0,0 +1,93 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+function sendCommand(state, cmd) {
+ // Get the debug command processor in paused state.
+ var dcp = state.debugCommandProcessor(false);
+ var request = JSON.stringify(cmd);
+ var response = dcp.processDebugJSONRequest(request);
+}
+
+var state = 0;
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Break) {
+ var line = event_data.sourceLineText();
+ print('break: ' + line);
+ print('event data: ' + event_data.toJSONProtocol());
+ print();
+ assertEquals('// BREAK', line.substr(-8),
+ "should not break outside evaluate");
+
+ switch (state) {
+ case 0:
+ state = 1;
+ // While in the debugger and stepping through a set of instructions
+ // executed in the evaluate command, the stepping must stop at the end
+ // of the said set of instructions and not step further into native
+ // debugger code.
+ sendCommand(exec_state, {
+ seq : 0,
+ type : "request",
+ command : "evaluate",
+ arguments : {
+ 'expression' : 'print("A"); debugger; print("B"); // BREAK',
+ 'global' : true
+ }
+ });
+ break;
+ case 1:
+ sendCommand(exec_state, {
+ seq : 0,
+ type : "request",
+ command : "continue",
+ arguments : {
+ stepaction : "next"
+ }
+ });
+ break;
+ }
+ }
+ } catch (e) {
+ print(e);
+ }
+}
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+function a() {
+} // BREAK
+
+// Set a break point and call to invoke the debug event listener.
+Debug.setBreakPoint(a, 0, 0);
+a();
diff --git a/test/mjsunit/regress/regress-1692.js b/test/mjsunit/regress/regress-1692.js
new file mode 100644
index 00000000..06bd66cf
--- /dev/null
+++ b/test/mjsunit/regress/regress-1692.js
@@ -0,0 +1,89 @@
+// 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.
+
+// Test that Object.prototype.propertyIsEnumerable handles array indices
+// correctly.
+
+var p = Object.create({}, {
+ a : { value : 42, enumerable : true },
+ b : { value : 42, enumerable : false },
+ 1 : { value : 42, enumerable : true },
+ 2 : { value : 42, enumerable : false },
+ f : { get: function(){}, enumerable: true },
+ g : { get: function(){}, enumerable: false },
+ 11 : { get: function(){}, enumerable: true },
+ 12 : { get: function(){}, enumerable: false }
+});
+var o = Object.create(p, {
+ c : { value : 42, enumerable : true },
+ d : { value : 42, enumerable : false },
+ 3 : { value : 42, enumerable : true },
+ 4 : { value : 42, enumerable : false },
+ h : { get: function(){}, enumerable: true },
+ k : { get: function(){}, enumerable: false },
+ 13 : { get: function(){}, enumerable: true },
+ 14 : { get: function(){}, enumerable: false }
+});
+
+// Inherited properties are ignored.
+assertFalse(o.propertyIsEnumerable("a"));
+assertFalse(o.propertyIsEnumerable("b"));
+assertFalse(o.propertyIsEnumerable("1"));
+assertFalse(o.propertyIsEnumerable("2"));
+
+// Own properties.
+assertTrue(o.propertyIsEnumerable("c"));
+assertFalse(o.propertyIsEnumerable("d"));
+assertTrue(o.propertyIsEnumerable("3"));
+assertFalse(o.propertyIsEnumerable("4"));
+
+// Inherited accessors.
+assertFalse(o.propertyIsEnumerable("f"));
+assertFalse(o.propertyIsEnumerable("g"));
+assertFalse(o.propertyIsEnumerable("11"));
+assertFalse(o.propertyIsEnumerable("12"));
+
+// Own accessors.
+assertTrue(o.propertyIsEnumerable("h"));
+assertFalse(o.propertyIsEnumerable("k"));
+assertTrue(o.propertyIsEnumerable("13"));
+assertFalse(o.propertyIsEnumerable("14"));
+
+// Nonexisting properties.
+assertFalse(o.propertyIsEnumerable("xxx"));
+assertFalse(o.propertyIsEnumerable("999"));
+
+// String object properties.
+var o = Object("string");
+// Non-string property on String object.
+o[10] = 42;
+assertTrue(o.propertyIsEnumerable(10));
+assertFalse(o.propertyIsEnumerable(0));
+
+// Fast elements.
+var o = [1,2,3,4,5];
+assertTrue(o.propertyIsEnumerable(3));
diff --git a/test/mjsunit/regress/regress-1708.js b/test/mjsunit/regress/regress-1708.js
new file mode 100644
index 00000000..ab50e078
--- /dev/null
+++ b/test/mjsunit/regress/regress-1708.js
@@ -0,0 +1,63 @@
+// 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.
+
+// Regression test of a very rare corner case where left-trimming an
+// array caused invalid marking bit patterns on lazily swept pages.
+
+// Flags: --expose-gc --noincremental-marking --max-new-space-size 1000
+
+(function() {
+ var head = new Array(1);
+ var tail = head;
+
+ // Fill heap to increase old-space size and trigger lazy sweeping on
+ // some of the old-space pages.
+ for (var i = 0; i < 200; i++) {
+ tail[1] = new Array(1000);
+ tail = tail[1];
+ }
+ array = new Array(100);
+ gc(); gc();
+
+ // At this point "array" should have been promoted to old-space and be
+ // located in a lazy swept page with intact marking bits. Now shift
+ // the array to trigger left-trimming operations.
+ assertEquals(100, array.length);
+ for (var i = 0; i < 50; i++) {
+ array.shift();
+ }
+ assertEquals(50, array.length);
+
+ // At this point "array" should have been trimmed from the left with
+ // marking bits being correctly transfered to the new object start.
+ // Scavenging operations cause lazy sweeping to advance and verify
+ // that marking bit patterns are still sane.
+ for (var i = 0; i < 200; i++) {
+ tail[1] = new Array(1000);
+ tail = tail[1];
+ }
+})();
diff --git a/test/mjsunit/regress/regress-1711.js b/test/mjsunit/regress/regress-1711.js
new file mode 100644
index 00000000..15591b1e
--- /dev/null
+++ b/test/mjsunit/regress/regress-1711.js
@@ -0,0 +1,38 @@
+// 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.
+
+// string.split needs to evaluate the separator's toString even if limit
+// is 0 because toString may have side effects.
+
+var side_effect = false;
+var separator = new Object();
+separator.toString = function() {
+ side_effect = true;
+ return undefined;
+}
+'subject'.split(separator, 0);
+assertTrue(side_effect);
diff --git a/test/mjsunit/regress/regress-1713.js b/test/mjsunit/regress/regress-1713.js
new file mode 100644
index 00000000..0af1144a
--- /dev/null
+++ b/test/mjsunit/regress/regress-1713.js
@@ -0,0 +1,127 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --always-compact --expose-gc
+
+var O = { get f() { return 0; } };
+
+var CODE = [];
+
+var R = [];
+
+function Allocate4Kb(N) {
+ var arr = [];
+ do {arr.push(new Array(1024));} while (--N > 0);
+ return arr;
+}
+
+function AllocateXMb(X) {
+ return Allocate4Kb((1024 * X) / 4);
+}
+
+function Node(v, next) { this.v = v; this.next = next; }
+
+Node.prototype.execute = function (O) {
+ var n = this;
+ while (n.next !== null) n = n.next;
+ n.v(O);
+};
+
+function LongList(N, x) {
+ if (N == 0) return new Node(x, null);
+ return new Node(new Array(1024), LongList(N - 1, x));
+}
+
+var L = LongList(1024, function (O) {
+ for (var i = 0; i < 5; i++) O.f;
+});
+
+
+
+function Incremental(O, x) {
+ if (!x) {
+ return;
+ }
+ function CreateCode(i) {
+ var f = new Function("return O.f_" + i);
+ CODE.push(f);
+ f(); // compile
+ f(); // compile
+ f(); // compile
+ }
+
+ for (var i = 0; i < 1e4; i++) CreateCode(i);
+ gc();
+ gc();
+ gc();
+
+ print(">>> 1 <<<");
+
+ L.execute(O);
+
+ try {} catch (e) {}
+
+ L = null;
+ print(">>> 2 <<<");
+ AllocateXMb(8);
+ //rint("1");
+ //llocateXMb(8);
+ //rint("1");
+ //llocateXMb(8);
+
+}
+
+function foo(O, x) {
+ Incremental(O, x);
+
+ print('f');
+
+ for (var i = 0; i < 5; i++) O.f;
+
+
+ print('g');
+
+ bar(x);
+}
+
+function bar(x) {
+ if (!x) return;
+ %DeoptimizeFunction(foo);
+ AllocateXMb(8);
+ AllocateXMb(8);
+}
+
+var O1 = {};
+var O2 = {};
+var O3 = {};
+var O4 = {f:0};
+
+foo(O1, false);
+foo(O2, false);
+foo(O3, false);
+%OptimizeFunctionOnNextCall(foo);
+foo(O4, true);
diff --git a/test/mjsunit/regress/regress-1748.js b/test/mjsunit/regress/regress-1748.js
new file mode 100644
index 00000000..e287e554
--- /dev/null
+++ b/test/mjsunit/regress/regress-1748.js
@@ -0,0 +1,35 @@
+// 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.
+
+// Test that /^/ only matches at beginning of string.
+// Bug in x64 caused it to match when executing the RegExp on a part
+// of a string that starts at a multiplum of 256.
+
+var str = Array(10000).join("X");
+str.replace(/^|X/g, function(m, i, s) {
+ if (i > 0) assertEquals("X", m, "at position 0x" + i.toString(16));
+}); \ No newline at end of file
diff --git a/test/mjsunit/regress/regress-1757.js b/test/mjsunit/regress/regress-1757.js
new file mode 100644
index 00000000..f7a5516c
--- /dev/null
+++ b/test/mjsunit/regress/regress-1757.js
@@ -0,0 +1,32 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --string-slices --expose-externalize-string
+
+var a = "abcdefghijklmnopqrstuvqxy"+"z";
+externalizeString(a, true);
+assertEquals('b', a.substring(1).charAt(0)); \ No newline at end of file
diff --git a/test/mjsunit/regress/regress-1790.js b/test/mjsunit/regress/regress-1790.js
new file mode 100644
index 00000000..8848eeaf
--- /dev/null
+++ b/test/mjsunit/regress/regress-1790.js
@@ -0,0 +1,58 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Regression test checking that the sequence of element access in built-in
+// array functions is specification conform (i.e. [[HasProperty]] might return
+// bogus result after [[Get]] has been called).
+
+function CheckSequence(builtin, callback) {
+ var array = [1,2,3];
+ var callback_count = 0;
+ var callback_wrapper = function() {
+ callback_count++;
+ return callback()
+ }
+
+ // Define getter that will delete itself upon first invocation.
+ Object.defineProperty(array, '1', {
+ get: function () { delete array[1]; },
+ configurable: true
+ });
+
+ assertTrue(array.hasOwnProperty('1'));
+ builtin.apply(array, [callback_wrapper, 'argument']);
+ assertFalse(array.hasOwnProperty('1'));
+ assertEquals(3, callback_count);
+}
+
+CheckSequence(Array.prototype.every, function() { return true; });
+CheckSequence(Array.prototype.filter, function() { return true; });
+CheckSequence(Array.prototype.forEach, function() { return 0; });
+CheckSequence(Array.prototype.map, function() { return 0; });
+CheckSequence(Array.prototype.reduce, function() { return 0; });
+CheckSequence(Array.prototype.reduceRight, function() { return 0; });
+CheckSequence(Array.prototype.some, function() { return false; });
diff --git a/test/mjsunit/regress/regress-1849.js b/test/mjsunit/regress/regress-1849.js
new file mode 100644
index 00000000..176f918b
--- /dev/null
+++ b/test/mjsunit/regress/regress-1849.js
@@ -0,0 +1,39 @@
+// 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.
+
+// See: http://code.google.com/p/v8/issues/detail?id=1878
+
+// Flags: --allow-natives-syntax
+
+var count = 1e5;
+var arr = new Array(count);
+assertFalse(%HasFastDoubleElements(arr));
+for (var i = 0; i < count; i++) {
+ arr[i] = 0;
+}
+assertFalse(%HasFastDoubleElements(arr));
+assertTrue(%HasFastSmiOnlyElements(arr));
diff --git a/test/mjsunit/regress/regress-1853.js b/test/mjsunit/regress/regress-1853.js
new file mode 100644
index 00000000..f80badec
--- /dev/null
+++ b/test/mjsunit/regress/regress-1853.js
@@ -0,0 +1,116 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+
+// Test whether scripts compiled after setting the break point are
+// updated correctly.
+
+Debug = debug.Debug;
+
+var break_count = 0;
+var test_break_1 = false;
+var test_break_2 = false;
+
+function sendCommand(state, cmd) {
+ // Get the debug command processor in paused state.
+ var dcp = state.debugCommandProcessor(false);
+ var request = JSON.stringify(cmd);
+ var response = dcp.processDebugJSONRequest(request);
+ return JSON.parse(response);
+}
+
+function setBreakPointByName(state) {
+ sendCommand(state, {
+ seq: 0,
+ type: "request",
+ command: "setbreakpoint",
+ arguments: {
+ type: "script",
+ target: "testScriptOne",
+ line: 2
+ }
+ });
+}
+
+function setBreakPointByRegExp(state) {
+ sendCommand(state, {
+ seq: 0,
+ type: "request",
+ command: "setbreakpoint",
+ arguments: {
+ type: "scriptRegExp",
+ target: "Scrip.Two",
+ line: 2
+ }
+ });
+}
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Break) {
+ switch (break_count) {
+ case 0:
+ // Set break points before the code has been compiled.
+ setBreakPointByName(exec_state);
+ setBreakPointByRegExp(exec_state);
+ break;
+ case 1:
+ // Set the flag to prove that we hit the first break point.
+ test_break_1 = true;
+ break;
+ case 2:
+ // Set the flag to prove that we hit the second break point.
+ test_break_2 = true;
+ break;
+ }
+ break_count++;
+ }
+ } catch (e) {
+ print(e);
+ }
+}
+
+Debug.setListener(listener);
+debugger;
+
+eval('function test1() { \n' +
+ ' assertFalse(test_break_1); \n' +
+ ' assertTrue(test_break_1); \n' +
+ '} \n' +
+ '//@ sourceURL=testScriptOne');
+
+eval('function test2() { \n' +
+ ' assertFalse(test_break_2); \n' +
+ ' assertTrue(test_break_2); \n' +
+ '} \n' +
+ '//@ sourceURL=testScriptTwo');
+
+test1();
+test2();
+assertEquals(3, break_count);
+
diff --git a/test/mjsunit/regress/regress-1878.js b/test/mjsunit/regress/regress-1878.js
new file mode 100644
index 00000000..a1648b12
--- /dev/null
+++ b/test/mjsunit/regress/regress-1878.js
@@ -0,0 +1,44 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// See: http://code.google.com/p/v8/issues/detail?id=1878
+
+// Flags: --allow-natives-syntax --expose_natives_as=natives
+
+var a = Array();
+
+for (var i = 0; i < 1000; i++) {
+ var ai = natives.InternalArray(10000);
+ assertFalse(%HaveSameMap(ai, a));
+ assertTrue(%HasFastElements(ai));
+}
+
+for (var i = 0; i < 1000; i++) {
+ var ai = new natives.InternalArray(10000);
+ assertFalse(%HaveSameMap(ai, a));
+ assertTrue(%HasFastElements(ai));
+}
diff --git a/test/mjsunit/regress/regress-1898.js b/test/mjsunit/regress/regress-1898.js
new file mode 100644
index 00000000..5440446f
--- /dev/null
+++ b/test/mjsunit/regress/regress-1898.js
@@ -0,0 +1,37 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function f(x) {
+ Math.log(Math.min(0.1, Math.abs(x)));
+}
+
+f(0.1);
+f(0.1);
+%OptimizeFunctionOnNextCall(f);
+f(0.1);
diff --git a/test/mjsunit/regress/regress-1924.js b/test/mjsunit/regress/regress-1924.js
new file mode 100644
index 00000000..80395414
--- /dev/null
+++ b/test/mjsunit/regress/regress-1924.js
@@ -0,0 +1,42 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// For http://code.google.com/p/v8/issues/detail?id=1924
+
+a: break a;
+a: b: break a;
+a: b: break b;
+assertThrows("a: break a a", SyntaxError)
+assertThrows("a: break a 1", SyntaxError)
+assertThrows("a: break a ''", SyntaxError)
+assertThrows("a: break a var b", SyntaxError)
+assertThrows("a: break a {}", SyntaxError)
+
+a: if (0) break a;
+b: if (0) {break b;} else {}
+c: if (0) break c; else {}
+d: if (0) break d; else break d;
diff --git a/test/mjsunit/regress/regress-1945.js b/test/mjsunit/regress/regress-1945.js
new file mode 100644
index 00000000..bffc775f
--- /dev/null
+++ b/test/mjsunit/regress/regress-1945.js
@@ -0,0 +1,34 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+var _d = new Date();
+_d.setHours(0,0,0,0);
+_d.setHours(0,0,0,0);
+%OptimizeFunctionOnNextCall(_d.setHours);
+_d.setHours(0,0,0,0);
diff --git a/test/mjsunit/regress/regress-1969.js b/test/mjsunit/regress/regress-1969.js
new file mode 100644
index 00000000..2728c2ca
--- /dev/null
+++ b/test/mjsunit/regress/regress-1969.js
@@ -0,0 +1,5045 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+f();
+f();
+%OptimizeFunctionOnNextCall(f);
+var start = (new Date()).getTime();
+var array = f();
+var end = (new Date()).getTime();
+
+// Assert that recompiling and executing f() takes less than a second.
+assertTrue((end - start) < 1000);
+
+for (var i = 0; i < 5000; i++) assertEquals(0, array[i]);
+
+function f() {
+ var a = new Array(5000);
+ a[0]=0;
+ a[1]=0;
+ a[2]=0;
+ a[3]=0;
+ a[4]=0;
+ a[5]=0;
+ a[6]=0;
+ a[7]=0;
+ a[8]=0;
+ a[9]=0;
+ a[10]=0;
+ a[11]=0;
+ a[12]=0;
+ a[13]=0;
+ a[14]=0;
+ a[15]=0;
+ a[16]=0;
+ a[17]=0;
+ a[18]=0;
+ a[19]=0;
+ a[20]=0;
+ a[21]=0;
+ a[22]=0;
+ a[23]=0;
+ a[24]=0;
+ a[25]=0;
+ a[26]=0;
+ a[27]=0;
+ a[28]=0;
+ a[29]=0;
+ a[30]=0;
+ a[31]=0;
+ a[32]=0;
+ a[33]=0;
+ a[34]=0;
+ a[35]=0;
+ a[36]=0;
+ a[37]=0;
+ a[38]=0;
+ a[39]=0;
+ a[40]=0;
+ a[41]=0;
+ a[42]=0;
+ a[43]=0;
+ a[44]=0;
+ a[45]=0;
+ a[46]=0;
+ a[47]=0;
+ a[48]=0;
+ a[49]=0;
+ a[50]=0;
+ a[51]=0;
+ a[52]=0;
+ a[53]=0;
+ a[54]=0;
+ a[55]=0;
+ a[56]=0;
+ a[57]=0;
+ a[58]=0;
+ a[59]=0;
+ a[60]=0;
+ a[61]=0;
+ a[62]=0;
+ a[63]=0;
+ a[64]=0;
+ a[65]=0;
+ a[66]=0;
+ a[67]=0;
+ a[68]=0;
+ a[69]=0;
+ a[70]=0;
+ a[71]=0;
+ a[72]=0;
+ a[73]=0;
+ a[74]=0;
+ a[75]=0;
+ a[76]=0;
+ a[77]=0;
+ a[78]=0;
+ a[79]=0;
+ a[80]=0;
+ a[81]=0;
+ a[82]=0;
+ a[83]=0;
+ a[84]=0;
+ a[85]=0;
+ a[86]=0;
+ a[87]=0;
+ a[88]=0;
+ a[89]=0;
+ a[90]=0;
+ a[91]=0;
+ a[92]=0;
+ a[93]=0;
+ a[94]=0;
+ a[95]=0;
+ a[96]=0;
+ a[97]=0;
+ a[98]=0;
+ a[99]=0;
+ a[100]=0;
+ a[101]=0;
+ a[102]=0;
+ a[103]=0;
+ a[104]=0;
+ a[105]=0;
+ a[106]=0;
+ a[107]=0;
+ a[108]=0;
+ a[109]=0;
+ a[110]=0;
+ a[111]=0;
+ a[112]=0;
+ a[113]=0;
+ a[114]=0;
+ a[115]=0;
+ a[116]=0;
+ a[117]=0;
+ a[118]=0;
+ a[119]=0;
+ a[120]=0;
+ a[121]=0;
+ a[122]=0;
+ a[123]=0;
+ a[124]=0;
+ a[125]=0;
+ a[126]=0;
+ a[127]=0;
+ a[128]=0;
+ a[129]=0;
+ a[130]=0;
+ a[131]=0;
+ a[132]=0;
+ a[133]=0;
+ a[134]=0;
+ a[135]=0;
+ a[136]=0;
+ a[137]=0;
+ a[138]=0;
+ a[139]=0;
+ a[140]=0;
+ a[141]=0;
+ a[142]=0;
+ a[143]=0;
+ a[144]=0;
+ a[145]=0;
+ a[146]=0;
+ a[147]=0;
+ a[148]=0;
+ a[149]=0;
+ a[150]=0;
+ a[151]=0;
+ a[152]=0;
+ a[153]=0;
+ a[154]=0;
+ a[155]=0;
+ a[156]=0;
+ a[157]=0;
+ a[158]=0;
+ a[159]=0;
+ a[160]=0;
+ a[161]=0;
+ a[162]=0;
+ a[163]=0;
+ a[164]=0;
+ a[165]=0;
+ a[166]=0;
+ a[167]=0;
+ a[168]=0;
+ a[169]=0;
+ a[170]=0;
+ a[171]=0;
+ a[172]=0;
+ a[173]=0;
+ a[174]=0;
+ a[175]=0;
+ a[176]=0;
+ a[177]=0;
+ a[178]=0;
+ a[179]=0;
+ a[180]=0;
+ a[181]=0;
+ a[182]=0;
+ a[183]=0;
+ a[184]=0;
+ a[185]=0;
+ a[186]=0;
+ a[187]=0;
+ a[188]=0;
+ a[189]=0;
+ a[190]=0;
+ a[191]=0;
+ a[192]=0;
+ a[193]=0;
+ a[194]=0;
+ a[195]=0;
+ a[196]=0;
+ a[197]=0;
+ a[198]=0;
+ a[199]=0;
+ a[200]=0;
+ a[201]=0;
+ a[202]=0;
+ a[203]=0;
+ a[204]=0;
+ a[205]=0;
+ a[206]=0;
+ a[207]=0;
+ a[208]=0;
+ a[209]=0;
+ a[210]=0;
+ a[211]=0;
+ a[212]=0;
+ a[213]=0;
+ a[214]=0;
+ a[215]=0;
+ a[216]=0;
+ a[217]=0;
+ a[218]=0;
+ a[219]=0;
+ a[220]=0;
+ a[221]=0;
+ a[222]=0;
+ a[223]=0;
+ a[224]=0;
+ a[225]=0;
+ a[226]=0;
+ a[227]=0;
+ a[228]=0;
+ a[229]=0;
+ a[230]=0;
+ a[231]=0;
+ a[232]=0;
+ a[233]=0;
+ a[234]=0;
+ a[235]=0;
+ a[236]=0;
+ a[237]=0;
+ a[238]=0;
+ a[239]=0;
+ a[240]=0;
+ a[241]=0;
+ a[242]=0;
+ a[243]=0;
+ a[244]=0;
+ a[245]=0;
+ a[246]=0;
+ a[247]=0;
+ a[248]=0;
+ a[249]=0;
+ a[250]=0;
+ a[251]=0;
+ a[252]=0;
+ a[253]=0;
+ a[254]=0;
+ a[255]=0;
+ a[256]=0;
+ a[257]=0;
+ a[258]=0;
+ a[259]=0;
+ a[260]=0;
+ a[261]=0;
+ a[262]=0;
+ a[263]=0;
+ a[264]=0;
+ a[265]=0;
+ a[266]=0;
+ a[267]=0;
+ a[268]=0;
+ a[269]=0;
+ a[270]=0;
+ a[271]=0;
+ a[272]=0;
+ a[273]=0;
+ a[274]=0;
+ a[275]=0;
+ a[276]=0;
+ a[277]=0;
+ a[278]=0;
+ a[279]=0;
+ a[280]=0;
+ a[281]=0;
+ a[282]=0;
+ a[283]=0;
+ a[284]=0;
+ a[285]=0;
+ a[286]=0;
+ a[287]=0;
+ a[288]=0;
+ a[289]=0;
+ a[290]=0;
+ a[291]=0;
+ a[292]=0;
+ a[293]=0;
+ a[294]=0;
+ a[295]=0;
+ a[296]=0;
+ a[297]=0;
+ a[298]=0;
+ a[299]=0;
+ a[300]=0;
+ a[301]=0;
+ a[302]=0;
+ a[303]=0;
+ a[304]=0;
+ a[305]=0;
+ a[306]=0;
+ a[307]=0;
+ a[308]=0;
+ a[309]=0;
+ a[310]=0;
+ a[311]=0;
+ a[312]=0;
+ a[313]=0;
+ a[314]=0;
+ a[315]=0;
+ a[316]=0;
+ a[317]=0;
+ a[318]=0;
+ a[319]=0;
+ a[320]=0;
+ a[321]=0;
+ a[322]=0;
+ a[323]=0;
+ a[324]=0;
+ a[325]=0;
+ a[326]=0;
+ a[327]=0;
+ a[328]=0;
+ a[329]=0;
+ a[330]=0;
+ a[331]=0;
+ a[332]=0;
+ a[333]=0;
+ a[334]=0;
+ a[335]=0;
+ a[336]=0;
+ a[337]=0;
+ a[338]=0;
+ a[339]=0;
+ a[340]=0;
+ a[341]=0;
+ a[342]=0;
+ a[343]=0;
+ a[344]=0;
+ a[345]=0;
+ a[346]=0;
+ a[347]=0;
+ a[348]=0;
+ a[349]=0;
+ a[350]=0;
+ a[351]=0;
+ a[352]=0;
+ a[353]=0;
+ a[354]=0;
+ a[355]=0;
+ a[356]=0;
+ a[357]=0;
+ a[358]=0;
+ a[359]=0;
+ a[360]=0;
+ a[361]=0;
+ a[362]=0;
+ a[363]=0;
+ a[364]=0;
+ a[365]=0;
+ a[366]=0;
+ a[367]=0;
+ a[368]=0;
+ a[369]=0;
+ a[370]=0;
+ a[371]=0;
+ a[372]=0;
+ a[373]=0;
+ a[374]=0;
+ a[375]=0;
+ a[376]=0;
+ a[377]=0;
+ a[378]=0;
+ a[379]=0;
+ a[380]=0;
+ a[381]=0;
+ a[382]=0;
+ a[383]=0;
+ a[384]=0;
+ a[385]=0;
+ a[386]=0;
+ a[387]=0;
+ a[388]=0;
+ a[389]=0;
+ a[390]=0;
+ a[391]=0;
+ a[392]=0;
+ a[393]=0;
+ a[394]=0;
+ a[395]=0;
+ a[396]=0;
+ a[397]=0;
+ a[398]=0;
+ a[399]=0;
+ a[400]=0;
+ a[401]=0;
+ a[402]=0;
+ a[403]=0;
+ a[404]=0;
+ a[405]=0;
+ a[406]=0;
+ a[407]=0;
+ a[408]=0;
+ a[409]=0;
+ a[410]=0;
+ a[411]=0;
+ a[412]=0;
+ a[413]=0;
+ a[414]=0;
+ a[415]=0;
+ a[416]=0;
+ a[417]=0;
+ a[418]=0;
+ a[419]=0;
+ a[420]=0;
+ a[421]=0;
+ a[422]=0;
+ a[423]=0;
+ a[424]=0;
+ a[425]=0;
+ a[426]=0;
+ a[427]=0;
+ a[428]=0;
+ a[429]=0;
+ a[430]=0;
+ a[431]=0;
+ a[432]=0;
+ a[433]=0;
+ a[434]=0;
+ a[435]=0;
+ a[436]=0;
+ a[437]=0;
+ a[438]=0;
+ a[439]=0;
+ a[440]=0;
+ a[441]=0;
+ a[442]=0;
+ a[443]=0;
+ a[444]=0;
+ a[445]=0;
+ a[446]=0;
+ a[447]=0;
+ a[448]=0;
+ a[449]=0;
+ a[450]=0;
+ a[451]=0;
+ a[452]=0;
+ a[453]=0;
+ a[454]=0;
+ a[455]=0;
+ a[456]=0;
+ a[457]=0;
+ a[458]=0;
+ a[459]=0;
+ a[460]=0;
+ a[461]=0;
+ a[462]=0;
+ a[463]=0;
+ a[464]=0;
+ a[465]=0;
+ a[466]=0;
+ a[467]=0;
+ a[468]=0;
+ a[469]=0;
+ a[470]=0;
+ a[471]=0;
+ a[472]=0;
+ a[473]=0;
+ a[474]=0;
+ a[475]=0;
+ a[476]=0;
+ a[477]=0;
+ a[478]=0;
+ a[479]=0;
+ a[480]=0;
+ a[481]=0;
+ a[482]=0;
+ a[483]=0;
+ a[484]=0;
+ a[485]=0;
+ a[486]=0;
+ a[487]=0;
+ a[488]=0;
+ a[489]=0;
+ a[490]=0;
+ a[491]=0;
+ a[492]=0;
+ a[493]=0;
+ a[494]=0;
+ a[495]=0;
+ a[496]=0;
+ a[497]=0;
+ a[498]=0;
+ a[499]=0;
+ a[500]=0;
+ a[501]=0;
+ a[502]=0;
+ a[503]=0;
+ a[504]=0;
+ a[505]=0;
+ a[506]=0;
+ a[507]=0;
+ a[508]=0;
+ a[509]=0;
+ a[510]=0;
+ a[511]=0;
+ a[512]=0;
+ a[513]=0;
+ a[514]=0;
+ a[515]=0;
+ a[516]=0;
+ a[517]=0;
+ a[518]=0;
+ a[519]=0;
+ a[520]=0;
+ a[521]=0;
+ a[522]=0;
+ a[523]=0;
+ a[524]=0;
+ a[525]=0;
+ a[526]=0;
+ a[527]=0;
+ a[528]=0;
+ a[529]=0;
+ a[530]=0;
+ a[531]=0;
+ a[532]=0;
+ a[533]=0;
+ a[534]=0;
+ a[535]=0;
+ a[536]=0;
+ a[537]=0;
+ a[538]=0;
+ a[539]=0;
+ a[540]=0;
+ a[541]=0;
+ a[542]=0;
+ a[543]=0;
+ a[544]=0;
+ a[545]=0;
+ a[546]=0;
+ a[547]=0;
+ a[548]=0;
+ a[549]=0;
+ a[550]=0;
+ a[551]=0;
+ a[552]=0;
+ a[553]=0;
+ a[554]=0;
+ a[555]=0;
+ a[556]=0;
+ a[557]=0;
+ a[558]=0;
+ a[559]=0;
+ a[560]=0;
+ a[561]=0;
+ a[562]=0;
+ a[563]=0;
+ a[564]=0;
+ a[565]=0;
+ a[566]=0;
+ a[567]=0;
+ a[568]=0;
+ a[569]=0;
+ a[570]=0;
+ a[571]=0;
+ a[572]=0;
+ a[573]=0;
+ a[574]=0;
+ a[575]=0;
+ a[576]=0;
+ a[577]=0;
+ a[578]=0;
+ a[579]=0;
+ a[580]=0;
+ a[581]=0;
+ a[582]=0;
+ a[583]=0;
+ a[584]=0;
+ a[585]=0;
+ a[586]=0;
+ a[587]=0;
+ a[588]=0;
+ a[589]=0;
+ a[590]=0;
+ a[591]=0;
+ a[592]=0;
+ a[593]=0;
+ a[594]=0;
+ a[595]=0;
+ a[596]=0;
+ a[597]=0;
+ a[598]=0;
+ a[599]=0;
+ a[600]=0;
+ a[601]=0;
+ a[602]=0;
+ a[603]=0;
+ a[604]=0;
+ a[605]=0;
+ a[606]=0;
+ a[607]=0;
+ a[608]=0;
+ a[609]=0;
+ a[610]=0;
+ a[611]=0;
+ a[612]=0;
+ a[613]=0;
+ a[614]=0;
+ a[615]=0;
+ a[616]=0;
+ a[617]=0;
+ a[618]=0;
+ a[619]=0;
+ a[620]=0;
+ a[621]=0;
+ a[622]=0;
+ a[623]=0;
+ a[624]=0;
+ a[625]=0;
+ a[626]=0;
+ a[627]=0;
+ a[628]=0;
+ a[629]=0;
+ a[630]=0;
+ a[631]=0;
+ a[632]=0;
+ a[633]=0;
+ a[634]=0;
+ a[635]=0;
+ a[636]=0;
+ a[637]=0;
+ a[638]=0;
+ a[639]=0;
+ a[640]=0;
+ a[641]=0;
+ a[642]=0;
+ a[643]=0;
+ a[644]=0;
+ a[645]=0;
+ a[646]=0;
+ a[647]=0;
+ a[648]=0;
+ a[649]=0;
+ a[650]=0;
+ a[651]=0;
+ a[652]=0;
+ a[653]=0;
+ a[654]=0;
+ a[655]=0;
+ a[656]=0;
+ a[657]=0;
+ a[658]=0;
+ a[659]=0;
+ a[660]=0;
+ a[661]=0;
+ a[662]=0;
+ a[663]=0;
+ a[664]=0;
+ a[665]=0;
+ a[666]=0;
+ a[667]=0;
+ a[668]=0;
+ a[669]=0;
+ a[670]=0;
+ a[671]=0;
+ a[672]=0;
+ a[673]=0;
+ a[674]=0;
+ a[675]=0;
+ a[676]=0;
+ a[677]=0;
+ a[678]=0;
+ a[679]=0;
+ a[680]=0;
+ a[681]=0;
+ a[682]=0;
+ a[683]=0;
+ a[684]=0;
+ a[685]=0;
+ a[686]=0;
+ a[687]=0;
+ a[688]=0;
+ a[689]=0;
+ a[690]=0;
+ a[691]=0;
+ a[692]=0;
+ a[693]=0;
+ a[694]=0;
+ a[695]=0;
+ a[696]=0;
+ a[697]=0;
+ a[698]=0;
+ a[699]=0;
+ a[700]=0;
+ a[701]=0;
+ a[702]=0;
+ a[703]=0;
+ a[704]=0;
+ a[705]=0;
+ a[706]=0;
+ a[707]=0;
+ a[708]=0;
+ a[709]=0;
+ a[710]=0;
+ a[711]=0;
+ a[712]=0;
+ a[713]=0;
+ a[714]=0;
+ a[715]=0;
+ a[716]=0;
+ a[717]=0;
+ a[718]=0;
+ a[719]=0;
+ a[720]=0;
+ a[721]=0;
+ a[722]=0;
+ a[723]=0;
+ a[724]=0;
+ a[725]=0;
+ a[726]=0;
+ a[727]=0;
+ a[728]=0;
+ a[729]=0;
+ a[730]=0;
+ a[731]=0;
+ a[732]=0;
+ a[733]=0;
+ a[734]=0;
+ a[735]=0;
+ a[736]=0;
+ a[737]=0;
+ a[738]=0;
+ a[739]=0;
+ a[740]=0;
+ a[741]=0;
+ a[742]=0;
+ a[743]=0;
+ a[744]=0;
+ a[745]=0;
+ a[746]=0;
+ a[747]=0;
+ a[748]=0;
+ a[749]=0;
+ a[750]=0;
+ a[751]=0;
+ a[752]=0;
+ a[753]=0;
+ a[754]=0;
+ a[755]=0;
+ a[756]=0;
+ a[757]=0;
+ a[758]=0;
+ a[759]=0;
+ a[760]=0;
+ a[761]=0;
+ a[762]=0;
+ a[763]=0;
+ a[764]=0;
+ a[765]=0;
+ a[766]=0;
+ a[767]=0;
+ a[768]=0;
+ a[769]=0;
+ a[770]=0;
+ a[771]=0;
+ a[772]=0;
+ a[773]=0;
+ a[774]=0;
+ a[775]=0;
+ a[776]=0;
+ a[777]=0;
+ a[778]=0;
+ a[779]=0;
+ a[780]=0;
+ a[781]=0;
+ a[782]=0;
+ a[783]=0;
+ a[784]=0;
+ a[785]=0;
+ a[786]=0;
+ a[787]=0;
+ a[788]=0;
+ a[789]=0;
+ a[790]=0;
+ a[791]=0;
+ a[792]=0;
+ a[793]=0;
+ a[794]=0;
+ a[795]=0;
+ a[796]=0;
+ a[797]=0;
+ a[798]=0;
+ a[799]=0;
+ a[800]=0;
+ a[801]=0;
+ a[802]=0;
+ a[803]=0;
+ a[804]=0;
+ a[805]=0;
+ a[806]=0;
+ a[807]=0;
+ a[808]=0;
+ a[809]=0;
+ a[810]=0;
+ a[811]=0;
+ a[812]=0;
+ a[813]=0;
+ a[814]=0;
+ a[815]=0;
+ a[816]=0;
+ a[817]=0;
+ a[818]=0;
+ a[819]=0;
+ a[820]=0;
+ a[821]=0;
+ a[822]=0;
+ a[823]=0;
+ a[824]=0;
+ a[825]=0;
+ a[826]=0;
+ a[827]=0;
+ a[828]=0;
+ a[829]=0;
+ a[830]=0;
+ a[831]=0;
+ a[832]=0;
+ a[833]=0;
+ a[834]=0;
+ a[835]=0;
+ a[836]=0;
+ a[837]=0;
+ a[838]=0;
+ a[839]=0;
+ a[840]=0;
+ a[841]=0;
+ a[842]=0;
+ a[843]=0;
+ a[844]=0;
+ a[845]=0;
+ a[846]=0;
+ a[847]=0;
+ a[848]=0;
+ a[849]=0;
+ a[850]=0;
+ a[851]=0;
+ a[852]=0;
+ a[853]=0;
+ a[854]=0;
+ a[855]=0;
+ a[856]=0;
+ a[857]=0;
+ a[858]=0;
+ a[859]=0;
+ a[860]=0;
+ a[861]=0;
+ a[862]=0;
+ a[863]=0;
+ a[864]=0;
+ a[865]=0;
+ a[866]=0;
+ a[867]=0;
+ a[868]=0;
+ a[869]=0;
+ a[870]=0;
+ a[871]=0;
+ a[872]=0;
+ a[873]=0;
+ a[874]=0;
+ a[875]=0;
+ a[876]=0;
+ a[877]=0;
+ a[878]=0;
+ a[879]=0;
+ a[880]=0;
+ a[881]=0;
+ a[882]=0;
+ a[883]=0;
+ a[884]=0;
+ a[885]=0;
+ a[886]=0;
+ a[887]=0;
+ a[888]=0;
+ a[889]=0;
+ a[890]=0;
+ a[891]=0;
+ a[892]=0;
+ a[893]=0;
+ a[894]=0;
+ a[895]=0;
+ a[896]=0;
+ a[897]=0;
+ a[898]=0;
+ a[899]=0;
+ a[900]=0;
+ a[901]=0;
+ a[902]=0;
+ a[903]=0;
+ a[904]=0;
+ a[905]=0;
+ a[906]=0;
+ a[907]=0;
+ a[908]=0;
+ a[909]=0;
+ a[910]=0;
+ a[911]=0;
+ a[912]=0;
+ a[913]=0;
+ a[914]=0;
+ a[915]=0;
+ a[916]=0;
+ a[917]=0;
+ a[918]=0;
+ a[919]=0;
+ a[920]=0;
+ a[921]=0;
+ a[922]=0;
+ a[923]=0;
+ a[924]=0;
+ a[925]=0;
+ a[926]=0;
+ a[927]=0;
+ a[928]=0;
+ a[929]=0;
+ a[930]=0;
+ a[931]=0;
+ a[932]=0;
+ a[933]=0;
+ a[934]=0;
+ a[935]=0;
+ a[936]=0;
+ a[937]=0;
+ a[938]=0;
+ a[939]=0;
+ a[940]=0;
+ a[941]=0;
+ a[942]=0;
+ a[943]=0;
+ a[944]=0;
+ a[945]=0;
+ a[946]=0;
+ a[947]=0;
+ a[948]=0;
+ a[949]=0;
+ a[950]=0;
+ a[951]=0;
+ a[952]=0;
+ a[953]=0;
+ a[954]=0;
+ a[955]=0;
+ a[956]=0;
+ a[957]=0;
+ a[958]=0;
+ a[959]=0;
+ a[960]=0;
+ a[961]=0;
+ a[962]=0;
+ a[963]=0;
+ a[964]=0;
+ a[965]=0;
+ a[966]=0;
+ a[967]=0;
+ a[968]=0;
+ a[969]=0;
+ a[970]=0;
+ a[971]=0;
+ a[972]=0;
+ a[973]=0;
+ a[974]=0;
+ a[975]=0;
+ a[976]=0;
+ a[977]=0;
+ a[978]=0;
+ a[979]=0;
+ a[980]=0;
+ a[981]=0;
+ a[982]=0;
+ a[983]=0;
+ a[984]=0;
+ a[985]=0;
+ a[986]=0;
+ a[987]=0;
+ a[988]=0;
+ a[989]=0;
+ a[990]=0;
+ a[991]=0;
+ a[992]=0;
+ a[993]=0;
+ a[994]=0;
+ a[995]=0;
+ a[996]=0;
+ a[997]=0;
+ a[998]=0;
+ a[999]=0;
+ a[1000]=0;
+ a[1001]=0;
+ a[1002]=0;
+ a[1003]=0;
+ a[1004]=0;
+ a[1005]=0;
+ a[1006]=0;
+ a[1007]=0;
+ a[1008]=0;
+ a[1009]=0;
+ a[1010]=0;
+ a[1011]=0;
+ a[1012]=0;
+ a[1013]=0;
+ a[1014]=0;
+ a[1015]=0;
+ a[1016]=0;
+ a[1017]=0;
+ a[1018]=0;
+ a[1019]=0;
+ a[1020]=0;
+ a[1021]=0;
+ a[1022]=0;
+ a[1023]=0;
+ a[1024]=0;
+ a[1025]=0;
+ a[1026]=0;
+ a[1027]=0;
+ a[1028]=0;
+ a[1029]=0;
+ a[1030]=0;
+ a[1031]=0;
+ a[1032]=0;
+ a[1033]=0;
+ a[1034]=0;
+ a[1035]=0;
+ a[1036]=0;
+ a[1037]=0;
+ a[1038]=0;
+ a[1039]=0;
+ a[1040]=0;
+ a[1041]=0;
+ a[1042]=0;
+ a[1043]=0;
+ a[1044]=0;
+ a[1045]=0;
+ a[1046]=0;
+ a[1047]=0;
+ a[1048]=0;
+ a[1049]=0;
+ a[1050]=0;
+ a[1051]=0;
+ a[1052]=0;
+ a[1053]=0;
+ a[1054]=0;
+ a[1055]=0;
+ a[1056]=0;
+ a[1057]=0;
+ a[1058]=0;
+ a[1059]=0;
+ a[1060]=0;
+ a[1061]=0;
+ a[1062]=0;
+ a[1063]=0;
+ a[1064]=0;
+ a[1065]=0;
+ a[1066]=0;
+ a[1067]=0;
+ a[1068]=0;
+ a[1069]=0;
+ a[1070]=0;
+ a[1071]=0;
+ a[1072]=0;
+ a[1073]=0;
+ a[1074]=0;
+ a[1075]=0;
+ a[1076]=0;
+ a[1077]=0;
+ a[1078]=0;
+ a[1079]=0;
+ a[1080]=0;
+ a[1081]=0;
+ a[1082]=0;
+ a[1083]=0;
+ a[1084]=0;
+ a[1085]=0;
+ a[1086]=0;
+ a[1087]=0;
+ a[1088]=0;
+ a[1089]=0;
+ a[1090]=0;
+ a[1091]=0;
+ a[1092]=0;
+ a[1093]=0;
+ a[1094]=0;
+ a[1095]=0;
+ a[1096]=0;
+ a[1097]=0;
+ a[1098]=0;
+ a[1099]=0;
+ a[1100]=0;
+ a[1101]=0;
+ a[1102]=0;
+ a[1103]=0;
+ a[1104]=0;
+ a[1105]=0;
+ a[1106]=0;
+ a[1107]=0;
+ a[1108]=0;
+ a[1109]=0;
+ a[1110]=0;
+ a[1111]=0;
+ a[1112]=0;
+ a[1113]=0;
+ a[1114]=0;
+ a[1115]=0;
+ a[1116]=0;
+ a[1117]=0;
+ a[1118]=0;
+ a[1119]=0;
+ a[1120]=0;
+ a[1121]=0;
+ a[1122]=0;
+ a[1123]=0;
+ a[1124]=0;
+ a[1125]=0;
+ a[1126]=0;
+ a[1127]=0;
+ a[1128]=0;
+ a[1129]=0;
+ a[1130]=0;
+ a[1131]=0;
+ a[1132]=0;
+ a[1133]=0;
+ a[1134]=0;
+ a[1135]=0;
+ a[1136]=0;
+ a[1137]=0;
+ a[1138]=0;
+ a[1139]=0;
+ a[1140]=0;
+ a[1141]=0;
+ a[1142]=0;
+ a[1143]=0;
+ a[1144]=0;
+ a[1145]=0;
+ a[1146]=0;
+ a[1147]=0;
+ a[1148]=0;
+ a[1149]=0;
+ a[1150]=0;
+ a[1151]=0;
+ a[1152]=0;
+ a[1153]=0;
+ a[1154]=0;
+ a[1155]=0;
+ a[1156]=0;
+ a[1157]=0;
+ a[1158]=0;
+ a[1159]=0;
+ a[1160]=0;
+ a[1161]=0;
+ a[1162]=0;
+ a[1163]=0;
+ a[1164]=0;
+ a[1165]=0;
+ a[1166]=0;
+ a[1167]=0;
+ a[1168]=0;
+ a[1169]=0;
+ a[1170]=0;
+ a[1171]=0;
+ a[1172]=0;
+ a[1173]=0;
+ a[1174]=0;
+ a[1175]=0;
+ a[1176]=0;
+ a[1177]=0;
+ a[1178]=0;
+ a[1179]=0;
+ a[1180]=0;
+ a[1181]=0;
+ a[1182]=0;
+ a[1183]=0;
+ a[1184]=0;
+ a[1185]=0;
+ a[1186]=0;
+ a[1187]=0;
+ a[1188]=0;
+ a[1189]=0;
+ a[1190]=0;
+ a[1191]=0;
+ a[1192]=0;
+ a[1193]=0;
+ a[1194]=0;
+ a[1195]=0;
+ a[1196]=0;
+ a[1197]=0;
+ a[1198]=0;
+ a[1199]=0;
+ a[1200]=0;
+ a[1201]=0;
+ a[1202]=0;
+ a[1203]=0;
+ a[1204]=0;
+ a[1205]=0;
+ a[1206]=0;
+ a[1207]=0;
+ a[1208]=0;
+ a[1209]=0;
+ a[1210]=0;
+ a[1211]=0;
+ a[1212]=0;
+ a[1213]=0;
+ a[1214]=0;
+ a[1215]=0;
+ a[1216]=0;
+ a[1217]=0;
+ a[1218]=0;
+ a[1219]=0;
+ a[1220]=0;
+ a[1221]=0;
+ a[1222]=0;
+ a[1223]=0;
+ a[1224]=0;
+ a[1225]=0;
+ a[1226]=0;
+ a[1227]=0;
+ a[1228]=0;
+ a[1229]=0;
+ a[1230]=0;
+ a[1231]=0;
+ a[1232]=0;
+ a[1233]=0;
+ a[1234]=0;
+ a[1235]=0;
+ a[1236]=0;
+ a[1237]=0;
+ a[1238]=0;
+ a[1239]=0;
+ a[1240]=0;
+ a[1241]=0;
+ a[1242]=0;
+ a[1243]=0;
+ a[1244]=0;
+ a[1245]=0;
+ a[1246]=0;
+ a[1247]=0;
+ a[1248]=0;
+ a[1249]=0;
+ a[1250]=0;
+ a[1251]=0;
+ a[1252]=0;
+ a[1253]=0;
+ a[1254]=0;
+ a[1255]=0;
+ a[1256]=0;
+ a[1257]=0;
+ a[1258]=0;
+ a[1259]=0;
+ a[1260]=0;
+ a[1261]=0;
+ a[1262]=0;
+ a[1263]=0;
+ a[1264]=0;
+ a[1265]=0;
+ a[1266]=0;
+ a[1267]=0;
+ a[1268]=0;
+ a[1269]=0;
+ a[1270]=0;
+ a[1271]=0;
+ a[1272]=0;
+ a[1273]=0;
+ a[1274]=0;
+ a[1275]=0;
+ a[1276]=0;
+ a[1277]=0;
+ a[1278]=0;
+ a[1279]=0;
+ a[1280]=0;
+ a[1281]=0;
+ a[1282]=0;
+ a[1283]=0;
+ a[1284]=0;
+ a[1285]=0;
+ a[1286]=0;
+ a[1287]=0;
+ a[1288]=0;
+ a[1289]=0;
+ a[1290]=0;
+ a[1291]=0;
+ a[1292]=0;
+ a[1293]=0;
+ a[1294]=0;
+ a[1295]=0;
+ a[1296]=0;
+ a[1297]=0;
+ a[1298]=0;
+ a[1299]=0;
+ a[1300]=0;
+ a[1301]=0;
+ a[1302]=0;
+ a[1303]=0;
+ a[1304]=0;
+ a[1305]=0;
+ a[1306]=0;
+ a[1307]=0;
+ a[1308]=0;
+ a[1309]=0;
+ a[1310]=0;
+ a[1311]=0;
+ a[1312]=0;
+ a[1313]=0;
+ a[1314]=0;
+ a[1315]=0;
+ a[1316]=0;
+ a[1317]=0;
+ a[1318]=0;
+ a[1319]=0;
+ a[1320]=0;
+ a[1321]=0;
+ a[1322]=0;
+ a[1323]=0;
+ a[1324]=0;
+ a[1325]=0;
+ a[1326]=0;
+ a[1327]=0;
+ a[1328]=0;
+ a[1329]=0;
+ a[1330]=0;
+ a[1331]=0;
+ a[1332]=0;
+ a[1333]=0;
+ a[1334]=0;
+ a[1335]=0;
+ a[1336]=0;
+ a[1337]=0;
+ a[1338]=0;
+ a[1339]=0;
+ a[1340]=0;
+ a[1341]=0;
+ a[1342]=0;
+ a[1343]=0;
+ a[1344]=0;
+ a[1345]=0;
+ a[1346]=0;
+ a[1347]=0;
+ a[1348]=0;
+ a[1349]=0;
+ a[1350]=0;
+ a[1351]=0;
+ a[1352]=0;
+ a[1353]=0;
+ a[1354]=0;
+ a[1355]=0;
+ a[1356]=0;
+ a[1357]=0;
+ a[1358]=0;
+ a[1359]=0;
+ a[1360]=0;
+ a[1361]=0;
+ a[1362]=0;
+ a[1363]=0;
+ a[1364]=0;
+ a[1365]=0;
+ a[1366]=0;
+ a[1367]=0;
+ a[1368]=0;
+ a[1369]=0;
+ a[1370]=0;
+ a[1371]=0;
+ a[1372]=0;
+ a[1373]=0;
+ a[1374]=0;
+ a[1375]=0;
+ a[1376]=0;
+ a[1377]=0;
+ a[1378]=0;
+ a[1379]=0;
+ a[1380]=0;
+ a[1381]=0;
+ a[1382]=0;
+ a[1383]=0;
+ a[1384]=0;
+ a[1385]=0;
+ a[1386]=0;
+ a[1387]=0;
+ a[1388]=0;
+ a[1389]=0;
+ a[1390]=0;
+ a[1391]=0;
+ a[1392]=0;
+ a[1393]=0;
+ a[1394]=0;
+ a[1395]=0;
+ a[1396]=0;
+ a[1397]=0;
+ a[1398]=0;
+ a[1399]=0;
+ a[1400]=0;
+ a[1401]=0;
+ a[1402]=0;
+ a[1403]=0;
+ a[1404]=0;
+ a[1405]=0;
+ a[1406]=0;
+ a[1407]=0;
+ a[1408]=0;
+ a[1409]=0;
+ a[1410]=0;
+ a[1411]=0;
+ a[1412]=0;
+ a[1413]=0;
+ a[1414]=0;
+ a[1415]=0;
+ a[1416]=0;
+ a[1417]=0;
+ a[1418]=0;
+ a[1419]=0;
+ a[1420]=0;
+ a[1421]=0;
+ a[1422]=0;
+ a[1423]=0;
+ a[1424]=0;
+ a[1425]=0;
+ a[1426]=0;
+ a[1427]=0;
+ a[1428]=0;
+ a[1429]=0;
+ a[1430]=0;
+ a[1431]=0;
+ a[1432]=0;
+ a[1433]=0;
+ a[1434]=0;
+ a[1435]=0;
+ a[1436]=0;
+ a[1437]=0;
+ a[1438]=0;
+ a[1439]=0;
+ a[1440]=0;
+ a[1441]=0;
+ a[1442]=0;
+ a[1443]=0;
+ a[1444]=0;
+ a[1445]=0;
+ a[1446]=0;
+ a[1447]=0;
+ a[1448]=0;
+ a[1449]=0;
+ a[1450]=0;
+ a[1451]=0;
+ a[1452]=0;
+ a[1453]=0;
+ a[1454]=0;
+ a[1455]=0;
+ a[1456]=0;
+ a[1457]=0;
+ a[1458]=0;
+ a[1459]=0;
+ a[1460]=0;
+ a[1461]=0;
+ a[1462]=0;
+ a[1463]=0;
+ a[1464]=0;
+ a[1465]=0;
+ a[1466]=0;
+ a[1467]=0;
+ a[1468]=0;
+ a[1469]=0;
+ a[1470]=0;
+ a[1471]=0;
+ a[1472]=0;
+ a[1473]=0;
+ a[1474]=0;
+ a[1475]=0;
+ a[1476]=0;
+ a[1477]=0;
+ a[1478]=0;
+ a[1479]=0;
+ a[1480]=0;
+ a[1481]=0;
+ a[1482]=0;
+ a[1483]=0;
+ a[1484]=0;
+ a[1485]=0;
+ a[1486]=0;
+ a[1487]=0;
+ a[1488]=0;
+ a[1489]=0;
+ a[1490]=0;
+ a[1491]=0;
+ a[1492]=0;
+ a[1493]=0;
+ a[1494]=0;
+ a[1495]=0;
+ a[1496]=0;
+ a[1497]=0;
+ a[1498]=0;
+ a[1499]=0;
+ a[1500]=0;
+ a[1501]=0;
+ a[1502]=0;
+ a[1503]=0;
+ a[1504]=0;
+ a[1505]=0;
+ a[1506]=0;
+ a[1507]=0;
+ a[1508]=0;
+ a[1509]=0;
+ a[1510]=0;
+ a[1511]=0;
+ a[1512]=0;
+ a[1513]=0;
+ a[1514]=0;
+ a[1515]=0;
+ a[1516]=0;
+ a[1517]=0;
+ a[1518]=0;
+ a[1519]=0;
+ a[1520]=0;
+ a[1521]=0;
+ a[1522]=0;
+ a[1523]=0;
+ a[1524]=0;
+ a[1525]=0;
+ a[1526]=0;
+ a[1527]=0;
+ a[1528]=0;
+ a[1529]=0;
+ a[1530]=0;
+ a[1531]=0;
+ a[1532]=0;
+ a[1533]=0;
+ a[1534]=0;
+ a[1535]=0;
+ a[1536]=0;
+ a[1537]=0;
+ a[1538]=0;
+ a[1539]=0;
+ a[1540]=0;
+ a[1541]=0;
+ a[1542]=0;
+ a[1543]=0;
+ a[1544]=0;
+ a[1545]=0;
+ a[1546]=0;
+ a[1547]=0;
+ a[1548]=0;
+ a[1549]=0;
+ a[1550]=0;
+ a[1551]=0;
+ a[1552]=0;
+ a[1553]=0;
+ a[1554]=0;
+ a[1555]=0;
+ a[1556]=0;
+ a[1557]=0;
+ a[1558]=0;
+ a[1559]=0;
+ a[1560]=0;
+ a[1561]=0;
+ a[1562]=0;
+ a[1563]=0;
+ a[1564]=0;
+ a[1565]=0;
+ a[1566]=0;
+ a[1567]=0;
+ a[1568]=0;
+ a[1569]=0;
+ a[1570]=0;
+ a[1571]=0;
+ a[1572]=0;
+ a[1573]=0;
+ a[1574]=0;
+ a[1575]=0;
+ a[1576]=0;
+ a[1577]=0;
+ a[1578]=0;
+ a[1579]=0;
+ a[1580]=0;
+ a[1581]=0;
+ a[1582]=0;
+ a[1583]=0;
+ a[1584]=0;
+ a[1585]=0;
+ a[1586]=0;
+ a[1587]=0;
+ a[1588]=0;
+ a[1589]=0;
+ a[1590]=0;
+ a[1591]=0;
+ a[1592]=0;
+ a[1593]=0;
+ a[1594]=0;
+ a[1595]=0;
+ a[1596]=0;
+ a[1597]=0;
+ a[1598]=0;
+ a[1599]=0;
+ a[1600]=0;
+ a[1601]=0;
+ a[1602]=0;
+ a[1603]=0;
+ a[1604]=0;
+ a[1605]=0;
+ a[1606]=0;
+ a[1607]=0;
+ a[1608]=0;
+ a[1609]=0;
+ a[1610]=0;
+ a[1611]=0;
+ a[1612]=0;
+ a[1613]=0;
+ a[1614]=0;
+ a[1615]=0;
+ a[1616]=0;
+ a[1617]=0;
+ a[1618]=0;
+ a[1619]=0;
+ a[1620]=0;
+ a[1621]=0;
+ a[1622]=0;
+ a[1623]=0;
+ a[1624]=0;
+ a[1625]=0;
+ a[1626]=0;
+ a[1627]=0;
+ a[1628]=0;
+ a[1629]=0;
+ a[1630]=0;
+ a[1631]=0;
+ a[1632]=0;
+ a[1633]=0;
+ a[1634]=0;
+ a[1635]=0;
+ a[1636]=0;
+ a[1637]=0;
+ a[1638]=0;
+ a[1639]=0;
+ a[1640]=0;
+ a[1641]=0;
+ a[1642]=0;
+ a[1643]=0;
+ a[1644]=0;
+ a[1645]=0;
+ a[1646]=0;
+ a[1647]=0;
+ a[1648]=0;
+ a[1649]=0;
+ a[1650]=0;
+ a[1651]=0;
+ a[1652]=0;
+ a[1653]=0;
+ a[1654]=0;
+ a[1655]=0;
+ a[1656]=0;
+ a[1657]=0;
+ a[1658]=0;
+ a[1659]=0;
+ a[1660]=0;
+ a[1661]=0;
+ a[1662]=0;
+ a[1663]=0;
+ a[1664]=0;
+ a[1665]=0;
+ a[1666]=0;
+ a[1667]=0;
+ a[1668]=0;
+ a[1669]=0;
+ a[1670]=0;
+ a[1671]=0;
+ a[1672]=0;
+ a[1673]=0;
+ a[1674]=0;
+ a[1675]=0;
+ a[1676]=0;
+ a[1677]=0;
+ a[1678]=0;
+ a[1679]=0;
+ a[1680]=0;
+ a[1681]=0;
+ a[1682]=0;
+ a[1683]=0;
+ a[1684]=0;
+ a[1685]=0;
+ a[1686]=0;
+ a[1687]=0;
+ a[1688]=0;
+ a[1689]=0;
+ a[1690]=0;
+ a[1691]=0;
+ a[1692]=0;
+ a[1693]=0;
+ a[1694]=0;
+ a[1695]=0;
+ a[1696]=0;
+ a[1697]=0;
+ a[1698]=0;
+ a[1699]=0;
+ a[1700]=0;
+ a[1701]=0;
+ a[1702]=0;
+ a[1703]=0;
+ a[1704]=0;
+ a[1705]=0;
+ a[1706]=0;
+ a[1707]=0;
+ a[1708]=0;
+ a[1709]=0;
+ a[1710]=0;
+ a[1711]=0;
+ a[1712]=0;
+ a[1713]=0;
+ a[1714]=0;
+ a[1715]=0;
+ a[1716]=0;
+ a[1717]=0;
+ a[1718]=0;
+ a[1719]=0;
+ a[1720]=0;
+ a[1721]=0;
+ a[1722]=0;
+ a[1723]=0;
+ a[1724]=0;
+ a[1725]=0;
+ a[1726]=0;
+ a[1727]=0;
+ a[1728]=0;
+ a[1729]=0;
+ a[1730]=0;
+ a[1731]=0;
+ a[1732]=0;
+ a[1733]=0;
+ a[1734]=0;
+ a[1735]=0;
+ a[1736]=0;
+ a[1737]=0;
+ a[1738]=0;
+ a[1739]=0;
+ a[1740]=0;
+ a[1741]=0;
+ a[1742]=0;
+ a[1743]=0;
+ a[1744]=0;
+ a[1745]=0;
+ a[1746]=0;
+ a[1747]=0;
+ a[1748]=0;
+ a[1749]=0;
+ a[1750]=0;
+ a[1751]=0;
+ a[1752]=0;
+ a[1753]=0;
+ a[1754]=0;
+ a[1755]=0;
+ a[1756]=0;
+ a[1757]=0;
+ a[1758]=0;
+ a[1759]=0;
+ a[1760]=0;
+ a[1761]=0;
+ a[1762]=0;
+ a[1763]=0;
+ a[1764]=0;
+ a[1765]=0;
+ a[1766]=0;
+ a[1767]=0;
+ a[1768]=0;
+ a[1769]=0;
+ a[1770]=0;
+ a[1771]=0;
+ a[1772]=0;
+ a[1773]=0;
+ a[1774]=0;
+ a[1775]=0;
+ a[1776]=0;
+ a[1777]=0;
+ a[1778]=0;
+ a[1779]=0;
+ a[1780]=0;
+ a[1781]=0;
+ a[1782]=0;
+ a[1783]=0;
+ a[1784]=0;
+ a[1785]=0;
+ a[1786]=0;
+ a[1787]=0;
+ a[1788]=0;
+ a[1789]=0;
+ a[1790]=0;
+ a[1791]=0;
+ a[1792]=0;
+ a[1793]=0;
+ a[1794]=0;
+ a[1795]=0;
+ a[1796]=0;
+ a[1797]=0;
+ a[1798]=0;
+ a[1799]=0;
+ a[1800]=0;
+ a[1801]=0;
+ a[1802]=0;
+ a[1803]=0;
+ a[1804]=0;
+ a[1805]=0;
+ a[1806]=0;
+ a[1807]=0;
+ a[1808]=0;
+ a[1809]=0;
+ a[1810]=0;
+ a[1811]=0;
+ a[1812]=0;
+ a[1813]=0;
+ a[1814]=0;
+ a[1815]=0;
+ a[1816]=0;
+ a[1817]=0;
+ a[1818]=0;
+ a[1819]=0;
+ a[1820]=0;
+ a[1821]=0;
+ a[1822]=0;
+ a[1823]=0;
+ a[1824]=0;
+ a[1825]=0;
+ a[1826]=0;
+ a[1827]=0;
+ a[1828]=0;
+ a[1829]=0;
+ a[1830]=0;
+ a[1831]=0;
+ a[1832]=0;
+ a[1833]=0;
+ a[1834]=0;
+ a[1835]=0;
+ a[1836]=0;
+ a[1837]=0;
+ a[1838]=0;
+ a[1839]=0;
+ a[1840]=0;
+ a[1841]=0;
+ a[1842]=0;
+ a[1843]=0;
+ a[1844]=0;
+ a[1845]=0;
+ a[1846]=0;
+ a[1847]=0;
+ a[1848]=0;
+ a[1849]=0;
+ a[1850]=0;
+ a[1851]=0;
+ a[1852]=0;
+ a[1853]=0;
+ a[1854]=0;
+ a[1855]=0;
+ a[1856]=0;
+ a[1857]=0;
+ a[1858]=0;
+ a[1859]=0;
+ a[1860]=0;
+ a[1861]=0;
+ a[1862]=0;
+ a[1863]=0;
+ a[1864]=0;
+ a[1865]=0;
+ a[1866]=0;
+ a[1867]=0;
+ a[1868]=0;
+ a[1869]=0;
+ a[1870]=0;
+ a[1871]=0;
+ a[1872]=0;
+ a[1873]=0;
+ a[1874]=0;
+ a[1875]=0;
+ a[1876]=0;
+ a[1877]=0;
+ a[1878]=0;
+ a[1879]=0;
+ a[1880]=0;
+ a[1881]=0;
+ a[1882]=0;
+ a[1883]=0;
+ a[1884]=0;
+ a[1885]=0;
+ a[1886]=0;
+ a[1887]=0;
+ a[1888]=0;
+ a[1889]=0;
+ a[1890]=0;
+ a[1891]=0;
+ a[1892]=0;
+ a[1893]=0;
+ a[1894]=0;
+ a[1895]=0;
+ a[1896]=0;
+ a[1897]=0;
+ a[1898]=0;
+ a[1899]=0;
+ a[1900]=0;
+ a[1901]=0;
+ a[1902]=0;
+ a[1903]=0;
+ a[1904]=0;
+ a[1905]=0;
+ a[1906]=0;
+ a[1907]=0;
+ a[1908]=0;
+ a[1909]=0;
+ a[1910]=0;
+ a[1911]=0;
+ a[1912]=0;
+ a[1913]=0;
+ a[1914]=0;
+ a[1915]=0;
+ a[1916]=0;
+ a[1917]=0;
+ a[1918]=0;
+ a[1919]=0;
+ a[1920]=0;
+ a[1921]=0;
+ a[1922]=0;
+ a[1923]=0;
+ a[1924]=0;
+ a[1925]=0;
+ a[1926]=0;
+ a[1927]=0;
+ a[1928]=0;
+ a[1929]=0;
+ a[1930]=0;
+ a[1931]=0;
+ a[1932]=0;
+ a[1933]=0;
+ a[1934]=0;
+ a[1935]=0;
+ a[1936]=0;
+ a[1937]=0;
+ a[1938]=0;
+ a[1939]=0;
+ a[1940]=0;
+ a[1941]=0;
+ a[1942]=0;
+ a[1943]=0;
+ a[1944]=0;
+ a[1945]=0;
+ a[1946]=0;
+ a[1947]=0;
+ a[1948]=0;
+ a[1949]=0;
+ a[1950]=0;
+ a[1951]=0;
+ a[1952]=0;
+ a[1953]=0;
+ a[1954]=0;
+ a[1955]=0;
+ a[1956]=0;
+ a[1957]=0;
+ a[1958]=0;
+ a[1959]=0;
+ a[1960]=0;
+ a[1961]=0;
+ a[1962]=0;
+ a[1963]=0;
+ a[1964]=0;
+ a[1965]=0;
+ a[1966]=0;
+ a[1967]=0;
+ a[1968]=0;
+ a[1969]=0;
+ a[1970]=0;
+ a[1971]=0;
+ a[1972]=0;
+ a[1973]=0;
+ a[1974]=0;
+ a[1975]=0;
+ a[1976]=0;
+ a[1977]=0;
+ a[1978]=0;
+ a[1979]=0;
+ a[1980]=0;
+ a[1981]=0;
+ a[1982]=0;
+ a[1983]=0;
+ a[1984]=0;
+ a[1985]=0;
+ a[1986]=0;
+ a[1987]=0;
+ a[1988]=0;
+ a[1989]=0;
+ a[1990]=0;
+ a[1991]=0;
+ a[1992]=0;
+ a[1993]=0;
+ a[1994]=0;
+ a[1995]=0;
+ a[1996]=0;
+ a[1997]=0;
+ a[1998]=0;
+ a[1999]=0;
+ a[2000]=0;
+ a[2001]=0;
+ a[2002]=0;
+ a[2003]=0;
+ a[2004]=0;
+ a[2005]=0;
+ a[2006]=0;
+ a[2007]=0;
+ a[2008]=0;
+ a[2009]=0;
+ a[2010]=0;
+ a[2011]=0;
+ a[2012]=0;
+ a[2013]=0;
+ a[2014]=0;
+ a[2015]=0;
+ a[2016]=0;
+ a[2017]=0;
+ a[2018]=0;
+ a[2019]=0;
+ a[2020]=0;
+ a[2021]=0;
+ a[2022]=0;
+ a[2023]=0;
+ a[2024]=0;
+ a[2025]=0;
+ a[2026]=0;
+ a[2027]=0;
+ a[2028]=0;
+ a[2029]=0;
+ a[2030]=0;
+ a[2031]=0;
+ a[2032]=0;
+ a[2033]=0;
+ a[2034]=0;
+ a[2035]=0;
+ a[2036]=0;
+ a[2037]=0;
+ a[2038]=0;
+ a[2039]=0;
+ a[2040]=0;
+ a[2041]=0;
+ a[2042]=0;
+ a[2043]=0;
+ a[2044]=0;
+ a[2045]=0;
+ a[2046]=0;
+ a[2047]=0;
+ a[2048]=0;
+ a[2049]=0;
+ a[2050]=0;
+ a[2051]=0;
+ a[2052]=0;
+ a[2053]=0;
+ a[2054]=0;
+ a[2055]=0;
+ a[2056]=0;
+ a[2057]=0;
+ a[2058]=0;
+ a[2059]=0;
+ a[2060]=0;
+ a[2061]=0;
+ a[2062]=0;
+ a[2063]=0;
+ a[2064]=0;
+ a[2065]=0;
+ a[2066]=0;
+ a[2067]=0;
+ a[2068]=0;
+ a[2069]=0;
+ a[2070]=0;
+ a[2071]=0;
+ a[2072]=0;
+ a[2073]=0;
+ a[2074]=0;
+ a[2075]=0;
+ a[2076]=0;
+ a[2077]=0;
+ a[2078]=0;
+ a[2079]=0;
+ a[2080]=0;
+ a[2081]=0;
+ a[2082]=0;
+ a[2083]=0;
+ a[2084]=0;
+ a[2085]=0;
+ a[2086]=0;
+ a[2087]=0;
+ a[2088]=0;
+ a[2089]=0;
+ a[2090]=0;
+ a[2091]=0;
+ a[2092]=0;
+ a[2093]=0;
+ a[2094]=0;
+ a[2095]=0;
+ a[2096]=0;
+ a[2097]=0;
+ a[2098]=0;
+ a[2099]=0;
+ a[2100]=0;
+ a[2101]=0;
+ a[2102]=0;
+ a[2103]=0;
+ a[2104]=0;
+ a[2105]=0;
+ a[2106]=0;
+ a[2107]=0;
+ a[2108]=0;
+ a[2109]=0;
+ a[2110]=0;
+ a[2111]=0;
+ a[2112]=0;
+ a[2113]=0;
+ a[2114]=0;
+ a[2115]=0;
+ a[2116]=0;
+ a[2117]=0;
+ a[2118]=0;
+ a[2119]=0;
+ a[2120]=0;
+ a[2121]=0;
+ a[2122]=0;
+ a[2123]=0;
+ a[2124]=0;
+ a[2125]=0;
+ a[2126]=0;
+ a[2127]=0;
+ a[2128]=0;
+ a[2129]=0;
+ a[2130]=0;
+ a[2131]=0;
+ a[2132]=0;
+ a[2133]=0;
+ a[2134]=0;
+ a[2135]=0;
+ a[2136]=0;
+ a[2137]=0;
+ a[2138]=0;
+ a[2139]=0;
+ a[2140]=0;
+ a[2141]=0;
+ a[2142]=0;
+ a[2143]=0;
+ a[2144]=0;
+ a[2145]=0;
+ a[2146]=0;
+ a[2147]=0;
+ a[2148]=0;
+ a[2149]=0;
+ a[2150]=0;
+ a[2151]=0;
+ a[2152]=0;
+ a[2153]=0;
+ a[2154]=0;
+ a[2155]=0;
+ a[2156]=0;
+ a[2157]=0;
+ a[2158]=0;
+ a[2159]=0;
+ a[2160]=0;
+ a[2161]=0;
+ a[2162]=0;
+ a[2163]=0;
+ a[2164]=0;
+ a[2165]=0;
+ a[2166]=0;
+ a[2167]=0;
+ a[2168]=0;
+ a[2169]=0;
+ a[2170]=0;
+ a[2171]=0;
+ a[2172]=0;
+ a[2173]=0;
+ a[2174]=0;
+ a[2175]=0;
+ a[2176]=0;
+ a[2177]=0;
+ a[2178]=0;
+ a[2179]=0;
+ a[2180]=0;
+ a[2181]=0;
+ a[2182]=0;
+ a[2183]=0;
+ a[2184]=0;
+ a[2185]=0;
+ a[2186]=0;
+ a[2187]=0;
+ a[2188]=0;
+ a[2189]=0;
+ a[2190]=0;
+ a[2191]=0;
+ a[2192]=0;
+ a[2193]=0;
+ a[2194]=0;
+ a[2195]=0;
+ a[2196]=0;
+ a[2197]=0;
+ a[2198]=0;
+ a[2199]=0;
+ a[2200]=0;
+ a[2201]=0;
+ a[2202]=0;
+ a[2203]=0;
+ a[2204]=0;
+ a[2205]=0;
+ a[2206]=0;
+ a[2207]=0;
+ a[2208]=0;
+ a[2209]=0;
+ a[2210]=0;
+ a[2211]=0;
+ a[2212]=0;
+ a[2213]=0;
+ a[2214]=0;
+ a[2215]=0;
+ a[2216]=0;
+ a[2217]=0;
+ a[2218]=0;
+ a[2219]=0;
+ a[2220]=0;
+ a[2221]=0;
+ a[2222]=0;
+ a[2223]=0;
+ a[2224]=0;
+ a[2225]=0;
+ a[2226]=0;
+ a[2227]=0;
+ a[2228]=0;
+ a[2229]=0;
+ a[2230]=0;
+ a[2231]=0;
+ a[2232]=0;
+ a[2233]=0;
+ a[2234]=0;
+ a[2235]=0;
+ a[2236]=0;
+ a[2237]=0;
+ a[2238]=0;
+ a[2239]=0;
+ a[2240]=0;
+ a[2241]=0;
+ a[2242]=0;
+ a[2243]=0;
+ a[2244]=0;
+ a[2245]=0;
+ a[2246]=0;
+ a[2247]=0;
+ a[2248]=0;
+ a[2249]=0;
+ a[2250]=0;
+ a[2251]=0;
+ a[2252]=0;
+ a[2253]=0;
+ a[2254]=0;
+ a[2255]=0;
+ a[2256]=0;
+ a[2257]=0;
+ a[2258]=0;
+ a[2259]=0;
+ a[2260]=0;
+ a[2261]=0;
+ a[2262]=0;
+ a[2263]=0;
+ a[2264]=0;
+ a[2265]=0;
+ a[2266]=0;
+ a[2267]=0;
+ a[2268]=0;
+ a[2269]=0;
+ a[2270]=0;
+ a[2271]=0;
+ a[2272]=0;
+ a[2273]=0;
+ a[2274]=0;
+ a[2275]=0;
+ a[2276]=0;
+ a[2277]=0;
+ a[2278]=0;
+ a[2279]=0;
+ a[2280]=0;
+ a[2281]=0;
+ a[2282]=0;
+ a[2283]=0;
+ a[2284]=0;
+ a[2285]=0;
+ a[2286]=0;
+ a[2287]=0;
+ a[2288]=0;
+ a[2289]=0;
+ a[2290]=0;
+ a[2291]=0;
+ a[2292]=0;
+ a[2293]=0;
+ a[2294]=0;
+ a[2295]=0;
+ a[2296]=0;
+ a[2297]=0;
+ a[2298]=0;
+ a[2299]=0;
+ a[2300]=0;
+ a[2301]=0;
+ a[2302]=0;
+ a[2303]=0;
+ a[2304]=0;
+ a[2305]=0;
+ a[2306]=0;
+ a[2307]=0;
+ a[2308]=0;
+ a[2309]=0;
+ a[2310]=0;
+ a[2311]=0;
+ a[2312]=0;
+ a[2313]=0;
+ a[2314]=0;
+ a[2315]=0;
+ a[2316]=0;
+ a[2317]=0;
+ a[2318]=0;
+ a[2319]=0;
+ a[2320]=0;
+ a[2321]=0;
+ a[2322]=0;
+ a[2323]=0;
+ a[2324]=0;
+ a[2325]=0;
+ a[2326]=0;
+ a[2327]=0;
+ a[2328]=0;
+ a[2329]=0;
+ a[2330]=0;
+ a[2331]=0;
+ a[2332]=0;
+ a[2333]=0;
+ a[2334]=0;
+ a[2335]=0;
+ a[2336]=0;
+ a[2337]=0;
+ a[2338]=0;
+ a[2339]=0;
+ a[2340]=0;
+ a[2341]=0;
+ a[2342]=0;
+ a[2343]=0;
+ a[2344]=0;
+ a[2345]=0;
+ a[2346]=0;
+ a[2347]=0;
+ a[2348]=0;
+ a[2349]=0;
+ a[2350]=0;
+ a[2351]=0;
+ a[2352]=0;
+ a[2353]=0;
+ a[2354]=0;
+ a[2355]=0;
+ a[2356]=0;
+ a[2357]=0;
+ a[2358]=0;
+ a[2359]=0;
+ a[2360]=0;
+ a[2361]=0;
+ a[2362]=0;
+ a[2363]=0;
+ a[2364]=0;
+ a[2365]=0;
+ a[2366]=0;
+ a[2367]=0;
+ a[2368]=0;
+ a[2369]=0;
+ a[2370]=0;
+ a[2371]=0;
+ a[2372]=0;
+ a[2373]=0;
+ a[2374]=0;
+ a[2375]=0;
+ a[2376]=0;
+ a[2377]=0;
+ a[2378]=0;
+ a[2379]=0;
+ a[2380]=0;
+ a[2381]=0;
+ a[2382]=0;
+ a[2383]=0;
+ a[2384]=0;
+ a[2385]=0;
+ a[2386]=0;
+ a[2387]=0;
+ a[2388]=0;
+ a[2389]=0;
+ a[2390]=0;
+ a[2391]=0;
+ a[2392]=0;
+ a[2393]=0;
+ a[2394]=0;
+ a[2395]=0;
+ a[2396]=0;
+ a[2397]=0;
+ a[2398]=0;
+ a[2399]=0;
+ a[2400]=0;
+ a[2401]=0;
+ a[2402]=0;
+ a[2403]=0;
+ a[2404]=0;
+ a[2405]=0;
+ a[2406]=0;
+ a[2407]=0;
+ a[2408]=0;
+ a[2409]=0;
+ a[2410]=0;
+ a[2411]=0;
+ a[2412]=0;
+ a[2413]=0;
+ a[2414]=0;
+ a[2415]=0;
+ a[2416]=0;
+ a[2417]=0;
+ a[2418]=0;
+ a[2419]=0;
+ a[2420]=0;
+ a[2421]=0;
+ a[2422]=0;
+ a[2423]=0;
+ a[2424]=0;
+ a[2425]=0;
+ a[2426]=0;
+ a[2427]=0;
+ a[2428]=0;
+ a[2429]=0;
+ a[2430]=0;
+ a[2431]=0;
+ a[2432]=0;
+ a[2433]=0;
+ a[2434]=0;
+ a[2435]=0;
+ a[2436]=0;
+ a[2437]=0;
+ a[2438]=0;
+ a[2439]=0;
+ a[2440]=0;
+ a[2441]=0;
+ a[2442]=0;
+ a[2443]=0;
+ a[2444]=0;
+ a[2445]=0;
+ a[2446]=0;
+ a[2447]=0;
+ a[2448]=0;
+ a[2449]=0;
+ a[2450]=0;
+ a[2451]=0;
+ a[2452]=0;
+ a[2453]=0;
+ a[2454]=0;
+ a[2455]=0;
+ a[2456]=0;
+ a[2457]=0;
+ a[2458]=0;
+ a[2459]=0;
+ a[2460]=0;
+ a[2461]=0;
+ a[2462]=0;
+ a[2463]=0;
+ a[2464]=0;
+ a[2465]=0;
+ a[2466]=0;
+ a[2467]=0;
+ a[2468]=0;
+ a[2469]=0;
+ a[2470]=0;
+ a[2471]=0;
+ a[2472]=0;
+ a[2473]=0;
+ a[2474]=0;
+ a[2475]=0;
+ a[2476]=0;
+ a[2477]=0;
+ a[2478]=0;
+ a[2479]=0;
+ a[2480]=0;
+ a[2481]=0;
+ a[2482]=0;
+ a[2483]=0;
+ a[2484]=0;
+ a[2485]=0;
+ a[2486]=0;
+ a[2487]=0;
+ a[2488]=0;
+ a[2489]=0;
+ a[2490]=0;
+ a[2491]=0;
+ a[2492]=0;
+ a[2493]=0;
+ a[2494]=0;
+ a[2495]=0;
+ a[2496]=0;
+ a[2497]=0;
+ a[2498]=0;
+ a[2499]=0;
+ a[2500]=0;
+ a[2501]=0;
+ a[2502]=0;
+ a[2503]=0;
+ a[2504]=0;
+ a[2505]=0;
+ a[2506]=0;
+ a[2507]=0;
+ a[2508]=0;
+ a[2509]=0;
+ a[2510]=0;
+ a[2511]=0;
+ a[2512]=0;
+ a[2513]=0;
+ a[2514]=0;
+ a[2515]=0;
+ a[2516]=0;
+ a[2517]=0;
+ a[2518]=0;
+ a[2519]=0;
+ a[2520]=0;
+ a[2521]=0;
+ a[2522]=0;
+ a[2523]=0;
+ a[2524]=0;
+ a[2525]=0;
+ a[2526]=0;
+ a[2527]=0;
+ a[2528]=0;
+ a[2529]=0;
+ a[2530]=0;
+ a[2531]=0;
+ a[2532]=0;
+ a[2533]=0;
+ a[2534]=0;
+ a[2535]=0;
+ a[2536]=0;
+ a[2537]=0;
+ a[2538]=0;
+ a[2539]=0;
+ a[2540]=0;
+ a[2541]=0;
+ a[2542]=0;
+ a[2543]=0;
+ a[2544]=0;
+ a[2545]=0;
+ a[2546]=0;
+ a[2547]=0;
+ a[2548]=0;
+ a[2549]=0;
+ a[2550]=0;
+ a[2551]=0;
+ a[2552]=0;
+ a[2553]=0;
+ a[2554]=0;
+ a[2555]=0;
+ a[2556]=0;
+ a[2557]=0;
+ a[2558]=0;
+ a[2559]=0;
+ a[2560]=0;
+ a[2561]=0;
+ a[2562]=0;
+ a[2563]=0;
+ a[2564]=0;
+ a[2565]=0;
+ a[2566]=0;
+ a[2567]=0;
+ a[2568]=0;
+ a[2569]=0;
+ a[2570]=0;
+ a[2571]=0;
+ a[2572]=0;
+ a[2573]=0;
+ a[2574]=0;
+ a[2575]=0;
+ a[2576]=0;
+ a[2577]=0;
+ a[2578]=0;
+ a[2579]=0;
+ a[2580]=0;
+ a[2581]=0;
+ a[2582]=0;
+ a[2583]=0;
+ a[2584]=0;
+ a[2585]=0;
+ a[2586]=0;
+ a[2587]=0;
+ a[2588]=0;
+ a[2589]=0;
+ a[2590]=0;
+ a[2591]=0;
+ a[2592]=0;
+ a[2593]=0;
+ a[2594]=0;
+ a[2595]=0;
+ a[2596]=0;
+ a[2597]=0;
+ a[2598]=0;
+ a[2599]=0;
+ a[2600]=0;
+ a[2601]=0;
+ a[2602]=0;
+ a[2603]=0;
+ a[2604]=0;
+ a[2605]=0;
+ a[2606]=0;
+ a[2607]=0;
+ a[2608]=0;
+ a[2609]=0;
+ a[2610]=0;
+ a[2611]=0;
+ a[2612]=0;
+ a[2613]=0;
+ a[2614]=0;
+ a[2615]=0;
+ a[2616]=0;
+ a[2617]=0;
+ a[2618]=0;
+ a[2619]=0;
+ a[2620]=0;
+ a[2621]=0;
+ a[2622]=0;
+ a[2623]=0;
+ a[2624]=0;
+ a[2625]=0;
+ a[2626]=0;
+ a[2627]=0;
+ a[2628]=0;
+ a[2629]=0;
+ a[2630]=0;
+ a[2631]=0;
+ a[2632]=0;
+ a[2633]=0;
+ a[2634]=0;
+ a[2635]=0;
+ a[2636]=0;
+ a[2637]=0;
+ a[2638]=0;
+ a[2639]=0;
+ a[2640]=0;
+ a[2641]=0;
+ a[2642]=0;
+ a[2643]=0;
+ a[2644]=0;
+ a[2645]=0;
+ a[2646]=0;
+ a[2647]=0;
+ a[2648]=0;
+ a[2649]=0;
+ a[2650]=0;
+ a[2651]=0;
+ a[2652]=0;
+ a[2653]=0;
+ a[2654]=0;
+ a[2655]=0;
+ a[2656]=0;
+ a[2657]=0;
+ a[2658]=0;
+ a[2659]=0;
+ a[2660]=0;
+ a[2661]=0;
+ a[2662]=0;
+ a[2663]=0;
+ a[2664]=0;
+ a[2665]=0;
+ a[2666]=0;
+ a[2667]=0;
+ a[2668]=0;
+ a[2669]=0;
+ a[2670]=0;
+ a[2671]=0;
+ a[2672]=0;
+ a[2673]=0;
+ a[2674]=0;
+ a[2675]=0;
+ a[2676]=0;
+ a[2677]=0;
+ a[2678]=0;
+ a[2679]=0;
+ a[2680]=0;
+ a[2681]=0;
+ a[2682]=0;
+ a[2683]=0;
+ a[2684]=0;
+ a[2685]=0;
+ a[2686]=0;
+ a[2687]=0;
+ a[2688]=0;
+ a[2689]=0;
+ a[2690]=0;
+ a[2691]=0;
+ a[2692]=0;
+ a[2693]=0;
+ a[2694]=0;
+ a[2695]=0;
+ a[2696]=0;
+ a[2697]=0;
+ a[2698]=0;
+ a[2699]=0;
+ a[2700]=0;
+ a[2701]=0;
+ a[2702]=0;
+ a[2703]=0;
+ a[2704]=0;
+ a[2705]=0;
+ a[2706]=0;
+ a[2707]=0;
+ a[2708]=0;
+ a[2709]=0;
+ a[2710]=0;
+ a[2711]=0;
+ a[2712]=0;
+ a[2713]=0;
+ a[2714]=0;
+ a[2715]=0;
+ a[2716]=0;
+ a[2717]=0;
+ a[2718]=0;
+ a[2719]=0;
+ a[2720]=0;
+ a[2721]=0;
+ a[2722]=0;
+ a[2723]=0;
+ a[2724]=0;
+ a[2725]=0;
+ a[2726]=0;
+ a[2727]=0;
+ a[2728]=0;
+ a[2729]=0;
+ a[2730]=0;
+ a[2731]=0;
+ a[2732]=0;
+ a[2733]=0;
+ a[2734]=0;
+ a[2735]=0;
+ a[2736]=0;
+ a[2737]=0;
+ a[2738]=0;
+ a[2739]=0;
+ a[2740]=0;
+ a[2741]=0;
+ a[2742]=0;
+ a[2743]=0;
+ a[2744]=0;
+ a[2745]=0;
+ a[2746]=0;
+ a[2747]=0;
+ a[2748]=0;
+ a[2749]=0;
+ a[2750]=0;
+ a[2751]=0;
+ a[2752]=0;
+ a[2753]=0;
+ a[2754]=0;
+ a[2755]=0;
+ a[2756]=0;
+ a[2757]=0;
+ a[2758]=0;
+ a[2759]=0;
+ a[2760]=0;
+ a[2761]=0;
+ a[2762]=0;
+ a[2763]=0;
+ a[2764]=0;
+ a[2765]=0;
+ a[2766]=0;
+ a[2767]=0;
+ a[2768]=0;
+ a[2769]=0;
+ a[2770]=0;
+ a[2771]=0;
+ a[2772]=0;
+ a[2773]=0;
+ a[2774]=0;
+ a[2775]=0;
+ a[2776]=0;
+ a[2777]=0;
+ a[2778]=0;
+ a[2779]=0;
+ a[2780]=0;
+ a[2781]=0;
+ a[2782]=0;
+ a[2783]=0;
+ a[2784]=0;
+ a[2785]=0;
+ a[2786]=0;
+ a[2787]=0;
+ a[2788]=0;
+ a[2789]=0;
+ a[2790]=0;
+ a[2791]=0;
+ a[2792]=0;
+ a[2793]=0;
+ a[2794]=0;
+ a[2795]=0;
+ a[2796]=0;
+ a[2797]=0;
+ a[2798]=0;
+ a[2799]=0;
+ a[2800]=0;
+ a[2801]=0;
+ a[2802]=0;
+ a[2803]=0;
+ a[2804]=0;
+ a[2805]=0;
+ a[2806]=0;
+ a[2807]=0;
+ a[2808]=0;
+ a[2809]=0;
+ a[2810]=0;
+ a[2811]=0;
+ a[2812]=0;
+ a[2813]=0;
+ a[2814]=0;
+ a[2815]=0;
+ a[2816]=0;
+ a[2817]=0;
+ a[2818]=0;
+ a[2819]=0;
+ a[2820]=0;
+ a[2821]=0;
+ a[2822]=0;
+ a[2823]=0;
+ a[2824]=0;
+ a[2825]=0;
+ a[2826]=0;
+ a[2827]=0;
+ a[2828]=0;
+ a[2829]=0;
+ a[2830]=0;
+ a[2831]=0;
+ a[2832]=0;
+ a[2833]=0;
+ a[2834]=0;
+ a[2835]=0;
+ a[2836]=0;
+ a[2837]=0;
+ a[2838]=0;
+ a[2839]=0;
+ a[2840]=0;
+ a[2841]=0;
+ a[2842]=0;
+ a[2843]=0;
+ a[2844]=0;
+ a[2845]=0;
+ a[2846]=0;
+ a[2847]=0;
+ a[2848]=0;
+ a[2849]=0;
+ a[2850]=0;
+ a[2851]=0;
+ a[2852]=0;
+ a[2853]=0;
+ a[2854]=0;
+ a[2855]=0;
+ a[2856]=0;
+ a[2857]=0;
+ a[2858]=0;
+ a[2859]=0;
+ a[2860]=0;
+ a[2861]=0;
+ a[2862]=0;
+ a[2863]=0;
+ a[2864]=0;
+ a[2865]=0;
+ a[2866]=0;
+ a[2867]=0;
+ a[2868]=0;
+ a[2869]=0;
+ a[2870]=0;
+ a[2871]=0;
+ a[2872]=0;
+ a[2873]=0;
+ a[2874]=0;
+ a[2875]=0;
+ a[2876]=0;
+ a[2877]=0;
+ a[2878]=0;
+ a[2879]=0;
+ a[2880]=0;
+ a[2881]=0;
+ a[2882]=0;
+ a[2883]=0;
+ a[2884]=0;
+ a[2885]=0;
+ a[2886]=0;
+ a[2887]=0;
+ a[2888]=0;
+ a[2889]=0;
+ a[2890]=0;
+ a[2891]=0;
+ a[2892]=0;
+ a[2893]=0;
+ a[2894]=0;
+ a[2895]=0;
+ a[2896]=0;
+ a[2897]=0;
+ a[2898]=0;
+ a[2899]=0;
+ a[2900]=0;
+ a[2901]=0;
+ a[2902]=0;
+ a[2903]=0;
+ a[2904]=0;
+ a[2905]=0;
+ a[2906]=0;
+ a[2907]=0;
+ a[2908]=0;
+ a[2909]=0;
+ a[2910]=0;
+ a[2911]=0;
+ a[2912]=0;
+ a[2913]=0;
+ a[2914]=0;
+ a[2915]=0;
+ a[2916]=0;
+ a[2917]=0;
+ a[2918]=0;
+ a[2919]=0;
+ a[2920]=0;
+ a[2921]=0;
+ a[2922]=0;
+ a[2923]=0;
+ a[2924]=0;
+ a[2925]=0;
+ a[2926]=0;
+ a[2927]=0;
+ a[2928]=0;
+ a[2929]=0;
+ a[2930]=0;
+ a[2931]=0;
+ a[2932]=0;
+ a[2933]=0;
+ a[2934]=0;
+ a[2935]=0;
+ a[2936]=0;
+ a[2937]=0;
+ a[2938]=0;
+ a[2939]=0;
+ a[2940]=0;
+ a[2941]=0;
+ a[2942]=0;
+ a[2943]=0;
+ a[2944]=0;
+ a[2945]=0;
+ a[2946]=0;
+ a[2947]=0;
+ a[2948]=0;
+ a[2949]=0;
+ a[2950]=0;
+ a[2951]=0;
+ a[2952]=0;
+ a[2953]=0;
+ a[2954]=0;
+ a[2955]=0;
+ a[2956]=0;
+ a[2957]=0;
+ a[2958]=0;
+ a[2959]=0;
+ a[2960]=0;
+ a[2961]=0;
+ a[2962]=0;
+ a[2963]=0;
+ a[2964]=0;
+ a[2965]=0;
+ a[2966]=0;
+ a[2967]=0;
+ a[2968]=0;
+ a[2969]=0;
+ a[2970]=0;
+ a[2971]=0;
+ a[2972]=0;
+ a[2973]=0;
+ a[2974]=0;
+ a[2975]=0;
+ a[2976]=0;
+ a[2977]=0;
+ a[2978]=0;
+ a[2979]=0;
+ a[2980]=0;
+ a[2981]=0;
+ a[2982]=0;
+ a[2983]=0;
+ a[2984]=0;
+ a[2985]=0;
+ a[2986]=0;
+ a[2987]=0;
+ a[2988]=0;
+ a[2989]=0;
+ a[2990]=0;
+ a[2991]=0;
+ a[2992]=0;
+ a[2993]=0;
+ a[2994]=0;
+ a[2995]=0;
+ a[2996]=0;
+ a[2997]=0;
+ a[2998]=0;
+ a[2999]=0;
+ a[3000]=0;
+ a[3001]=0;
+ a[3002]=0;
+ a[3003]=0;
+ a[3004]=0;
+ a[3005]=0;
+ a[3006]=0;
+ a[3007]=0;
+ a[3008]=0;
+ a[3009]=0;
+ a[3010]=0;
+ a[3011]=0;
+ a[3012]=0;
+ a[3013]=0;
+ a[3014]=0;
+ a[3015]=0;
+ a[3016]=0;
+ a[3017]=0;
+ a[3018]=0;
+ a[3019]=0;
+ a[3020]=0;
+ a[3021]=0;
+ a[3022]=0;
+ a[3023]=0;
+ a[3024]=0;
+ a[3025]=0;
+ a[3026]=0;
+ a[3027]=0;
+ a[3028]=0;
+ a[3029]=0;
+ a[3030]=0;
+ a[3031]=0;
+ a[3032]=0;
+ a[3033]=0;
+ a[3034]=0;
+ a[3035]=0;
+ a[3036]=0;
+ a[3037]=0;
+ a[3038]=0;
+ a[3039]=0;
+ a[3040]=0;
+ a[3041]=0;
+ a[3042]=0;
+ a[3043]=0;
+ a[3044]=0;
+ a[3045]=0;
+ a[3046]=0;
+ a[3047]=0;
+ a[3048]=0;
+ a[3049]=0;
+ a[3050]=0;
+ a[3051]=0;
+ a[3052]=0;
+ a[3053]=0;
+ a[3054]=0;
+ a[3055]=0;
+ a[3056]=0;
+ a[3057]=0;
+ a[3058]=0;
+ a[3059]=0;
+ a[3060]=0;
+ a[3061]=0;
+ a[3062]=0;
+ a[3063]=0;
+ a[3064]=0;
+ a[3065]=0;
+ a[3066]=0;
+ a[3067]=0;
+ a[3068]=0;
+ a[3069]=0;
+ a[3070]=0;
+ a[3071]=0;
+ a[3072]=0;
+ a[3073]=0;
+ a[3074]=0;
+ a[3075]=0;
+ a[3076]=0;
+ a[3077]=0;
+ a[3078]=0;
+ a[3079]=0;
+ a[3080]=0;
+ a[3081]=0;
+ a[3082]=0;
+ a[3083]=0;
+ a[3084]=0;
+ a[3085]=0;
+ a[3086]=0;
+ a[3087]=0;
+ a[3088]=0;
+ a[3089]=0;
+ a[3090]=0;
+ a[3091]=0;
+ a[3092]=0;
+ a[3093]=0;
+ a[3094]=0;
+ a[3095]=0;
+ a[3096]=0;
+ a[3097]=0;
+ a[3098]=0;
+ a[3099]=0;
+ a[3100]=0;
+ a[3101]=0;
+ a[3102]=0;
+ a[3103]=0;
+ a[3104]=0;
+ a[3105]=0;
+ a[3106]=0;
+ a[3107]=0;
+ a[3108]=0;
+ a[3109]=0;
+ a[3110]=0;
+ a[3111]=0;
+ a[3112]=0;
+ a[3113]=0;
+ a[3114]=0;
+ a[3115]=0;
+ a[3116]=0;
+ a[3117]=0;
+ a[3118]=0;
+ a[3119]=0;
+ a[3120]=0;
+ a[3121]=0;
+ a[3122]=0;
+ a[3123]=0;
+ a[3124]=0;
+ a[3125]=0;
+ a[3126]=0;
+ a[3127]=0;
+ a[3128]=0;
+ a[3129]=0;
+ a[3130]=0;
+ a[3131]=0;
+ a[3132]=0;
+ a[3133]=0;
+ a[3134]=0;
+ a[3135]=0;
+ a[3136]=0;
+ a[3137]=0;
+ a[3138]=0;
+ a[3139]=0;
+ a[3140]=0;
+ a[3141]=0;
+ a[3142]=0;
+ a[3143]=0;
+ a[3144]=0;
+ a[3145]=0;
+ a[3146]=0;
+ a[3147]=0;
+ a[3148]=0;
+ a[3149]=0;
+ a[3150]=0;
+ a[3151]=0;
+ a[3152]=0;
+ a[3153]=0;
+ a[3154]=0;
+ a[3155]=0;
+ a[3156]=0;
+ a[3157]=0;
+ a[3158]=0;
+ a[3159]=0;
+ a[3160]=0;
+ a[3161]=0;
+ a[3162]=0;
+ a[3163]=0;
+ a[3164]=0;
+ a[3165]=0;
+ a[3166]=0;
+ a[3167]=0;
+ a[3168]=0;
+ a[3169]=0;
+ a[3170]=0;
+ a[3171]=0;
+ a[3172]=0;
+ a[3173]=0;
+ a[3174]=0;
+ a[3175]=0;
+ a[3176]=0;
+ a[3177]=0;
+ a[3178]=0;
+ a[3179]=0;
+ a[3180]=0;
+ a[3181]=0;
+ a[3182]=0;
+ a[3183]=0;
+ a[3184]=0;
+ a[3185]=0;
+ a[3186]=0;
+ a[3187]=0;
+ a[3188]=0;
+ a[3189]=0;
+ a[3190]=0;
+ a[3191]=0;
+ a[3192]=0;
+ a[3193]=0;
+ a[3194]=0;
+ a[3195]=0;
+ a[3196]=0;
+ a[3197]=0;
+ a[3198]=0;
+ a[3199]=0;
+ a[3200]=0;
+ a[3201]=0;
+ a[3202]=0;
+ a[3203]=0;
+ a[3204]=0;
+ a[3205]=0;
+ a[3206]=0;
+ a[3207]=0;
+ a[3208]=0;
+ a[3209]=0;
+ a[3210]=0;
+ a[3211]=0;
+ a[3212]=0;
+ a[3213]=0;
+ a[3214]=0;
+ a[3215]=0;
+ a[3216]=0;
+ a[3217]=0;
+ a[3218]=0;
+ a[3219]=0;
+ a[3220]=0;
+ a[3221]=0;
+ a[3222]=0;
+ a[3223]=0;
+ a[3224]=0;
+ a[3225]=0;
+ a[3226]=0;
+ a[3227]=0;
+ a[3228]=0;
+ a[3229]=0;
+ a[3230]=0;
+ a[3231]=0;
+ a[3232]=0;
+ a[3233]=0;
+ a[3234]=0;
+ a[3235]=0;
+ a[3236]=0;
+ a[3237]=0;
+ a[3238]=0;
+ a[3239]=0;
+ a[3240]=0;
+ a[3241]=0;
+ a[3242]=0;
+ a[3243]=0;
+ a[3244]=0;
+ a[3245]=0;
+ a[3246]=0;
+ a[3247]=0;
+ a[3248]=0;
+ a[3249]=0;
+ a[3250]=0;
+ a[3251]=0;
+ a[3252]=0;
+ a[3253]=0;
+ a[3254]=0;
+ a[3255]=0;
+ a[3256]=0;
+ a[3257]=0;
+ a[3258]=0;
+ a[3259]=0;
+ a[3260]=0;
+ a[3261]=0;
+ a[3262]=0;
+ a[3263]=0;
+ a[3264]=0;
+ a[3265]=0;
+ a[3266]=0;
+ a[3267]=0;
+ a[3268]=0;
+ a[3269]=0;
+ a[3270]=0;
+ a[3271]=0;
+ a[3272]=0;
+ a[3273]=0;
+ a[3274]=0;
+ a[3275]=0;
+ a[3276]=0;
+ a[3277]=0;
+ a[3278]=0;
+ a[3279]=0;
+ a[3280]=0;
+ a[3281]=0;
+ a[3282]=0;
+ a[3283]=0;
+ a[3284]=0;
+ a[3285]=0;
+ a[3286]=0;
+ a[3287]=0;
+ a[3288]=0;
+ a[3289]=0;
+ a[3290]=0;
+ a[3291]=0;
+ a[3292]=0;
+ a[3293]=0;
+ a[3294]=0;
+ a[3295]=0;
+ a[3296]=0;
+ a[3297]=0;
+ a[3298]=0;
+ a[3299]=0;
+ a[3300]=0;
+ a[3301]=0;
+ a[3302]=0;
+ a[3303]=0;
+ a[3304]=0;
+ a[3305]=0;
+ a[3306]=0;
+ a[3307]=0;
+ a[3308]=0;
+ a[3309]=0;
+ a[3310]=0;
+ a[3311]=0;
+ a[3312]=0;
+ a[3313]=0;
+ a[3314]=0;
+ a[3315]=0;
+ a[3316]=0;
+ a[3317]=0;
+ a[3318]=0;
+ a[3319]=0;
+ a[3320]=0;
+ a[3321]=0;
+ a[3322]=0;
+ a[3323]=0;
+ a[3324]=0;
+ a[3325]=0;
+ a[3326]=0;
+ a[3327]=0;
+ a[3328]=0;
+ a[3329]=0;
+ a[3330]=0;
+ a[3331]=0;
+ a[3332]=0;
+ a[3333]=0;
+ a[3334]=0;
+ a[3335]=0;
+ a[3336]=0;
+ a[3337]=0;
+ a[3338]=0;
+ a[3339]=0;
+ a[3340]=0;
+ a[3341]=0;
+ a[3342]=0;
+ a[3343]=0;
+ a[3344]=0;
+ a[3345]=0;
+ a[3346]=0;
+ a[3347]=0;
+ a[3348]=0;
+ a[3349]=0;
+ a[3350]=0;
+ a[3351]=0;
+ a[3352]=0;
+ a[3353]=0;
+ a[3354]=0;
+ a[3355]=0;
+ a[3356]=0;
+ a[3357]=0;
+ a[3358]=0;
+ a[3359]=0;
+ a[3360]=0;
+ a[3361]=0;
+ a[3362]=0;
+ a[3363]=0;
+ a[3364]=0;
+ a[3365]=0;
+ a[3366]=0;
+ a[3367]=0;
+ a[3368]=0;
+ a[3369]=0;
+ a[3370]=0;
+ a[3371]=0;
+ a[3372]=0;
+ a[3373]=0;
+ a[3374]=0;
+ a[3375]=0;
+ a[3376]=0;
+ a[3377]=0;
+ a[3378]=0;
+ a[3379]=0;
+ a[3380]=0;
+ a[3381]=0;
+ a[3382]=0;
+ a[3383]=0;
+ a[3384]=0;
+ a[3385]=0;
+ a[3386]=0;
+ a[3387]=0;
+ a[3388]=0;
+ a[3389]=0;
+ a[3390]=0;
+ a[3391]=0;
+ a[3392]=0;
+ a[3393]=0;
+ a[3394]=0;
+ a[3395]=0;
+ a[3396]=0;
+ a[3397]=0;
+ a[3398]=0;
+ a[3399]=0;
+ a[3400]=0;
+ a[3401]=0;
+ a[3402]=0;
+ a[3403]=0;
+ a[3404]=0;
+ a[3405]=0;
+ a[3406]=0;
+ a[3407]=0;
+ a[3408]=0;
+ a[3409]=0;
+ a[3410]=0;
+ a[3411]=0;
+ a[3412]=0;
+ a[3413]=0;
+ a[3414]=0;
+ a[3415]=0;
+ a[3416]=0;
+ a[3417]=0;
+ a[3418]=0;
+ a[3419]=0;
+ a[3420]=0;
+ a[3421]=0;
+ a[3422]=0;
+ a[3423]=0;
+ a[3424]=0;
+ a[3425]=0;
+ a[3426]=0;
+ a[3427]=0;
+ a[3428]=0;
+ a[3429]=0;
+ a[3430]=0;
+ a[3431]=0;
+ a[3432]=0;
+ a[3433]=0;
+ a[3434]=0;
+ a[3435]=0;
+ a[3436]=0;
+ a[3437]=0;
+ a[3438]=0;
+ a[3439]=0;
+ a[3440]=0;
+ a[3441]=0;
+ a[3442]=0;
+ a[3443]=0;
+ a[3444]=0;
+ a[3445]=0;
+ a[3446]=0;
+ a[3447]=0;
+ a[3448]=0;
+ a[3449]=0;
+ a[3450]=0;
+ a[3451]=0;
+ a[3452]=0;
+ a[3453]=0;
+ a[3454]=0;
+ a[3455]=0;
+ a[3456]=0;
+ a[3457]=0;
+ a[3458]=0;
+ a[3459]=0;
+ a[3460]=0;
+ a[3461]=0;
+ a[3462]=0;
+ a[3463]=0;
+ a[3464]=0;
+ a[3465]=0;
+ a[3466]=0;
+ a[3467]=0;
+ a[3468]=0;
+ a[3469]=0;
+ a[3470]=0;
+ a[3471]=0;
+ a[3472]=0;
+ a[3473]=0;
+ a[3474]=0;
+ a[3475]=0;
+ a[3476]=0;
+ a[3477]=0;
+ a[3478]=0;
+ a[3479]=0;
+ a[3480]=0;
+ a[3481]=0;
+ a[3482]=0;
+ a[3483]=0;
+ a[3484]=0;
+ a[3485]=0;
+ a[3486]=0;
+ a[3487]=0;
+ a[3488]=0;
+ a[3489]=0;
+ a[3490]=0;
+ a[3491]=0;
+ a[3492]=0;
+ a[3493]=0;
+ a[3494]=0;
+ a[3495]=0;
+ a[3496]=0;
+ a[3497]=0;
+ a[3498]=0;
+ a[3499]=0;
+ a[3500]=0;
+ a[3501]=0;
+ a[3502]=0;
+ a[3503]=0;
+ a[3504]=0;
+ a[3505]=0;
+ a[3506]=0;
+ a[3507]=0;
+ a[3508]=0;
+ a[3509]=0;
+ a[3510]=0;
+ a[3511]=0;
+ a[3512]=0;
+ a[3513]=0;
+ a[3514]=0;
+ a[3515]=0;
+ a[3516]=0;
+ a[3517]=0;
+ a[3518]=0;
+ a[3519]=0;
+ a[3520]=0;
+ a[3521]=0;
+ a[3522]=0;
+ a[3523]=0;
+ a[3524]=0;
+ a[3525]=0;
+ a[3526]=0;
+ a[3527]=0;
+ a[3528]=0;
+ a[3529]=0;
+ a[3530]=0;
+ a[3531]=0;
+ a[3532]=0;
+ a[3533]=0;
+ a[3534]=0;
+ a[3535]=0;
+ a[3536]=0;
+ a[3537]=0;
+ a[3538]=0;
+ a[3539]=0;
+ a[3540]=0;
+ a[3541]=0;
+ a[3542]=0;
+ a[3543]=0;
+ a[3544]=0;
+ a[3545]=0;
+ a[3546]=0;
+ a[3547]=0;
+ a[3548]=0;
+ a[3549]=0;
+ a[3550]=0;
+ a[3551]=0;
+ a[3552]=0;
+ a[3553]=0;
+ a[3554]=0;
+ a[3555]=0;
+ a[3556]=0;
+ a[3557]=0;
+ a[3558]=0;
+ a[3559]=0;
+ a[3560]=0;
+ a[3561]=0;
+ a[3562]=0;
+ a[3563]=0;
+ a[3564]=0;
+ a[3565]=0;
+ a[3566]=0;
+ a[3567]=0;
+ a[3568]=0;
+ a[3569]=0;
+ a[3570]=0;
+ a[3571]=0;
+ a[3572]=0;
+ a[3573]=0;
+ a[3574]=0;
+ a[3575]=0;
+ a[3576]=0;
+ a[3577]=0;
+ a[3578]=0;
+ a[3579]=0;
+ a[3580]=0;
+ a[3581]=0;
+ a[3582]=0;
+ a[3583]=0;
+ a[3584]=0;
+ a[3585]=0;
+ a[3586]=0;
+ a[3587]=0;
+ a[3588]=0;
+ a[3589]=0;
+ a[3590]=0;
+ a[3591]=0;
+ a[3592]=0;
+ a[3593]=0;
+ a[3594]=0;
+ a[3595]=0;
+ a[3596]=0;
+ a[3597]=0;
+ a[3598]=0;
+ a[3599]=0;
+ a[3600]=0;
+ a[3601]=0;
+ a[3602]=0;
+ a[3603]=0;
+ a[3604]=0;
+ a[3605]=0;
+ a[3606]=0;
+ a[3607]=0;
+ a[3608]=0;
+ a[3609]=0;
+ a[3610]=0;
+ a[3611]=0;
+ a[3612]=0;
+ a[3613]=0;
+ a[3614]=0;
+ a[3615]=0;
+ a[3616]=0;
+ a[3617]=0;
+ a[3618]=0;
+ a[3619]=0;
+ a[3620]=0;
+ a[3621]=0;
+ a[3622]=0;
+ a[3623]=0;
+ a[3624]=0;
+ a[3625]=0;
+ a[3626]=0;
+ a[3627]=0;
+ a[3628]=0;
+ a[3629]=0;
+ a[3630]=0;
+ a[3631]=0;
+ a[3632]=0;
+ a[3633]=0;
+ a[3634]=0;
+ a[3635]=0;
+ a[3636]=0;
+ a[3637]=0;
+ a[3638]=0;
+ a[3639]=0;
+ a[3640]=0;
+ a[3641]=0;
+ a[3642]=0;
+ a[3643]=0;
+ a[3644]=0;
+ a[3645]=0;
+ a[3646]=0;
+ a[3647]=0;
+ a[3648]=0;
+ a[3649]=0;
+ a[3650]=0;
+ a[3651]=0;
+ a[3652]=0;
+ a[3653]=0;
+ a[3654]=0;
+ a[3655]=0;
+ a[3656]=0;
+ a[3657]=0;
+ a[3658]=0;
+ a[3659]=0;
+ a[3660]=0;
+ a[3661]=0;
+ a[3662]=0;
+ a[3663]=0;
+ a[3664]=0;
+ a[3665]=0;
+ a[3666]=0;
+ a[3667]=0;
+ a[3668]=0;
+ a[3669]=0;
+ a[3670]=0;
+ a[3671]=0;
+ a[3672]=0;
+ a[3673]=0;
+ a[3674]=0;
+ a[3675]=0;
+ a[3676]=0;
+ a[3677]=0;
+ a[3678]=0;
+ a[3679]=0;
+ a[3680]=0;
+ a[3681]=0;
+ a[3682]=0;
+ a[3683]=0;
+ a[3684]=0;
+ a[3685]=0;
+ a[3686]=0;
+ a[3687]=0;
+ a[3688]=0;
+ a[3689]=0;
+ a[3690]=0;
+ a[3691]=0;
+ a[3692]=0;
+ a[3693]=0;
+ a[3694]=0;
+ a[3695]=0;
+ a[3696]=0;
+ a[3697]=0;
+ a[3698]=0;
+ a[3699]=0;
+ a[3700]=0;
+ a[3701]=0;
+ a[3702]=0;
+ a[3703]=0;
+ a[3704]=0;
+ a[3705]=0;
+ a[3706]=0;
+ a[3707]=0;
+ a[3708]=0;
+ a[3709]=0;
+ a[3710]=0;
+ a[3711]=0;
+ a[3712]=0;
+ a[3713]=0;
+ a[3714]=0;
+ a[3715]=0;
+ a[3716]=0;
+ a[3717]=0;
+ a[3718]=0;
+ a[3719]=0;
+ a[3720]=0;
+ a[3721]=0;
+ a[3722]=0;
+ a[3723]=0;
+ a[3724]=0;
+ a[3725]=0;
+ a[3726]=0;
+ a[3727]=0;
+ a[3728]=0;
+ a[3729]=0;
+ a[3730]=0;
+ a[3731]=0;
+ a[3732]=0;
+ a[3733]=0;
+ a[3734]=0;
+ a[3735]=0;
+ a[3736]=0;
+ a[3737]=0;
+ a[3738]=0;
+ a[3739]=0;
+ a[3740]=0;
+ a[3741]=0;
+ a[3742]=0;
+ a[3743]=0;
+ a[3744]=0;
+ a[3745]=0;
+ a[3746]=0;
+ a[3747]=0;
+ a[3748]=0;
+ a[3749]=0;
+ a[3750]=0;
+ a[3751]=0;
+ a[3752]=0;
+ a[3753]=0;
+ a[3754]=0;
+ a[3755]=0;
+ a[3756]=0;
+ a[3757]=0;
+ a[3758]=0;
+ a[3759]=0;
+ a[3760]=0;
+ a[3761]=0;
+ a[3762]=0;
+ a[3763]=0;
+ a[3764]=0;
+ a[3765]=0;
+ a[3766]=0;
+ a[3767]=0;
+ a[3768]=0;
+ a[3769]=0;
+ a[3770]=0;
+ a[3771]=0;
+ a[3772]=0;
+ a[3773]=0;
+ a[3774]=0;
+ a[3775]=0;
+ a[3776]=0;
+ a[3777]=0;
+ a[3778]=0;
+ a[3779]=0;
+ a[3780]=0;
+ a[3781]=0;
+ a[3782]=0;
+ a[3783]=0;
+ a[3784]=0;
+ a[3785]=0;
+ a[3786]=0;
+ a[3787]=0;
+ a[3788]=0;
+ a[3789]=0;
+ a[3790]=0;
+ a[3791]=0;
+ a[3792]=0;
+ a[3793]=0;
+ a[3794]=0;
+ a[3795]=0;
+ a[3796]=0;
+ a[3797]=0;
+ a[3798]=0;
+ a[3799]=0;
+ a[3800]=0;
+ a[3801]=0;
+ a[3802]=0;
+ a[3803]=0;
+ a[3804]=0;
+ a[3805]=0;
+ a[3806]=0;
+ a[3807]=0;
+ a[3808]=0;
+ a[3809]=0;
+ a[3810]=0;
+ a[3811]=0;
+ a[3812]=0;
+ a[3813]=0;
+ a[3814]=0;
+ a[3815]=0;
+ a[3816]=0;
+ a[3817]=0;
+ a[3818]=0;
+ a[3819]=0;
+ a[3820]=0;
+ a[3821]=0;
+ a[3822]=0;
+ a[3823]=0;
+ a[3824]=0;
+ a[3825]=0;
+ a[3826]=0;
+ a[3827]=0;
+ a[3828]=0;
+ a[3829]=0;
+ a[3830]=0;
+ a[3831]=0;
+ a[3832]=0;
+ a[3833]=0;
+ a[3834]=0;
+ a[3835]=0;
+ a[3836]=0;
+ a[3837]=0;
+ a[3838]=0;
+ a[3839]=0;
+ a[3840]=0;
+ a[3841]=0;
+ a[3842]=0;
+ a[3843]=0;
+ a[3844]=0;
+ a[3845]=0;
+ a[3846]=0;
+ a[3847]=0;
+ a[3848]=0;
+ a[3849]=0;
+ a[3850]=0;
+ a[3851]=0;
+ a[3852]=0;
+ a[3853]=0;
+ a[3854]=0;
+ a[3855]=0;
+ a[3856]=0;
+ a[3857]=0;
+ a[3858]=0;
+ a[3859]=0;
+ a[3860]=0;
+ a[3861]=0;
+ a[3862]=0;
+ a[3863]=0;
+ a[3864]=0;
+ a[3865]=0;
+ a[3866]=0;
+ a[3867]=0;
+ a[3868]=0;
+ a[3869]=0;
+ a[3870]=0;
+ a[3871]=0;
+ a[3872]=0;
+ a[3873]=0;
+ a[3874]=0;
+ a[3875]=0;
+ a[3876]=0;
+ a[3877]=0;
+ a[3878]=0;
+ a[3879]=0;
+ a[3880]=0;
+ a[3881]=0;
+ a[3882]=0;
+ a[3883]=0;
+ a[3884]=0;
+ a[3885]=0;
+ a[3886]=0;
+ a[3887]=0;
+ a[3888]=0;
+ a[3889]=0;
+ a[3890]=0;
+ a[3891]=0;
+ a[3892]=0;
+ a[3893]=0;
+ a[3894]=0;
+ a[3895]=0;
+ a[3896]=0;
+ a[3897]=0;
+ a[3898]=0;
+ a[3899]=0;
+ a[3900]=0;
+ a[3901]=0;
+ a[3902]=0;
+ a[3903]=0;
+ a[3904]=0;
+ a[3905]=0;
+ a[3906]=0;
+ a[3907]=0;
+ a[3908]=0;
+ a[3909]=0;
+ a[3910]=0;
+ a[3911]=0;
+ a[3912]=0;
+ a[3913]=0;
+ a[3914]=0;
+ a[3915]=0;
+ a[3916]=0;
+ a[3917]=0;
+ a[3918]=0;
+ a[3919]=0;
+ a[3920]=0;
+ a[3921]=0;
+ a[3922]=0;
+ a[3923]=0;
+ a[3924]=0;
+ a[3925]=0;
+ a[3926]=0;
+ a[3927]=0;
+ a[3928]=0;
+ a[3929]=0;
+ a[3930]=0;
+ a[3931]=0;
+ a[3932]=0;
+ a[3933]=0;
+ a[3934]=0;
+ a[3935]=0;
+ a[3936]=0;
+ a[3937]=0;
+ a[3938]=0;
+ a[3939]=0;
+ a[3940]=0;
+ a[3941]=0;
+ a[3942]=0;
+ a[3943]=0;
+ a[3944]=0;
+ a[3945]=0;
+ a[3946]=0;
+ a[3947]=0;
+ a[3948]=0;
+ a[3949]=0;
+ a[3950]=0;
+ a[3951]=0;
+ a[3952]=0;
+ a[3953]=0;
+ a[3954]=0;
+ a[3955]=0;
+ a[3956]=0;
+ a[3957]=0;
+ a[3958]=0;
+ a[3959]=0;
+ a[3960]=0;
+ a[3961]=0;
+ a[3962]=0;
+ a[3963]=0;
+ a[3964]=0;
+ a[3965]=0;
+ a[3966]=0;
+ a[3967]=0;
+ a[3968]=0;
+ a[3969]=0;
+ a[3970]=0;
+ a[3971]=0;
+ a[3972]=0;
+ a[3973]=0;
+ a[3974]=0;
+ a[3975]=0;
+ a[3976]=0;
+ a[3977]=0;
+ a[3978]=0;
+ a[3979]=0;
+ a[3980]=0;
+ a[3981]=0;
+ a[3982]=0;
+ a[3983]=0;
+ a[3984]=0;
+ a[3985]=0;
+ a[3986]=0;
+ a[3987]=0;
+ a[3988]=0;
+ a[3989]=0;
+ a[3990]=0;
+ a[3991]=0;
+ a[3992]=0;
+ a[3993]=0;
+ a[3994]=0;
+ a[3995]=0;
+ a[3996]=0;
+ a[3997]=0;
+ a[3998]=0;
+ a[3999]=0;
+ a[4000]=0;
+ a[4001]=0;
+ a[4002]=0;
+ a[4003]=0;
+ a[4004]=0;
+ a[4005]=0;
+ a[4006]=0;
+ a[4007]=0;
+ a[4008]=0;
+ a[4009]=0;
+ a[4010]=0;
+ a[4011]=0;
+ a[4012]=0;
+ a[4013]=0;
+ a[4014]=0;
+ a[4015]=0;
+ a[4016]=0;
+ a[4017]=0;
+ a[4018]=0;
+ a[4019]=0;
+ a[4020]=0;
+ a[4021]=0;
+ a[4022]=0;
+ a[4023]=0;
+ a[4024]=0;
+ a[4025]=0;
+ a[4026]=0;
+ a[4027]=0;
+ a[4028]=0;
+ a[4029]=0;
+ a[4030]=0;
+ a[4031]=0;
+ a[4032]=0;
+ a[4033]=0;
+ a[4034]=0;
+ a[4035]=0;
+ a[4036]=0;
+ a[4037]=0;
+ a[4038]=0;
+ a[4039]=0;
+ a[4040]=0;
+ a[4041]=0;
+ a[4042]=0;
+ a[4043]=0;
+ a[4044]=0;
+ a[4045]=0;
+ a[4046]=0;
+ a[4047]=0;
+ a[4048]=0;
+ a[4049]=0;
+ a[4050]=0;
+ a[4051]=0;
+ a[4052]=0;
+ a[4053]=0;
+ a[4054]=0;
+ a[4055]=0;
+ a[4056]=0;
+ a[4057]=0;
+ a[4058]=0;
+ a[4059]=0;
+ a[4060]=0;
+ a[4061]=0;
+ a[4062]=0;
+ a[4063]=0;
+ a[4064]=0;
+ a[4065]=0;
+ a[4066]=0;
+ a[4067]=0;
+ a[4068]=0;
+ a[4069]=0;
+ a[4070]=0;
+ a[4071]=0;
+ a[4072]=0;
+ a[4073]=0;
+ a[4074]=0;
+ a[4075]=0;
+ a[4076]=0;
+ a[4077]=0;
+ a[4078]=0;
+ a[4079]=0;
+ a[4080]=0;
+ a[4081]=0;
+ a[4082]=0;
+ a[4083]=0;
+ a[4084]=0;
+ a[4085]=0;
+ a[4086]=0;
+ a[4087]=0;
+ a[4088]=0;
+ a[4089]=0;
+ a[4090]=0;
+ a[4091]=0;
+ a[4092]=0;
+ a[4093]=0;
+ a[4094]=0;
+ a[4095]=0;
+ a[4096]=0;
+ a[4097]=0;
+ a[4098]=0;
+ a[4099]=0;
+ a[4100]=0;
+ a[4101]=0;
+ a[4102]=0;
+ a[4103]=0;
+ a[4104]=0;
+ a[4105]=0;
+ a[4106]=0;
+ a[4107]=0;
+ a[4108]=0;
+ a[4109]=0;
+ a[4110]=0;
+ a[4111]=0;
+ a[4112]=0;
+ a[4113]=0;
+ a[4114]=0;
+ a[4115]=0;
+ a[4116]=0;
+ a[4117]=0;
+ a[4118]=0;
+ a[4119]=0;
+ a[4120]=0;
+ a[4121]=0;
+ a[4122]=0;
+ a[4123]=0;
+ a[4124]=0;
+ a[4125]=0;
+ a[4126]=0;
+ a[4127]=0;
+ a[4128]=0;
+ a[4129]=0;
+ a[4130]=0;
+ a[4131]=0;
+ a[4132]=0;
+ a[4133]=0;
+ a[4134]=0;
+ a[4135]=0;
+ a[4136]=0;
+ a[4137]=0;
+ a[4138]=0;
+ a[4139]=0;
+ a[4140]=0;
+ a[4141]=0;
+ a[4142]=0;
+ a[4143]=0;
+ a[4144]=0;
+ a[4145]=0;
+ a[4146]=0;
+ a[4147]=0;
+ a[4148]=0;
+ a[4149]=0;
+ a[4150]=0;
+ a[4151]=0;
+ a[4152]=0;
+ a[4153]=0;
+ a[4154]=0;
+ a[4155]=0;
+ a[4156]=0;
+ a[4157]=0;
+ a[4158]=0;
+ a[4159]=0;
+ a[4160]=0;
+ a[4161]=0;
+ a[4162]=0;
+ a[4163]=0;
+ a[4164]=0;
+ a[4165]=0;
+ a[4166]=0;
+ a[4167]=0;
+ a[4168]=0;
+ a[4169]=0;
+ a[4170]=0;
+ a[4171]=0;
+ a[4172]=0;
+ a[4173]=0;
+ a[4174]=0;
+ a[4175]=0;
+ a[4176]=0;
+ a[4177]=0;
+ a[4178]=0;
+ a[4179]=0;
+ a[4180]=0;
+ a[4181]=0;
+ a[4182]=0;
+ a[4183]=0;
+ a[4184]=0;
+ a[4185]=0;
+ a[4186]=0;
+ a[4187]=0;
+ a[4188]=0;
+ a[4189]=0;
+ a[4190]=0;
+ a[4191]=0;
+ a[4192]=0;
+ a[4193]=0;
+ a[4194]=0;
+ a[4195]=0;
+ a[4196]=0;
+ a[4197]=0;
+ a[4198]=0;
+ a[4199]=0;
+ a[4200]=0;
+ a[4201]=0;
+ a[4202]=0;
+ a[4203]=0;
+ a[4204]=0;
+ a[4205]=0;
+ a[4206]=0;
+ a[4207]=0;
+ a[4208]=0;
+ a[4209]=0;
+ a[4210]=0;
+ a[4211]=0;
+ a[4212]=0;
+ a[4213]=0;
+ a[4214]=0;
+ a[4215]=0;
+ a[4216]=0;
+ a[4217]=0;
+ a[4218]=0;
+ a[4219]=0;
+ a[4220]=0;
+ a[4221]=0;
+ a[4222]=0;
+ a[4223]=0;
+ a[4224]=0;
+ a[4225]=0;
+ a[4226]=0;
+ a[4227]=0;
+ a[4228]=0;
+ a[4229]=0;
+ a[4230]=0;
+ a[4231]=0;
+ a[4232]=0;
+ a[4233]=0;
+ a[4234]=0;
+ a[4235]=0;
+ a[4236]=0;
+ a[4237]=0;
+ a[4238]=0;
+ a[4239]=0;
+ a[4240]=0;
+ a[4241]=0;
+ a[4242]=0;
+ a[4243]=0;
+ a[4244]=0;
+ a[4245]=0;
+ a[4246]=0;
+ a[4247]=0;
+ a[4248]=0;
+ a[4249]=0;
+ a[4250]=0;
+ a[4251]=0;
+ a[4252]=0;
+ a[4253]=0;
+ a[4254]=0;
+ a[4255]=0;
+ a[4256]=0;
+ a[4257]=0;
+ a[4258]=0;
+ a[4259]=0;
+ a[4260]=0;
+ a[4261]=0;
+ a[4262]=0;
+ a[4263]=0;
+ a[4264]=0;
+ a[4265]=0;
+ a[4266]=0;
+ a[4267]=0;
+ a[4268]=0;
+ a[4269]=0;
+ a[4270]=0;
+ a[4271]=0;
+ a[4272]=0;
+ a[4273]=0;
+ a[4274]=0;
+ a[4275]=0;
+ a[4276]=0;
+ a[4277]=0;
+ a[4278]=0;
+ a[4279]=0;
+ a[4280]=0;
+ a[4281]=0;
+ a[4282]=0;
+ a[4283]=0;
+ a[4284]=0;
+ a[4285]=0;
+ a[4286]=0;
+ a[4287]=0;
+ a[4288]=0;
+ a[4289]=0;
+ a[4290]=0;
+ a[4291]=0;
+ a[4292]=0;
+ a[4293]=0;
+ a[4294]=0;
+ a[4295]=0;
+ a[4296]=0;
+ a[4297]=0;
+ a[4298]=0;
+ a[4299]=0;
+ a[4300]=0;
+ a[4301]=0;
+ a[4302]=0;
+ a[4303]=0;
+ a[4304]=0;
+ a[4305]=0;
+ a[4306]=0;
+ a[4307]=0;
+ a[4308]=0;
+ a[4309]=0;
+ a[4310]=0;
+ a[4311]=0;
+ a[4312]=0;
+ a[4313]=0;
+ a[4314]=0;
+ a[4315]=0;
+ a[4316]=0;
+ a[4317]=0;
+ a[4318]=0;
+ a[4319]=0;
+ a[4320]=0;
+ a[4321]=0;
+ a[4322]=0;
+ a[4323]=0;
+ a[4324]=0;
+ a[4325]=0;
+ a[4326]=0;
+ a[4327]=0;
+ a[4328]=0;
+ a[4329]=0;
+ a[4330]=0;
+ a[4331]=0;
+ a[4332]=0;
+ a[4333]=0;
+ a[4334]=0;
+ a[4335]=0;
+ a[4336]=0;
+ a[4337]=0;
+ a[4338]=0;
+ a[4339]=0;
+ a[4340]=0;
+ a[4341]=0;
+ a[4342]=0;
+ a[4343]=0;
+ a[4344]=0;
+ a[4345]=0;
+ a[4346]=0;
+ a[4347]=0;
+ a[4348]=0;
+ a[4349]=0;
+ a[4350]=0;
+ a[4351]=0;
+ a[4352]=0;
+ a[4353]=0;
+ a[4354]=0;
+ a[4355]=0;
+ a[4356]=0;
+ a[4357]=0;
+ a[4358]=0;
+ a[4359]=0;
+ a[4360]=0;
+ a[4361]=0;
+ a[4362]=0;
+ a[4363]=0;
+ a[4364]=0;
+ a[4365]=0;
+ a[4366]=0;
+ a[4367]=0;
+ a[4368]=0;
+ a[4369]=0;
+ a[4370]=0;
+ a[4371]=0;
+ a[4372]=0;
+ a[4373]=0;
+ a[4374]=0;
+ a[4375]=0;
+ a[4376]=0;
+ a[4377]=0;
+ a[4378]=0;
+ a[4379]=0;
+ a[4380]=0;
+ a[4381]=0;
+ a[4382]=0;
+ a[4383]=0;
+ a[4384]=0;
+ a[4385]=0;
+ a[4386]=0;
+ a[4387]=0;
+ a[4388]=0;
+ a[4389]=0;
+ a[4390]=0;
+ a[4391]=0;
+ a[4392]=0;
+ a[4393]=0;
+ a[4394]=0;
+ a[4395]=0;
+ a[4396]=0;
+ a[4397]=0;
+ a[4398]=0;
+ a[4399]=0;
+ a[4400]=0;
+ a[4401]=0;
+ a[4402]=0;
+ a[4403]=0;
+ a[4404]=0;
+ a[4405]=0;
+ a[4406]=0;
+ a[4407]=0;
+ a[4408]=0;
+ a[4409]=0;
+ a[4410]=0;
+ a[4411]=0;
+ a[4412]=0;
+ a[4413]=0;
+ a[4414]=0;
+ a[4415]=0;
+ a[4416]=0;
+ a[4417]=0;
+ a[4418]=0;
+ a[4419]=0;
+ a[4420]=0;
+ a[4421]=0;
+ a[4422]=0;
+ a[4423]=0;
+ a[4424]=0;
+ a[4425]=0;
+ a[4426]=0;
+ a[4427]=0;
+ a[4428]=0;
+ a[4429]=0;
+ a[4430]=0;
+ a[4431]=0;
+ a[4432]=0;
+ a[4433]=0;
+ a[4434]=0;
+ a[4435]=0;
+ a[4436]=0;
+ a[4437]=0;
+ a[4438]=0;
+ a[4439]=0;
+ a[4440]=0;
+ a[4441]=0;
+ a[4442]=0;
+ a[4443]=0;
+ a[4444]=0;
+ a[4445]=0;
+ a[4446]=0;
+ a[4447]=0;
+ a[4448]=0;
+ a[4449]=0;
+ a[4450]=0;
+ a[4451]=0;
+ a[4452]=0;
+ a[4453]=0;
+ a[4454]=0;
+ a[4455]=0;
+ a[4456]=0;
+ a[4457]=0;
+ a[4458]=0;
+ a[4459]=0;
+ a[4460]=0;
+ a[4461]=0;
+ a[4462]=0;
+ a[4463]=0;
+ a[4464]=0;
+ a[4465]=0;
+ a[4466]=0;
+ a[4467]=0;
+ a[4468]=0;
+ a[4469]=0;
+ a[4470]=0;
+ a[4471]=0;
+ a[4472]=0;
+ a[4473]=0;
+ a[4474]=0;
+ a[4475]=0;
+ a[4476]=0;
+ a[4477]=0;
+ a[4478]=0;
+ a[4479]=0;
+ a[4480]=0;
+ a[4481]=0;
+ a[4482]=0;
+ a[4483]=0;
+ a[4484]=0;
+ a[4485]=0;
+ a[4486]=0;
+ a[4487]=0;
+ a[4488]=0;
+ a[4489]=0;
+ a[4490]=0;
+ a[4491]=0;
+ a[4492]=0;
+ a[4493]=0;
+ a[4494]=0;
+ a[4495]=0;
+ a[4496]=0;
+ a[4497]=0;
+ a[4498]=0;
+ a[4499]=0;
+ a[4500]=0;
+ a[4501]=0;
+ a[4502]=0;
+ a[4503]=0;
+ a[4504]=0;
+ a[4505]=0;
+ a[4506]=0;
+ a[4507]=0;
+ a[4508]=0;
+ a[4509]=0;
+ a[4510]=0;
+ a[4511]=0;
+ a[4512]=0;
+ a[4513]=0;
+ a[4514]=0;
+ a[4515]=0;
+ a[4516]=0;
+ a[4517]=0;
+ a[4518]=0;
+ a[4519]=0;
+ a[4520]=0;
+ a[4521]=0;
+ a[4522]=0;
+ a[4523]=0;
+ a[4524]=0;
+ a[4525]=0;
+ a[4526]=0;
+ a[4527]=0;
+ a[4528]=0;
+ a[4529]=0;
+ a[4530]=0;
+ a[4531]=0;
+ a[4532]=0;
+ a[4533]=0;
+ a[4534]=0;
+ a[4535]=0;
+ a[4536]=0;
+ a[4537]=0;
+ a[4538]=0;
+ a[4539]=0;
+ a[4540]=0;
+ a[4541]=0;
+ a[4542]=0;
+ a[4543]=0;
+ a[4544]=0;
+ a[4545]=0;
+ a[4546]=0;
+ a[4547]=0;
+ a[4548]=0;
+ a[4549]=0;
+ a[4550]=0;
+ a[4551]=0;
+ a[4552]=0;
+ a[4553]=0;
+ a[4554]=0;
+ a[4555]=0;
+ a[4556]=0;
+ a[4557]=0;
+ a[4558]=0;
+ a[4559]=0;
+ a[4560]=0;
+ a[4561]=0;
+ a[4562]=0;
+ a[4563]=0;
+ a[4564]=0;
+ a[4565]=0;
+ a[4566]=0;
+ a[4567]=0;
+ a[4568]=0;
+ a[4569]=0;
+ a[4570]=0;
+ a[4571]=0;
+ a[4572]=0;
+ a[4573]=0;
+ a[4574]=0;
+ a[4575]=0;
+ a[4576]=0;
+ a[4577]=0;
+ a[4578]=0;
+ a[4579]=0;
+ a[4580]=0;
+ a[4581]=0;
+ a[4582]=0;
+ a[4583]=0;
+ a[4584]=0;
+ a[4585]=0;
+ a[4586]=0;
+ a[4587]=0;
+ a[4588]=0;
+ a[4589]=0;
+ a[4590]=0;
+ a[4591]=0;
+ a[4592]=0;
+ a[4593]=0;
+ a[4594]=0;
+ a[4595]=0;
+ a[4596]=0;
+ a[4597]=0;
+ a[4598]=0;
+ a[4599]=0;
+ a[4600]=0;
+ a[4601]=0;
+ a[4602]=0;
+ a[4603]=0;
+ a[4604]=0;
+ a[4605]=0;
+ a[4606]=0;
+ a[4607]=0;
+ a[4608]=0;
+ a[4609]=0;
+ a[4610]=0;
+ a[4611]=0;
+ a[4612]=0;
+ a[4613]=0;
+ a[4614]=0;
+ a[4615]=0;
+ a[4616]=0;
+ a[4617]=0;
+ a[4618]=0;
+ a[4619]=0;
+ a[4620]=0;
+ a[4621]=0;
+ a[4622]=0;
+ a[4623]=0;
+ a[4624]=0;
+ a[4625]=0;
+ a[4626]=0;
+ a[4627]=0;
+ a[4628]=0;
+ a[4629]=0;
+ a[4630]=0;
+ a[4631]=0;
+ a[4632]=0;
+ a[4633]=0;
+ a[4634]=0;
+ a[4635]=0;
+ a[4636]=0;
+ a[4637]=0;
+ a[4638]=0;
+ a[4639]=0;
+ a[4640]=0;
+ a[4641]=0;
+ a[4642]=0;
+ a[4643]=0;
+ a[4644]=0;
+ a[4645]=0;
+ a[4646]=0;
+ a[4647]=0;
+ a[4648]=0;
+ a[4649]=0;
+ a[4650]=0;
+ a[4651]=0;
+ a[4652]=0;
+ a[4653]=0;
+ a[4654]=0;
+ a[4655]=0;
+ a[4656]=0;
+ a[4657]=0;
+ a[4658]=0;
+ a[4659]=0;
+ a[4660]=0;
+ a[4661]=0;
+ a[4662]=0;
+ a[4663]=0;
+ a[4664]=0;
+ a[4665]=0;
+ a[4666]=0;
+ a[4667]=0;
+ a[4668]=0;
+ a[4669]=0;
+ a[4670]=0;
+ a[4671]=0;
+ a[4672]=0;
+ a[4673]=0;
+ a[4674]=0;
+ a[4675]=0;
+ a[4676]=0;
+ a[4677]=0;
+ a[4678]=0;
+ a[4679]=0;
+ a[4680]=0;
+ a[4681]=0;
+ a[4682]=0;
+ a[4683]=0;
+ a[4684]=0;
+ a[4685]=0;
+ a[4686]=0;
+ a[4687]=0;
+ a[4688]=0;
+ a[4689]=0;
+ a[4690]=0;
+ a[4691]=0;
+ a[4692]=0;
+ a[4693]=0;
+ a[4694]=0;
+ a[4695]=0;
+ a[4696]=0;
+ a[4697]=0;
+ a[4698]=0;
+ a[4699]=0;
+ a[4700]=0;
+ a[4701]=0;
+ a[4702]=0;
+ a[4703]=0;
+ a[4704]=0;
+ a[4705]=0;
+ a[4706]=0;
+ a[4707]=0;
+ a[4708]=0;
+ a[4709]=0;
+ a[4710]=0;
+ a[4711]=0;
+ a[4712]=0;
+ a[4713]=0;
+ a[4714]=0;
+ a[4715]=0;
+ a[4716]=0;
+ a[4717]=0;
+ a[4718]=0;
+ a[4719]=0;
+ a[4720]=0;
+ a[4721]=0;
+ a[4722]=0;
+ a[4723]=0;
+ a[4724]=0;
+ a[4725]=0;
+ a[4726]=0;
+ a[4727]=0;
+ a[4728]=0;
+ a[4729]=0;
+ a[4730]=0;
+ a[4731]=0;
+ a[4732]=0;
+ a[4733]=0;
+ a[4734]=0;
+ a[4735]=0;
+ a[4736]=0;
+ a[4737]=0;
+ a[4738]=0;
+ a[4739]=0;
+ a[4740]=0;
+ a[4741]=0;
+ a[4742]=0;
+ a[4743]=0;
+ a[4744]=0;
+ a[4745]=0;
+ a[4746]=0;
+ a[4747]=0;
+ a[4748]=0;
+ a[4749]=0;
+ a[4750]=0;
+ a[4751]=0;
+ a[4752]=0;
+ a[4753]=0;
+ a[4754]=0;
+ a[4755]=0;
+ a[4756]=0;
+ a[4757]=0;
+ a[4758]=0;
+ a[4759]=0;
+ a[4760]=0;
+ a[4761]=0;
+ a[4762]=0;
+ a[4763]=0;
+ a[4764]=0;
+ a[4765]=0;
+ a[4766]=0;
+ a[4767]=0;
+ a[4768]=0;
+ a[4769]=0;
+ a[4770]=0;
+ a[4771]=0;
+ a[4772]=0;
+ a[4773]=0;
+ a[4774]=0;
+ a[4775]=0;
+ a[4776]=0;
+ a[4777]=0;
+ a[4778]=0;
+ a[4779]=0;
+ a[4780]=0;
+ a[4781]=0;
+ a[4782]=0;
+ a[4783]=0;
+ a[4784]=0;
+ a[4785]=0;
+ a[4786]=0;
+ a[4787]=0;
+ a[4788]=0;
+ a[4789]=0;
+ a[4790]=0;
+ a[4791]=0;
+ a[4792]=0;
+ a[4793]=0;
+ a[4794]=0;
+ a[4795]=0;
+ a[4796]=0;
+ a[4797]=0;
+ a[4798]=0;
+ a[4799]=0;
+ a[4800]=0;
+ a[4801]=0;
+ a[4802]=0;
+ a[4803]=0;
+ a[4804]=0;
+ a[4805]=0;
+ a[4806]=0;
+ a[4807]=0;
+ a[4808]=0;
+ a[4809]=0;
+ a[4810]=0;
+ a[4811]=0;
+ a[4812]=0;
+ a[4813]=0;
+ a[4814]=0;
+ a[4815]=0;
+ a[4816]=0;
+ a[4817]=0;
+ a[4818]=0;
+ a[4819]=0;
+ a[4820]=0;
+ a[4821]=0;
+ a[4822]=0;
+ a[4823]=0;
+ a[4824]=0;
+ a[4825]=0;
+ a[4826]=0;
+ a[4827]=0;
+ a[4828]=0;
+ a[4829]=0;
+ a[4830]=0;
+ a[4831]=0;
+ a[4832]=0;
+ a[4833]=0;
+ a[4834]=0;
+ a[4835]=0;
+ a[4836]=0;
+ a[4837]=0;
+ a[4838]=0;
+ a[4839]=0;
+ a[4840]=0;
+ a[4841]=0;
+ a[4842]=0;
+ a[4843]=0;
+ a[4844]=0;
+ a[4845]=0;
+ a[4846]=0;
+ a[4847]=0;
+ a[4848]=0;
+ a[4849]=0;
+ a[4850]=0;
+ a[4851]=0;
+ a[4852]=0;
+ a[4853]=0;
+ a[4854]=0;
+ a[4855]=0;
+ a[4856]=0;
+ a[4857]=0;
+ a[4858]=0;
+ a[4859]=0;
+ a[4860]=0;
+ a[4861]=0;
+ a[4862]=0;
+ a[4863]=0;
+ a[4864]=0;
+ a[4865]=0;
+ a[4866]=0;
+ a[4867]=0;
+ a[4868]=0;
+ a[4869]=0;
+ a[4870]=0;
+ a[4871]=0;
+ a[4872]=0;
+ a[4873]=0;
+ a[4874]=0;
+ a[4875]=0;
+ a[4876]=0;
+ a[4877]=0;
+ a[4878]=0;
+ a[4879]=0;
+ a[4880]=0;
+ a[4881]=0;
+ a[4882]=0;
+ a[4883]=0;
+ a[4884]=0;
+ a[4885]=0;
+ a[4886]=0;
+ a[4887]=0;
+ a[4888]=0;
+ a[4889]=0;
+ a[4890]=0;
+ a[4891]=0;
+ a[4892]=0;
+ a[4893]=0;
+ a[4894]=0;
+ a[4895]=0;
+ a[4896]=0;
+ a[4897]=0;
+ a[4898]=0;
+ a[4899]=0;
+ a[4900]=0;
+ a[4901]=0;
+ a[4902]=0;
+ a[4903]=0;
+ a[4904]=0;
+ a[4905]=0;
+ a[4906]=0;
+ a[4907]=0;
+ a[4908]=0;
+ a[4909]=0;
+ a[4910]=0;
+ a[4911]=0;
+ a[4912]=0;
+ a[4913]=0;
+ a[4914]=0;
+ a[4915]=0;
+ a[4916]=0;
+ a[4917]=0;
+ a[4918]=0;
+ a[4919]=0;
+ a[4920]=0;
+ a[4921]=0;
+ a[4922]=0;
+ a[4923]=0;
+ a[4924]=0;
+ a[4925]=0;
+ a[4926]=0;
+ a[4927]=0;
+ a[4928]=0;
+ a[4929]=0;
+ a[4930]=0;
+ a[4931]=0;
+ a[4932]=0;
+ a[4933]=0;
+ a[4934]=0;
+ a[4935]=0;
+ a[4936]=0;
+ a[4937]=0;
+ a[4938]=0;
+ a[4939]=0;
+ a[4940]=0;
+ a[4941]=0;
+ a[4942]=0;
+ a[4943]=0;
+ a[4944]=0;
+ a[4945]=0;
+ a[4946]=0;
+ a[4947]=0;
+ a[4948]=0;
+ a[4949]=0;
+ a[4950]=0;
+ a[4951]=0;
+ a[4952]=0;
+ a[4953]=0;
+ a[4954]=0;
+ a[4955]=0;
+ a[4956]=0;
+ a[4957]=0;
+ a[4958]=0;
+ a[4959]=0;
+ a[4960]=0;
+ a[4961]=0;
+ a[4962]=0;
+ a[4963]=0;
+ a[4964]=0;
+ a[4965]=0;
+ a[4966]=0;
+ a[4967]=0;
+ a[4968]=0;
+ a[4969]=0;
+ a[4970]=0;
+ a[4971]=0;
+ a[4972]=0;
+ a[4973]=0;
+ a[4974]=0;
+ a[4975]=0;
+ a[4976]=0;
+ a[4977]=0;
+ a[4978]=0;
+ a[4979]=0;
+ a[4980]=0;
+ a[4981]=0;
+ a[4982]=0;
+ a[4983]=0;
+ a[4984]=0;
+ a[4985]=0;
+ a[4986]=0;
+ a[4987]=0;
+ a[4988]=0;
+ a[4989]=0;
+ a[4990]=0;
+ a[4991]=0;
+ a[4992]=0;
+ a[4993]=0;
+ a[4994]=0;
+ a[4995]=0;
+ a[4996]=0;
+ a[4997]=0;
+ a[4998]=0;
+ a[4999]=0;
+ return a;
+}
diff --git a/test/mjsunit/regress/regress-1973.js b/test/mjsunit/regress/regress-1973.js
new file mode 100644
index 00000000..8708bf12
--- /dev/null
+++ b/test/mjsunit/regress/regress-1973.js
@@ -0,0 +1,52 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test that getters and setters pass unwrapped this values in strict mode
+// and wrapped this values is non-strict mode.
+
+function TestAccessorWrapping(primitive) {
+ var prototype = Object.getPrototypeOf(Object(primitive))
+ // Check that strict mode passes unwrapped this value.
+ var strict_type = typeof primitive;
+ Object.defineProperty(prototype, "strict", {
+ get: function() { "use strict"; assertSame(strict_type, typeof this); },
+ set: function() { "use strict"; assertSame(strict_type, typeof this); }
+ });
+ primitive.strict = primitive.strict;
+ // Check that non-strict mode passes wrapped this value.
+ var sloppy_type = typeof Object(primitive);
+ Object.defineProperty(prototype, "sloppy", {
+ get: function() { assertSame(sloppy_type, typeof this); },
+ set: function() { assertSame(sloppy_type, typeof this); }
+ });
+ primitive.sloppy = primitive.sloppy;
+}
+
+TestAccessorWrapping(true);
+TestAccessorWrapping(0);
+TestAccessorWrapping({});
+TestAccessorWrapping("");
diff --git a/test/mjsunit/regress/regress-1980.js b/test/mjsunit/regress/regress-1980.js
new file mode 100644
index 00000000..49dfd063
--- /dev/null
+++ b/test/mjsunit/regress/regress-1980.js
@@ -0,0 +1,40 @@
+// 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.
+
+// See: http://code.google.com/p/v8/issues/detail?id=1980
+
+var invalid_this = [ "invalid", 23, undefined, null ];
+for (var i = 0; i < invalid_this.length; i++) {
+ var exception = false;
+ try {
+ Error.prototype.toString.call(invalid_this[i]);
+ } catch (e) {
+ exception = true;
+ assertTrue("called_on_non_object" == e.type);
+ }
+ assertTrue(exception);
+}
diff --git a/test/mjsunit/regress/regress-2045.js b/test/mjsunit/regress/regress-2045.js
new file mode 100644
index 00000000..822ee1fa
--- /dev/null
+++ b/test/mjsunit/regress/regress-2045.js
@@ -0,0 +1,49 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function foo() {
+ assertEquals(2, arguments.length);
+}
+
+function bar() {
+ G.x;
+ return foo.apply(this, arguments);
+}
+
+function baz() {
+ return bar(1, 2);
+}
+
+G = {x: 0};
+baz();
+baz();
+%OptimizeFunctionOnNextCall(baz);
+baz();
+delete G.x;
+baz();
diff --git a/test/mjsunit/regress/regress-2056.js b/test/mjsunit/regress/regress-2056.js
new file mode 100644
index 00000000..d34a7500
--- /dev/null
+++ b/test/mjsunit/regress/regress-2056.js
@@ -0,0 +1,66 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+var cases = [
+ [0.0, 0.0, 0.0, 0,0],
+ [undefined, 0.0, NaN, NaN],
+ [0.0, undefined, NaN, NaN],
+ [NaN, 0.0, NaN, NaN],
+ [0.0, NaN, NaN, NaN],
+ [-NaN, 0.0, NaN, NaN],
+ [0.0, -NaN, NaN, NaN],
+ [Infinity, 0.0, Infinity, 0.0],
+ [0.0, Infinity, Infinity, 0.0],
+ [-Infinity, 0.0, 0.0, -Infinity],
+ [0.0, -Infinity, 0.0, -Infinity]
+];
+
+function do_min(a, b) {
+ return Math.min(a, b);
+}
+
+function do_max(a, b) {
+ return Math.max(a, b);
+}
+
+// Make sure that non-crankshaft results match expectations.
+for (i = 0; i < cases.length; ++i) {
+ var c = cases[i];
+ assertEquals(c[3], do_min(c[0], c[1]));
+ assertEquals(c[2], do_max(c[0], c[1]));
+}
+
+// Make sure that crankshaft results match expectations.
+for (i = 0; i < cases.length; ++i) {
+ var c = cases[i];
+ %OptimizeFunctionOnNextCall(do_min);
+ %OptimizeFunctionOnNextCall(do_max);
+ assertEquals(c[3], do_min(c[0], c[1]));
+ assertEquals(c[2], do_max(c[0], c[1]));
+}
diff --git a/test/mjsunit/regress/regress-397.js b/test/mjsunit/regress/regress-397.js
index 111f4a6e..0e4143d0 100644
--- a/test/mjsunit/regress/regress-397.js
+++ b/test/mjsunit/regress/regress-397.js
@@ -25,10 +25,19 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
// See http://code.google.com/p/v8/issues/detail?id=397
-assertEquals("Infinity", String(Math.pow(Infinity, 0.5)));
-assertEquals(0, Math.pow(Infinity, -0.5));
-assertEquals("Infinity", String(Math.pow(-Infinity, 0.5)));
-assertEquals(0, Math.pow(-Infinity, -0.5));
+function test() {
+ assertEquals("Infinity", String(Math.pow(Infinity, 0.5)));
+ assertEquals(0, Math.pow(Infinity, -0.5));
+
+ assertEquals("Infinity", String(Math.pow(-Infinity, 0.5)));
+ assertEquals(0, Math.pow(-Infinity, -0.5));
+}
+
+test();
+test();
+%OptimizeFunctionOnNextCall(test);
+test();
diff --git a/test/mjsunit/regress/regress-877615.js b/test/mjsunit/regress/regress-877615.js
index d35aba62..bec5a4d1 100644
--- a/test/mjsunit/regress/regress-877615.js
+++ b/test/mjsunit/regress/regress-877615.js
@@ -25,13 +25,13 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-Number.prototype.toLocaleString = function() { return 'invalid'};
-assertEquals([1].toLocaleString(), 'invalid'); // invalid
+Number.prototype.toLocaleString = function() { return 'invalid'; };
+assertEquals('invalid', [1].toLocaleString()); // invalid
Number.prototype.toLocaleString = 'invalid';
-assertEquals([1].toLocaleString(), '1'); // 1
+assertThrows(function() { [1].toLocaleString(); }); // Not callable.
+delete Number.prototype.toLocaleString;
Number.prototype.toString = function() { return 'invalid' };
-assertEquals([1].toLocaleString(), '1'); // 1
-assertEquals([1].toString(), '1'); // 1
-
+assertEquals([1].toLocaleString(), 'invalid'); // Uses ToObject on elements.
+assertEquals([1].toString(), '1'); // Uses ToString directly on elements.
diff --git a/test/mjsunit/regress/regress-91517.js b/test/mjsunit/regress/regress-91517.js
deleted file mode 100644
index 68a768c4..00000000
--- a/test/mjsunit/regress/regress-91517.js
+++ /dev/null
@@ -1,112 +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.
-
-// Getting property names of an object with a prototype chain that
-// triggers dictionary elements in GetLocalPropertyNames() shouldn't
-// crash the runtime
-
-// Flags: --allow-natives-syntax
-
-function Object1() {
- this.foo = 1;
-}
-
-function Object2() {
- this.fuz = 2;
- this.objects = new Object();
- this.fuz1 = 2;
- this.fuz2 = 2;
- this.fuz3 = 2;
- this.fuz4 = 2;
- this.fuz5 = 2;
- this.fuz6 = 2;
- this.fuz7 = 2;
- this.fuz8 = 2;
- this.fuz9 = 2;
- this.fuz10 = 2;
- this.fuz11 = 2;
- this.fuz12 = 2;
- this.fuz13 = 2;
- this.fuz14 = 2;
- this.fuz15 = 2;
- this.fuz16 = 2;
- this.fuz17 = 2;
- // Force dictionary-based properties
- for (x=1;x<1000;x++) {
- this["sdf" + x] = 2;
- }
-}
-
-function Object3() {
- this.boo = 3;
-}
-
-function Object4() {
- this.baz = 4;
-}
-
-obj1 = new Object1();
-obj2 = new Object2();
-obj3 = new Object3();
-obj4 = new Object4();
-
-%SetHiddenPrototype(obj4, obj3);
-%SetHiddenPrototype(obj3, obj2);
-%SetHiddenPrototype(obj2, obj1);
-
-function contains(a, obj) {
- for(var i = 0; i < a.length; i++) {
- if(a[i] === obj){
- return true;
- }
- }
- return false;
-}
-names = %GetLocalPropertyNames(obj4);
-assertEquals(1021, names.length);
-assertTrue(contains(names, "baz"));
-assertTrue(contains(names, "boo"));
-assertTrue(contains(names, "foo"));
-assertTrue(contains(names, "fuz"));
-assertTrue(contains(names, "fuz1"));
-assertTrue(contains(names, "fuz2"));
-assertTrue(contains(names, "fuz3"));
-assertTrue(contains(names, "fuz4"));
-assertTrue(contains(names, "fuz5"));
-assertTrue(contains(names, "fuz6"));
-assertTrue(contains(names, "fuz7"));
-assertTrue(contains(names, "fuz8"));
-assertTrue(contains(names, "fuz9"));
-assertTrue(contains(names, "fuz10"));
-assertTrue(contains(names, "fuz11"));
-assertTrue(contains(names, "fuz12"));
-assertTrue(contains(names, "fuz13"));
-assertTrue(contains(names, "fuz14"));
-assertTrue(contains(names, "fuz15"));
-assertTrue(contains(names, "fuz16"));
-assertTrue(contains(names, "fuz17"));
-assertFalse(names[1020] == undefined);
diff --git a/test/mjsunit/regress/regress-94873.js b/test/mjsunit/regress/regress-94873.js
new file mode 100644
index 00000000..41ca9921
--- /dev/null
+++ b/test/mjsunit/regress/regress-94873.js
@@ -0,0 +1,78 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug;
+
+function sendCommand(state, cmd) {
+ // Get the debug command processor in paused state.
+ var dcp = state.debugCommandProcessor(false);
+ var request = JSON.stringify(cmd);
+ var response = dcp.processDebugJSONRequest(request);
+ return JSON.parse(response);
+}
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Break) {
+ var line = event_data.sourceLineText();
+ print('break: ' + line);
+
+ var frame = sendCommand(exec_state, {
+ seq: 0,
+ type: "request",
+ command: "frame"
+ });
+
+ sendCommand(exec_state, {
+ seq: 0,
+ type: "request",
+ command: "evaluate",
+ arguments: {
+ expression: "obj.x.toString()",
+ additional_context: [{
+ name: "obj",
+ handle: frame.body.receiver.ref
+ }]
+ }
+ });
+ }
+ } catch (e) {
+ print(e);
+ }
+}
+
+Debug.setListener(listener);
+
+function a(x, y) {
+ this.x = x;
+ this.y = y;
+}
+
+Debug.setBreakPoint(a, 0, 0);
+new a(1, 2); \ No newline at end of file
diff --git a/test/mjsunit/regress/regress-95113.js b/test/mjsunit/regress/regress-95113.js
index f01b2700..468bff84 100644
--- a/test/mjsunit/regress/regress-95113.js
+++ b/test/mjsunit/regress/regress-95113.js
@@ -32,7 +32,7 @@ function get_double_array() {
var i = 0;
while (!%HasFastDoubleElements(a)) {
a[i] = i;
- i++;
+ i += 0.5;
}
assertTrue(%HasFastDoubleElements(a));
a.length = 1;
diff --git a/test/mjsunit/regress/regress-98773.js b/test/mjsunit/regress/regress-98773.js
new file mode 100644
index 00000000..eb24eb5d
--- /dev/null
+++ b/test/mjsunit/regress/regress-98773.js
@@ -0,0 +1,39 @@
+// 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.
+
+// Calling Array.sort on an external array is not supposed to crash.
+
+var array = new Int16Array(23);
+array[7] = 7; array[9] = 9;
+assertEquals(23, array.length);
+assertEquals(7, array[7]);
+assertEquals(9, array[9]);
+
+Array.prototype.sort.call(array);
+assertEquals(23, array.length);
+assertEquals(7, array[21]);
+assertEquals(9, array[22]);
diff --git a/test/mjsunit/regress/regress-99167.js b/test/mjsunit/regress/regress-99167.js
new file mode 100644
index 00000000..5053ae5d
--- /dev/null
+++ b/test/mjsunit/regress/regress-99167.js
@@ -0,0 +1,33 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-gc --max-new-space-size=1024
+
+eval("function Node() { this.a = 1; this.a = 3; }");
+new Node;
+for (var i = 0; i < 4; ++i) gc();
+for (var i = 0; i < 100000; ++i) new Node;
diff --git a/test/mjsunit/regress/regress-crbug-100859.js b/test/mjsunit/regress/regress-crbug-100859.js
new file mode 100644
index 00000000..68244262
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-100859.js
@@ -0,0 +1,39 @@
+// 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.
+
+// This used to trigger a crash because of an unhandled stack overflow.
+function setx() {
+ setx(typeof new Uint16Array('x') === 'object');
+}
+var exception = false;
+try {
+ setx();
+} catch (ex) {
+ assertTrue(ex instanceof RangeError);
+ exception = true;
+}
+assertTrue(exception);
diff --git a/test/mjsunit/regress/regress-crbug-107996.js b/test/mjsunit/regress/regress-crbug-107996.js
new file mode 100644
index 00000000..dfe07e59
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-107996.js
@@ -0,0 +1,64 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-debug-as debug
+
+Debug = debug.Debug;
+
+Debug.setListener(listener);
+
+var fourteen;
+var four_in_debugger = [];
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ for (var i = 0; i < exec_state.frameCount(); i++) {
+ var frame = exec_state.frame(i);
+ four_in_debugger[i] = frame.evaluate("four", false).value();
+ }
+ }
+}
+
+function f1() {
+ var three = 3;
+ var four = 4;
+ (function f2() {
+ var seven = 7;
+ (function f3() {
+ debugger;
+ fourteen = three + four + seven;
+ })();
+ })();
+}
+
+f1();
+assertEquals(14, fourteen);
+assertEquals(4, four_in_debugger[0]);
+assertEquals(4, four_in_debugger[1]);
+assertEquals(4, four_in_debugger[2]);
+
+Debug.setListener(null);
diff --git a/test/mjsunit/regress/regress-crbug-119926.js b/test/mjsunit/regress/regress-crbug-119926.js
new file mode 100644
index 00000000..26b84fad
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-119926.js
@@ -0,0 +1,33 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Test that array elements don't break upon garbage collection.
+
+var a = new Array(500);
+for (var i = 0; i < 500000; i++) {
+ a[i] = new Object();
+}
diff --git a/test/mjsunit/regress/regress-debug-code-recompilation.js b/test/mjsunit/regress/regress-debug-code-recompilation.js
new file mode 100644
index 00000000..1a608b14
--- /dev/null
+++ b/test/mjsunit/regress/regress-debug-code-recompilation.js
@@ -0,0 +1,47 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --hydrogen-filter=Debug.setBreakPoint --expose-debug-as debug
+
+Debug = debug.Debug
+
+function f() {a=1;b=2};
+function g() {
+ a=1;
+ b=2;
+}
+
+bp = Debug.setBreakPoint(f, 0, 0);
+Debug.clearBreakPoint(bp);
+%OptimizeFunctionOnNextCall(Debug.setBreakPoint);
+bp = Debug.setBreakPoint(f, 0, 0);
+Debug.clearBreakPoint(bp);
+bp = Debug.setBreakPoint(f, 0, 0);
+Debug.clearBreakPoint(bp);
+%OptimizeFunctionOnNextCall(Debug.setBreakPoint);
+bp = Debug.setBreakPoint(f, 0, 0);
+Debug.clearBreakPoint(bp);
diff --git a/test/mjsunit/regress/regress-deopt-gc.js b/test/mjsunit/regress/regress-deopt-gc.js
index 7b7c29a3..a74e2c5e 100644
--- a/test/mjsunit/regress/regress-deopt-gc.js
+++ b/test/mjsunit/regress/regress-deopt-gc.js
@@ -42,7 +42,7 @@ function deopt() {
// Make sure we don't inline this function
try { var a = 42; } catch(o) {};
%DeoptimizeFunction(opt_me);
- gc(true);
+ gc();
}
diff --git a/test/mjsunit/regress/regress-inlining-function-literal-context.js b/test/mjsunit/regress/regress-inlining-function-literal-context.js
new file mode 100644
index 00000000..9b7f7ac7
--- /dev/null
+++ b/test/mjsunit/regress/regress-inlining-function-literal-context.js
@@ -0,0 +1,53 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+function mkbaz(x) {
+ function baz() {
+ return function () {
+ return [x];
+ }
+ }
+ return baz;
+}
+
+var baz = mkbaz(1);
+
+function foo() {
+ var f = baz();
+ return f();
+}
+
+// Tenure.
+gc();
+gc();
+
+assertArrayEquals([1], foo());
+assertArrayEquals([1], foo());
+%OptimizeFunctionOnNextCall(foo);
+assertArrayEquals([1], foo());
diff --git a/test/mjsunit/regress/regress-smi-only-concat.js b/test/mjsunit/regress/regress-smi-only-concat.js
new file mode 100644
index 00000000..a9a6d89b
--- /dev/null
+++ b/test/mjsunit/regress/regress-smi-only-concat.js
@@ -0,0 +1,37 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+// This tests that concatenating a fast smi-only array and a fast object array
+// results in a fast object array.
+
+var fast_array = ['a', 'b'];
+var array = fast_array.concat(fast_array);
+
+assertTrue(%HasFastElements(fast_array));
+assertTrue(%HasFastElements(array)); \ No newline at end of file
diff --git a/test/mjsunit/regress/regress-sqrt.js b/test/mjsunit/regress/regress-sqrt.js
new file mode 100644
index 00000000..f2a7e552
--- /dev/null
+++ b/test/mjsunit/regress/regress-sqrt.js
@@ -0,0 +1,47 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+// Check that Math.sqrt returns the same value regardless of being
+// optimized or not.
+
+function f(x) {
+ return Math.sqrt(x);
+}
+
+var x = 7.0506280066499245e-233;
+
+var a = f(x);
+
+f(0.1);
+f(0.2);
+%OptimizeFunctionOnNextCall(f);
+
+var b = f(x);
+
+assertEquals(a, b);
diff --git a/test/mjsunit/regress/short-circuit.js b/test/mjsunit/regress/short-circuit.js
new file mode 100644
index 00000000..25363d6b
--- /dev/null
+++ b/test/mjsunit/regress/short-circuit.js
@@ -0,0 +1,32 @@
+// 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.
+
+var arr = [];
+
+for (var i = 0; i < 28000; i++) {
+ arr.push(new RegExp("prefix" + i.toString() + i.toString() + i.toString()));
+}
diff --git a/test/mjsunit/stack-traces-2.js b/test/mjsunit/stack-traces-2.js
new file mode 100644
index 00000000..165c4dfc
--- /dev/null
+++ b/test/mjsunit/stack-traces-2.js
@@ -0,0 +1,87 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --builtins-in-stack-traces
+
+
+// Poisonous object that throws a reference error if attempted converted to
+// a primitive values.
+var thrower = { valueOf: function() { FAIL; },
+ toString: function() { FAIL; } };
+
+// Tests that a native constructor function is included in the
+// stack trace.
+function testTraceNativeConstructor(nativeFunc) {
+ var nativeFuncName = nativeFunc.name;
+ try {
+ new nativeFunc(thrower);
+ assertUnreachable(nativeFuncName);
+ } catch (e) {
+ assertTrue(e.stack.indexOf(nativeFuncName) >= 0, nativeFuncName);
+ }
+}
+
+// Tests that a native conversion function is included in the
+// stack trace.
+function testTraceNativeConversion(nativeFunc) {
+ var nativeFuncName = nativeFunc.name;
+ try {
+ nativeFunc(thrower);
+ assertUnreachable(nativeFuncName);
+ } catch (e) {
+ assertTrue(e.stack.indexOf(nativeFuncName) >= 0, nativeFuncName);
+ }
+}
+
+
+function testNotOmittedBuiltin(throwing, included) {
+ try {
+ throwing();
+ assertUnreachable(included);
+ } catch (e) {
+ assertTrue(e.stack.indexOf(included) >= 0, included);
+ }
+}
+
+
+testTraceNativeConversion(String); // Does ToString on argument.
+testTraceNativeConversion(Number); // Does ToNumber on argument.
+testTraceNativeConversion(RegExp); // Does ToString on argument.
+
+testTraceNativeConstructor(String); // Does ToString on argument.
+testTraceNativeConstructor(Number); // Does ToNumber on argument.
+testTraceNativeConstructor(RegExp); // Does ToString on argument.
+testTraceNativeConstructor(Date); // Does ToNumber on argument.
+
+// QuickSort has builtins object as receiver, and is non-native
+// builtin. Should not be omitted with the --builtins-in-stack-traces flag.
+testNotOmittedBuiltin(function(){ [thrower, 2].sort(function (a,b) {
+ (b < a) - (a < b); });
+ }, "QuickSort");
+
+// Not omitted even though ADD from runtime.js is a non-native builtin.
+testNotOmittedBuiltin(function(){ thrower + 2; }, "ADD"); \ No newline at end of file
diff --git a/test/mjsunit/stack-traces.js b/test/mjsunit/stack-traces.js
index 47a5cc59..536e71bb 100644
--- a/test/mjsunit/stack-traces.js
+++ b/test/mjsunit/stack-traces.js
@@ -194,6 +194,46 @@ function testErrorsDuringFormatting() {
}
+// Poisonous object that throws a reference error if attempted converted to
+// a primitive values.
+var thrower = { valueOf: function() { FAIL; },
+ toString: function() { FAIL; } };
+
+// Tests that a native constructor function is included in the
+// stack trace.
+function testTraceNativeConstructor(nativeFunc) {
+ var nativeFuncName = nativeFunc.name;
+ try {
+ new nativeFunc(thrower);
+ assertUnreachable(nativeFuncName);
+ } catch (e) {
+ assertTrue(e.stack.indexOf(nativeFuncName) >= 0, nativeFuncName);
+ }
+}
+
+// Tests that a native conversion function is included in the
+// stack trace.
+function testTraceNativeConversion(nativeFunc) {
+ var nativeFuncName = nativeFunc.name;
+ try {
+ nativeFunc(thrower);
+ assertUnreachable(nativeFuncName);
+ } catch (e) {
+ assertTrue(e.stack.indexOf(nativeFuncName) >= 0, nativeFuncName);
+ }
+}
+
+
+function testOmittedBuiltin(throwing, omitted) {
+ try {
+ throwing();
+ assertUnreachable(omitted);
+ } catch (e) {
+ assertTrue(e.stack.indexOf(omitted) < 0, omitted);
+ }
+}
+
+
testTrace("testArrayNative", testArrayNative, ["Array.map (native)"]);
testTrace("testNested", testNested, ["at one", "at two", "at three"]);
testTrace("testMethodNameInference", testMethodNameInference, ["at Foo.bar"]);
@@ -217,3 +257,21 @@ testTrace("testStrippedCustomError", testStrippedCustomError, ["hep-hey"],
testCallerCensorship();
testUnintendedCallerCensorship();
testErrorsDuringFormatting();
+
+testTraceNativeConversion(String); // Does ToString on argument.
+testTraceNativeConversion(Number); // Does ToNumber on argument.
+testTraceNativeConversion(RegExp); // Does ToString on argument.
+
+testTraceNativeConstructor(String); // Does ToString on argument.
+testTraceNativeConstructor(Number); // Does ToNumber on argument.
+testTraceNativeConstructor(RegExp); // Does ToString on argument.
+testTraceNativeConstructor(Date); // Does ToNumber on argument.
+
+// Omitted because QuickSort has builtins object as receiver, and is non-native
+// builtin.
+testOmittedBuiltin(function(){ [thrower, 2].sort(function (a,b) {
+ (b < a) - (a < b); });
+ }, "QuickSort");
+
+// Omitted because ADD from runtime.js is non-native builtin.
+testOmittedBuiltin(function(){ thrower + 2; }, "ADD"); \ No newline at end of file
diff --git a/test/mjsunit/strict-mode-implicit-receiver.js b/test/mjsunit/strict-mode-implicit-receiver.js
index 338f6d10..8284eddc 100644
--- a/test/mjsunit/strict-mode-implicit-receiver.js
+++ b/test/mjsunit/strict-mode-implicit-receiver.js
@@ -168,12 +168,7 @@ outer_eval_conversion3(return_this, 'object');
outer_eval_conversion3(strict_eval, 'undefined');
outer_eval_conversion3(non_strict_eval, 'object');
-// TODO(ager): I'm not sure this is in accordance with the spec. At
-// the moment, any call to eval where eval is not bound in the global
-// context is treated as an indirect call to eval which means that the
-// global context is used and the global object is passed as the
-// receiver.
-outer_eval_conversion3(eval, 'object');
+outer_eval_conversion3(eval, 'undefined');
function test_constant_function() {
var o = { f: function() { "use strict"; return this; } };
diff --git a/test/mjsunit/strict-mode.js b/test/mjsunit/strict-mode.js
index 30234ba6..9c9bdfd5 100644
--- a/test/mjsunit/strict-mode.js
+++ b/test/mjsunit/strict-mode.js
@@ -1051,14 +1051,20 @@ function CheckPillDescriptor(func, name) {
}
assertThrows(function() { strict.caller; }, TypeError);
assertThrows(function() { strict.arguments; }, TypeError);
+ assertThrows(function() { strict.caller = 42; }, TypeError);
+ assertThrows(function() { strict.arguments = 42; }, TypeError);
var another = new Function("'use strict'");
assertThrows(function() { another.caller; }, TypeError);
assertThrows(function() { another.arguments; }, TypeError);
+ assertThrows(function() { another.caller = 42; }, TypeError);
+ assertThrows(function() { another.arguments = 42; }, TypeError);
var third = (function() { "use strict"; return function() {}; })();
assertThrows(function() { third.caller; }, TypeError);
assertThrows(function() { third.arguments; }, TypeError);
+ assertThrows(function() { third.caller = 42; }, TypeError);
+ assertThrows(function() { third.arguments = 42; }, TypeError);
CheckPillDescriptor(strict, "caller");
CheckPillDescriptor(strict, "arguments");
diff --git a/test/mjsunit/string-external-cached.js b/test/mjsunit/string-external-cached.js
new file mode 100644
index 00000000..6e242853
--- /dev/null
+++ b/test/mjsunit/string-external-cached.js
@@ -0,0 +1,121 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --expose-externalize-string --expose-gc
+// Test data pointer caching of external strings.
+
+function test() {
+ // Test string.charAt.
+ var charat_str = new Array(5);
+ charat_str[0] = "0123456789ABCDEF0123456789ABCDEF\
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\
+0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF";
+ charat_str[1] = "0123456789ABCDEF";
+ for (var i = 0; i < 6; i++) charat_str[1] += charat_str[1];
+ try { // String can only be externalized once
+ externalizeString(charat_str[0], false);
+ externalizeString(charat_str[1], true);
+ } catch (ex) { }
+ charat_str[2] = charat_str[0].slice(0, -1);
+ charat_str[3] = charat_str[1].slice(0, -1);
+ charat_str[4] = charat_str[0] + charat_str[0];
+
+ for (var i = 0; i < 5; i++) {
+ assertEquals('B', charat_str[i].charAt(6*16 + 11));
+ assertEquals('C', charat_str[i].charAt(6*16 + 12));
+ assertEquals('A', charat_str[i].charAt(3*16 + 10));
+ assertEquals('B', charat_str[i].charAt(3*16 + 11));
+ }
+
+ charat_short = "012";
+ try { // String can only be externalized once
+ externalizeString(charat_short, true);
+ } catch (ex) { }
+ assertEquals("1", charat_short.charAt(1));
+
+ // Test regexp and short substring.
+ var re = /(A|B)/;
+ var rere = /(T.{1,2}B)/;
+ var ascii = "ABCDEFGHIJKLMNOPQRST";
+ var twobyte = "_ABCDEFGHIJKLMNOPQRST";
+ try {
+ externalizeString(ascii, false);
+ externalizeString(twobyte, true);
+ } catch (ex) { }
+ assertTrue(isAsciiString(ascii));
+ assertFalse(isAsciiString(twobyte));
+ var ascii_slice = ascii.slice(1,-1);
+ var twobyte_slice = twobyte.slice(2,-1);
+ var ascii_cons = ascii + ascii;
+ var twobyte_cons = twobyte + twobyte;
+ for (var i = 0; i < 2; i++) {
+ assertEquals(["A", "A"], re.exec(ascii));
+ assertEquals(["B", "B"], re.exec(ascii_slice));
+ assertEquals(["TAB", "TAB"], rere.exec(ascii_cons));
+ assertEquals(["A", "A"], re.exec(twobyte));
+ assertEquals(["B", "B"], re.exec(twobyte_slice));
+ assertEquals(["T_AB", "T_AB"], rere.exec(twobyte_cons));
+ assertEquals("DEFG", ascii_slice.substr(2, 4));
+ assertEquals("DEFG", twobyte_slice.substr(2, 4));
+ assertEquals("DEFG", ascii_cons.substr(3, 4));
+ assertEquals("DEFG", twobyte_cons.substr(4, 4));
+ }
+
+ // Test adding external strings
+ var short_ascii = "E=";
+ var long_ascii = "MCsquared";
+ var short_twobyte = "E\u1234";
+ var long_twobyte = "MCsquare\u1234";
+ try { // String can only be externalized once
+ externalizeString(short_ascii, false);
+ externalizeString(long_ascii, false);
+ externalizeString(short_twobyte, true);
+ externalizeString(long_twobyte, true);
+ assertTrue(isAsciiString(short_asii) && isAsciiString(long_ascii));
+ assertFalse(isAsciiString(short_twobyte) || isAsciiString(long_twobyte));
+ } catch (ex) { }
+ assertEquals("E=MCsquared", short_ascii + long_ascii);
+ assertTrue(isAsciiString(short_ascii + long_ascii));
+ assertEquals("MCsquaredE=", long_ascii + short_ascii);
+ assertEquals("E\u1234MCsquare\u1234", short_twobyte + long_twobyte);
+ assertFalse(isAsciiString(short_twobyte + long_twobyte));
+ assertEquals("E=MCsquared", "E=" + long_ascii);
+ assertEquals("E\u1234MCsquared", short_twobyte + "MCsquared");
+ assertEquals("E\u1234MCsquared", short_twobyte + long_ascii);
+ assertFalse(isAsciiString(short_twobyte + long_ascii));
+}
+
+// Run the test many times to ensure IC-s don't break things.
+for (var i = 0; i < 10; i++) {
+ test();
+}
+
+// Clean up string to make Valgrind happy.
+gc();
+gc();
diff --git a/test/mjsunit/string-externalize.js b/test/mjsunit/string-externalize.js
index da897869..d52a7e2b 100644
--- a/test/mjsunit/string-externalize.js
+++ b/test/mjsunit/string-externalize.js
@@ -44,7 +44,7 @@ function test() {
assertFalse(isAsciiString(twoByteExternalWithAsciiData));
var realTwoByteExternalString =
- "\u1234\u1234" + (function() { return "\u1234"; })();
+ "\u1234\u1234\u1234\u1234" + (function() { return "\u1234"; })();
externalizeString(realTwoByteExternalString);
assertFalse(isAsciiString(realTwoByteExternalString));
diff --git a/test/mjsunit/string-replace-one-char.js b/test/mjsunit/string-replace-one-char.js
new file mode 100644
index 00000000..cb4167ba
--- /dev/null
+++ b/test/mjsunit/string-replace-one-char.js
@@ -0,0 +1,92 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Make sure the strings are long enough to trigger the one-char string replace.
+var prefix1024 = "0123456789ABCDEF";
+for (var i = 0; i < 6; i++) prefix1024 += prefix1024;
+
+function test_replace(result, expected, search, replace) {
+ assertEquals(expected, result.replace(search, replace));
+}
+
+// '$' in the replace string.
+test_replace(prefix1024 + "abcdefghijklmnopqrstuvwxyz",
+ prefix1024 + "abcdefghijk#l#mnopqrstuvwxyz",
+ "l", "#$&#");
+
+test_replace(prefix1024 + "abcdefghijklmnopqrstuvwxyz\u1234",
+ prefix1024 + "abcdefghijk\u2012l\u2012mnopqrstuvwxyz\u1234",
+ "l", "\u2012$&\u2012");
+
+test_replace(prefix1024 + "abcdefghijklmnopqrstuvwxyz",
+ prefix1024 + "abcdefghijk$mnopqrstuvwxyz",
+ "l", "$$");
+
+test_replace(prefix1024 + "abcdefghijklmnopqrstuvwxyz\u1234",
+ prefix1024 + "abcdefghijk$mnopqrstuvwxyz\u1234",
+ "l", "$$");
+
+// Zero length replace string.
+test_replace(prefix1024 + "abcdefghijklmnopqrstuvwxyz",
+ prefix1024 + "abcdefghijklmnopqstuvwxyz",
+ "r", "");
+
+test_replace(prefix1024 + "abcdefghijklmnopq\u1234stuvwxyz",
+ prefix1024 + "abcdefghijklmnopqstuvwxyz",
+ "\u1234", "");
+
+// Search char not found.
+var not_found_1 = prefix1024 + "abcdefghijklmnopqrstuvwxyz";
+test_replace(not_found_1, not_found_1, "+", "-");
+
+var not_found_2 = prefix1024 + "abcdefghijklm\u1234nopqrstuvwxyz";
+test_replace(not_found_2, not_found_2, "+", "---");
+
+var not_found_3 = prefix1024 + "abcdefghijklmnopqrstuvwxyz";
+test_replace(not_found_3, not_found_3, "\u1234", "ZZZ");
+
+// Deep cons tree.
+var nested_1 = "";
+for (var i = 0; i < 100000; i++) nested_1 += "y";
+var nested_1_result = prefix1024 + nested_1 + "aa";
+nested_1 = prefix1024 + nested_1 + "z";
+test_replace(nested_1, nested_1_result, "z", "aa");
+
+var nested_2 = "\u2244";
+for (var i = 0; i < 100000; i++) nested_2 += "y";
+var nested_2_result = prefix1024 + nested_2 + "aa";
+nested_2 = prefix1024 + nested_2 + "\u2012";
+test_replace(nested_2, nested_2_result, "\u2012", "aa");
+
+// Sliced string as input. A cons string is always flattened before sliced.
+var slice_1 = ("ab" + prefix1024 + "cdefghijklmnopqrstuvwxyz").slice(1, -1);
+var slice_1_result = "b" + prefix1024 + "cdefghijklmnopqrstuvwxQ";
+test_replace(slice_1, slice_1_result, "y", "Q");
+
+var slice_2 = (prefix1024 + "abcdefghijklmno\u1234\u1234p").slice(1, -1);
+var slice_2_result = prefix1024.substr(1) + "abcdefghijklmnoQ\u1234";
+test_replace(slice_2, slice_2_result, "\u1234", "Q");
diff --git a/test/mjsunit/string-slices-regexp.js b/test/mjsunit/string-slices-regexp.js
index a8cadaed..98b8ef9d 100644
--- a/test/mjsunit/string-slices-regexp.js
+++ b/test/mjsunit/string-slices-regexp.js
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// 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:
@@ -24,11 +24,6 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Flags: --string-slices
-
-//assertEquals('345"12345 6"1234567"123',
-// '12345""12345 6""1234567""1234'.slice(2,-1).replace(/""/g, '"'));
var foo = "lsdfj sldkfj sdklfj læsdfjl sdkfjlsdk fjsdl fjsdljskdj flsj flsdkj flskd regexp: /foobar/\nldkfj sdlkfj sdkl";
for(var i = 0; i < 1000; i++) {
diff --git a/test/mjsunit/string-slices.js b/test/mjsunit/string-slices.js
index 8cc1f81e..5b1dc360 100755
--- a/test/mjsunit/string-slices.js
+++ b/test/mjsunit/string-slices.js
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// 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:
@@ -25,7 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Flags: --string-slices --expose-externalize-string
+// Flags: --expose-externalize-string --allow-natives-syntax
var s = 'abcdefghijklmn';
assertEquals(s, s.substr());
@@ -100,14 +100,7 @@ for (var i = 5; i < 25; i++) {
// Keep creating strings to to force allocation failure on substring creation.
var x = "0123456789ABCDEF";
-x += x; // 2^5
-x += x;
-x += x;
-x += x;
-x += x;
-x += x; // 2^10
-x += x;
-x += x;
+for (var i = 0; i < 8; i++) x += x;
var xl = x.length;
var cache = [];
for (var i = 0; i < 1000; i++) {
@@ -119,14 +112,7 @@ for (var i = 0; i < 1000; i++) {
// Same with two-byte strings
var x = "\u2028123456789ABCDEF";
-x += x; // 2^5
-x += x;
-x += x;
-x += x;
-x += x;
-x += x; // 2^10
-x += x;
-x += x;
+for (var i = 0; i < 8; i++) x += x;
var xl = x.length;
var cache = [];
for (var i = 0; i < 1000; i++) {
@@ -174,6 +160,23 @@ for ( var i = 0; i < 1000; i++) {
f(flat, cons, slice, i);
}
+// Short substrings.
+flat = "abcdefghijkl12345";
+cons = flat + flat.toUpperCase();
+/x/.exec(cons); // Flatten cons
+slice = "abcdefghijklmn12345".slice(1, -1);
+assertEquals("cdefg", flat.substr(2, 5));
+assertEquals("cdefg", cons.substr(2, 5));
+assertEquals("cdefg", slice.substr(1, 5));
+
+flat = "abc\u1234defghijkl12345";
+cons = flat + flat.toUpperCase();
+/x/.exec(cons); // Flatten cons
+slice = "abc\u1234defghijklmn12345".slice(1, -1);
+assertEquals("c\u1234def", flat.substr(2, 5));
+assertEquals("c\u1234def", cons.substr(2, 5));
+assertEquals("c\u1234def", slice.substr(1, 5));
+
// Concatenate substrings.
var ascii = 'abcdefghijklmnop';
var utf = '\u03B1\u03B2\u03B3\u03B4\u03B5\u03B6\u03B7\u03B8\u03B9\u03BA\u03BB';
@@ -189,11 +192,34 @@ assertEquals("\u03B4\u03B5\u03B6\u03B7\u03B8\u03B9abcdefghijklmnop",
assertEquals("\u03B2\u03B3\u03B4\u03B5\u03B4\u03B5\u03B6\u03B7",
utf.substring(5,1) + utf.substring(3,7));
-/*
// Externalizing strings.
-var a = "123456789qwertyuiopasdfghjklzxcvbnm";
-var b = a.slice(1,-1);
+var a = "123456789" + "qwertyuiopasdfghjklzxcvbnm";
+var b = "23456789qwertyuiopasdfghjklzxcvbn"
assertEquals(a.slice(1,-1), b);
-externalizeString(a);
+
+assertTrue(isAsciiString(a));
+externalizeString(a, true);
+assertFalse(isAsciiString(a));
+
assertEquals(a.slice(1,-1), b);
-*/
+assertTrue(/3456789qwe/.test(a));
+assertEquals(5, a.indexOf("678"));
+assertEquals("12345", a.split("6")[0]);
+
+// Create a slice with an external string as parent string.
+var c = a.slice(1,-1);
+
+function test_crankshaft() {
+ for (var i = 0; i < 20; i++) {
+ assertEquals(b.charAt(i), a.charAt(i + 1));
+ assertEquals(b.charAt(i), c.charAt(i));
+ assertEquals(b.charAt(4), c.charAt(4));
+ assertTrue(/3456789qwe/.test(c));
+ assertEquals(4, c.indexOf("678"));
+ assertEquals("2345", c.split("6")[0]);
+ }
+}
+
+test_crankshaft();
+%OptimizeFunctionOnNextCall(test_crankshaft);
+test_crankshaft(); \ No newline at end of file
diff --git a/test/mjsunit/switch.js b/test/mjsunit/switch.js
index 180f994a..6a61fe59 100644
--- a/test/mjsunit/switch.js
+++ b/test/mjsunit/switch.js
@@ -25,6 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Flags: --allow-natives-syntax
+
function f0() {
switch (0) {
// switch deliberately left empty
@@ -126,6 +128,42 @@ assertEquals(3, f4(1), "fallthrough-switch.1");
assertEquals(3, f4(2), "fallthrough-switch.2");
assertEquals(5, f4(3), "fallthrough-switch.3");
+function f4_string(tag, x) {
+ switch(tag) {
+ case 'zero':
+ x++;
+ case 'two':
+ x++;
+ }
+ return x;
+}
+
+// Symbols
+assertEquals(2, f4_string('zero', 0), "fallthrough-string-switch.0");
+assertEquals(1, f4_string('one', 1), "fallthrough-string-switch.1");
+assertEquals(3, f4_string('two', 2), "fallthrough-string-switch.2");
+
+// Strings
+assertEquals(2, f4_string('_zero'.slice(1), 0), "fallthrough-string-switch.3");
+assertEquals(1, f4_string('_one'.slice(1), 1), "fallthrough-string-switch.4");
+assertEquals(3, f4_string('_two'.slice(1), 2), "fallthrough-string-switch.5");
+
+// Oddball
+assertEquals(3, f4_string(null, 3), "fallthrough-string-switch.6");
+
+// Test for regression
+function regress_string(value) {
+ var json = 1;
+ switch (typeof value) {
+ case 'object':
+ break;
+
+ default:
+
+ }
+ return json;
+};
+assertEquals(1, regress_string('object'), 'regression-string');
function f5(x) {
switch(x) {
@@ -287,3 +325,138 @@ var verylong_size = 1000;
var verylong = makeVeryLong(verylong_size);
assertEquals(verylong_size * 2 + 1, verylong());
+
+//
+// Test suite below aims to cover all possible combinations of following:
+//
+// clauses | tags | type feedback | optimization
+// =========================================================
+// strings | symbol | all | on
+// smis | string | target | off
+// mixed | oddball | non-target |
+// | smis | none |
+// | heapnum | |
+// =========================================================
+
+// Function-with-switch generator
+var test_id = 0,
+ clause_values = {
+ string: ['abc', 'def', 'ghi', 'jkl'],
+ smi: [1, 2, 3, 4],
+ mixed: ['abc', 1, 'def', 2, 'ghi', 3, 'jkl', 4]
+ };
+
+function switch_gen(clause_type, feedback, optimize) {
+ var values = clause_values[clause_type];
+
+ function opt(fn) {
+ if (feedback === 'all') {
+ values.forEach(fn);
+ } else if (Array.isArray(feedback)) {
+ // Non-target
+ values.filter(function(v) {
+ return feedback.indexOf(v) === -1;
+ }).forEach(fn);
+ } else if (feedback !== undefined) {
+ // Target
+ fn(feedback);
+ } else {
+ // None
+ }
+
+ if (optimize) %OptimizeFunctionOnNextCall(fn);
+
+ return fn;
+ };
+
+ return opt(new Function(
+ 'tag',
+ '"' + (test_id++) + '";' +
+ 'switch(tag) {' +
+ values.map(function(value) {
+ return 'case ' + JSON.stringify(value) + ': return' +
+ JSON.stringify('ok-' + value);
+ }).join(';') +
+ '}'
+ ));
+};
+
+function test_switch(clause_type, test_type, feedback, optimize) {
+ var pairs = [],
+ fn = switch_gen(clause_type, feedback, optimize);
+
+ if (Array.isArray(test_type)) {
+ pairs = test_type.map(function(v) {
+ return {
+ value: v,
+ expected: 'ok-' + v
+ };
+ });
+ } else if (test_type === 'symbols') {
+ pairs = clause_values.string.map(function(v) {
+ return {
+ value: v,
+ expected: clause_type !== 'smi' ? 'ok-' + v : undefined
+ };
+ });
+ } else if (test_type === 'strings') {
+ pairs = clause_values.string.map(function(v) {
+ return {
+ value: ('%%' + v).slice(2),
+ expected: clause_type !== 'smi' ? 'ok-' + v : undefined
+ };
+ });
+ } else if (test_type === 'oddball') {
+ pairs = [
+ { value: null, expected: undefined },
+ { value: NaN, expected: undefined },
+ { value: undefined, expected: undefined }
+ ];
+ } else if (test_type === 'smi') {
+ pairs = clause_values.smi.map(function(v) {
+ return {
+ value: v,
+ expected: clause_type !== 'string' ? 'ok-' + v : undefined
+ };
+ });
+ } else if (test_type === 'heapnum') {
+ pairs = clause_values.smi.map(function(v) {
+ return {
+ value: ((v * 17)/16) - ((v*17)%16/16),
+ expected: clause_type !== 'string' ? 'ok-' + v : undefined
+ };
+ });
+ }
+
+ pairs.forEach(function(pair) {
+ assertEquals(fn(pair.value), pair.expected);
+ });
+};
+
+// test_switch(clause_type, test_type, feedback, optimize);
+
+function test_switches(opt) {
+ var test_types = ['symbols', 'strings', 'oddball', 'smi', 'heapnum'];
+
+ function test(clause_type) {
+ var values = clause_values[clause_type];
+
+ test_types.forEach(function(test_type) {
+ test_switch(clause_type, test_type, 'all', opt);
+ test_switch(clause_type, test_type, 'none', opt);
+
+ // Targeting specific clause feedback
+ values.forEach(function(value) {
+ test_switch(clause_type, test_type, [value], value, opt);
+ test_switch(clause_type, test_type, value, value, opt);
+ });
+ });
+ };
+
+ test('string');
+ test('smi');
+ test('mixed');
+};
+
+test_switches(false);
+test_switches(true);
diff --git a/test/mjsunit/to_number_order.js b/test/mjsunit/to_number_order.js
index d17e6000..50e4bc76 100644
--- a/test/mjsunit/to_number_order.js
+++ b/test/mjsunit/to_number_order.js
@@ -161,7 +161,7 @@ assertEquals("fiskfisk", x, "Compare objects b >= b valueOf order");
x = "";
assertFalse(a > b, "Compare objects a > b");
-assertEquals("fiskhest", x, "Compare objects a > b valueOf order");
+assertEquals("hestfisk", x, "Compare objects a > b valueOf order");
x = "";
assertFalse(a > void(0), "Compare objects a > undefined");
@@ -195,7 +195,7 @@ function identical_object_comparison() {
x = "";
assertFalse(a > b, "Compare objects a > b");
- assertEquals("fiskhest", x, "Compare objects a > b valueOf order");
+ assertEquals("hestfisk", x, "Compare objects a > b valueOf order");
x = "";
assertFalse(a > void(0), "Compare objects a > undefined");
diff --git a/test/mjsunit/tools/tickprocessor.js b/test/mjsunit/tools/tickprocessor.js
index 30b0ec23..c48d9f3a 100644
--- a/test/mjsunit/tools/tickprocessor.js
+++ b/test/mjsunit/tools/tickprocessor.js
@@ -376,8 +376,11 @@ function driveTickProcessorTest(
}
assertTrue(pathLen != -1);
var testsPath = TEST_FILE_NAME.substr(0, pathLen + 1);
- var tp = new TickProcessor(
- new CppEntriesProviderMock(), separateIc, ignoreUnknown, stateFilter);
+ var tp = new TickProcessor(new CppEntriesProviderMock(),
+ separateIc,
+ TickProcessor.CALL_GRAPH_SIZE,
+ ignoreUnknown,
+ stateFilter);
var pm = new PrintMonitor(testsPath + refOutput);
tp.processLogFileInTest(testsPath + logInput);
tp.printStatistics();
diff --git a/test/mjsunit/unbox-double-arrays.js b/test/mjsunit/unbox-double-arrays.js
index feecaec8..fd7db28a 100644
--- a/test/mjsunit/unbox-double-arrays.js
+++ b/test/mjsunit/unbox-double-arrays.js
@@ -77,8 +77,6 @@ function testOneArrayType(allocator) {
assertEquals(value_6, a[6]);
assertEquals(value_6, a[computed_6()]); // Test non-constant key
assertEquals(value_7, a[7]);
- assertEquals(undefined, a[large_array_size-1]);
- assertEquals(undefined, a[-1]);
assertEquals(large_array_size, a.length);
assertTrue(%HasFastDoubleElements(a));
}
@@ -89,8 +87,6 @@ function testOneArrayType(allocator) {
assertEquals(value_6, a[6]);
assertEquals(value_6, a[computed_6()]); // Test non-constant key
assertEquals(value_7, a[7]);
- assertEquals(undefined, a[large_array_size-1]);
- assertEquals(undefined, a[-1]);
assertEquals(large_array_size, a.length);
assertTrue(%HasFastDoubleElements(a));
}
@@ -101,8 +97,6 @@ function testOneArrayType(allocator) {
assertEquals(value_6, a[6]);
assertEquals(value_6, a[computed_6()]); // Test non-constant key
assertEquals(value_7, a[7]);
- assertEquals(undefined, a[large_array_size-1]);
- assertEquals(undefined, a[-1]);
assertEquals(large_array_size, a.length);
assertTrue(%HasFastDoubleElements(a));
}
@@ -113,32 +107,40 @@ function testOneArrayType(allocator) {
assertEquals(value_6, a[6]);
assertEquals(value_6, a[computed_6()]); // Test non-constant key
assertEquals(value_7, a[7]);
- assertEquals(undefined, a[large_array_size-1]);
- assertEquals(undefined, a[-1]);
assertEquals(large_array_size, a.length);
assertTrue(%HasFastDoubleElements(a));
}
function test_various_loads5(a, value_5, value_6, value_7) {
assertTrue(%HasFastDoubleElements(a));
+ if (value_5 != undefined) {
+ assertEquals(value_5, a[5]);
+ };
+ if (value_6 != undefined) {
+ assertEquals(value_6, a[6]);
+ assertEquals(value_6, a[computed_6()]); // Test non-constant key
+ }
+ assertEquals(value_7, a[7]);
+ assertEquals(large_array_size, a.length);
+ assertTrue(%HasFastDoubleElements(a));
+ }
+
+ function test_various_loads6(a, value_5, value_6, value_7) {
+ assertTrue(%HasFastDoubleElements(a));
assertEquals(value_5, a[5]);
assertEquals(value_6, a[6]);
assertEquals(value_6, a[computed_6()]); // Test non-constant key
assertEquals(value_7, a[7]);
- assertEquals(undefined, a[large_array_size-1]);
- assertEquals(undefined, a[-1]);
assertEquals(large_array_size, a.length);
assertTrue(%HasFastDoubleElements(a));
}
- function test_various_loads6(a, value_5, value_6, value_7) {
+ function test_various_loads7(a, value_5, value_6, value_7) {
assertTrue(%HasFastDoubleElements(a));
assertEquals(value_5, a[5]);
assertEquals(value_6, a[6]);
assertEquals(value_6, a[computed_6()]); // Test non-constant key
assertEquals(value_7, a[7]);
- assertEquals(undefined, a[large_array_size-1]);
- assertEquals(undefined, a[-1]);
assertEquals(large_array_size, a.length);
assertTrue(%HasFastDoubleElements(a));
}
@@ -248,6 +250,8 @@ function testOneArrayType(allocator) {
expected_array_value(7));
// Make sure Crankshaft code handles the hole correctly (bailout)
+ var large_array = new allocator(large_array_size);
+ force_to_fast_double_array(large_array);
test_various_stores(large_array,
expected_array_value(5),
expected_array_value(6),
@@ -273,7 +277,12 @@ function testOneArrayType(allocator) {
undefined,
expected_array_value(7));
+ %DeoptimizeFunction(test_various_loads6);
+ gc();
+
// Test stores for non-NaN.
+ var large_array = new allocator(large_array_size);
+ force_to_fast_double_array(large_array);
%OptimizeFunctionOnNextCall(test_various_stores);
test_various_stores(large_array,
expected_array_value(5),
@@ -285,7 +294,19 @@ function testOneArrayType(allocator) {
expected_array_value(6),
expected_array_value(7));
- test_various_loads6(large_array,
+ test_various_loads7(large_array,
+ expected_array_value(5),
+ expected_array_value(6),
+ expected_array_value(7));
+
+ test_various_loads7(large_array,
+ expected_array_value(5),
+ expected_array_value(6),
+ expected_array_value(7));
+
+ %OptimizeFunctionOnNextCall(test_various_loads7);
+
+ test_various_loads7(large_array,
expected_array_value(5),
expected_array_value(6),
expected_array_value(7));
@@ -301,7 +322,7 @@ function testOneArrayType(allocator) {
-NaN,
expected_array_value(7));
- test_various_loads6(large_array,
+ test_various_loads7(large_array,
NaN,
-NaN,
expected_array_value(7));
@@ -317,7 +338,7 @@ function testOneArrayType(allocator) {
-Infinity,
expected_array_value(7));
- test_various_loads6(large_array,
+ test_various_loads7(large_array,
Infinity,
-Infinity,
expected_array_value(7));
@@ -434,7 +455,6 @@ large_array3[3] = Infinity;
large_array3[4] = -Infinity;
function call_apply() {
- assertTrue(%HasFastDoubleElements(large_array3));
called_by_apply.apply({}, large_array3);
}
@@ -449,7 +469,6 @@ call_apply();
function test_for_in() {
// Due to previous tests, keys 0..25 and 95 should be present.
next_expected = 0;
- assertTrue(%HasFastDoubleElements(large_array3));
for (x in large_array3) {
assertTrue(next_expected++ == x);
if (next_expected == 25) {
diff --git a/test/mjsunit/undeletable-functions.js b/test/mjsunit/undeletable-functions.js
index 04fd0606..635ea6fa 100644
--- a/test/mjsunit/undeletable-functions.js
+++ b/test/mjsunit/undeletable-functions.js
@@ -25,11 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Test that we match JSC in making some functions undeletable.
-// See http://code.google.com/p/chromium/issues/detail?id=1717
-// The functions on these prototypes are not just undeletable. It is
-// possible to override them with new definitions, then get the old
-// version back by deleting the new definition.
+// Test that we match ECMAScript in making most builtin functions
+// deletable and only specific ones undeletable or read-only.
var array;
@@ -37,7 +34,7 @@ array = [
"toString", "toLocaleString", "join", "pop", "push", "concat", "reverse",
"shift", "unshift", "slice", "splice", "sort", "filter", "forEach", "some",
"every", "map", "indexOf", "lastIndexOf", "reduce", "reduceRight"];
-CheckJSCSemantics(Array.prototype, array, "Array prototype");
+CheckEcmaSemantics(Array.prototype, array, "Array prototype");
var old_Array_prototype = Array.prototype;
var new_Array_prototype = {};
@@ -57,12 +54,12 @@ array = [
"setUTCMinutes", "setHours", "setUTCHours", "setDate", "setUTCDate",
"setMonth", "setUTCMonth", "setFullYear", "setUTCFullYear", "toGMTString",
"toUTCString", "getYear", "setYear", "toISOString", "toJSON"];
-CheckJSCSemantics(Date.prototype, array, "Date prototype");
+CheckEcmaSemantics(Date.prototype, array, "Date prototype");
array = [
"random", "abs", "acos", "asin", "atan", "ceil", "cos", "exp", "floor", "log",
"round", "sin", "sqrt", "tan", "atan2", "pow", "max", "min"];
-CheckJSCSemantics(Math, array, "Math1");
+CheckEcmaSemantics(Math, array, "Math1");
CheckEcmaSemantics(Date, ["UTC", "parse", "now"], "Date");
@@ -76,6 +73,8 @@ array = [
"execScript"];
CheckEcmaSemantics(this, array, "Global");
CheckReadOnlyAttr(this, "Infinity");
+CheckReadOnlyAttr(this, "NaN");
+CheckReadOnlyAttr(this, "undefined");
array = ["exec", "test", "toString", "compile"];
CheckEcmaSemantics(RegExp.prototype, array, "RegExp prototype");
@@ -112,7 +111,7 @@ array = [
"toUpperCase", "toLocaleUpperCase", "link", "anchor", "fontcolor", "fontsize",
"big", "blink", "bold", "fixed", "italics", "small", "strike", "sub", "sup",
"toJSON", "toString", "valueOf"];
-CheckJSCSemantics(String.prototype, array, "String prototype");
+CheckEcmaSemantics(String.prototype, array, "String prototype");
CheckEcmaSemantics(String, ["fromCharCode"], "String");
@@ -124,14 +123,6 @@ function CheckEcmaSemantics(type, props, name) {
}
-function CheckJSCSemantics(type, props, name) {
- print(name);
- for (var i = 0; i < props.length; i++) {
- CheckNotDeletable(type, props[i]);
- }
-}
-
-
function CheckDontDelete(type, props, name) {
print(name);
for (var i = 0; i < props.length; i++) {
@@ -154,21 +145,6 @@ function CheckDeletable(type, prop) {
}
-function CheckNotDeletable(type, prop) {
- var old = type[prop];
- if (!type[prop]) return;
- assertTrue(type.hasOwnProperty(prop), "inherited: " + prop);
- var deleted = delete type[prop];
- assertTrue(deleted, "delete operator returned false: " + prop);
- assertTrue(type.hasOwnProperty(prop), "not there after delete: " + prop);
- type[prop] = "foo";
- assertEquals("foo", type[prop], "not overwritable: " + prop);
- deleted = delete type[prop];
- assertTrue(deleted, "delete operator returned false 2nd time: " + prop);
- assertEquals(old.toString(), type[prop].toString(), "delete didn't restore the old value: " + prop);
-}
-
-
function CheckDontDeleteAttr(type, prop) {
var old = type[prop];
if (!type[prop]) return;
@@ -189,7 +165,7 @@ function CheckReadOnlyAttr(type, prop) {
assertFalse(deleted, "delete operator returned true: " + prop);
assertTrue(type.hasOwnProperty(prop), "not there after delete: " + prop);
type[prop] = "foo";
- assertEquals("foo", type[prop], "overwritable: " + prop);
+ assertEquals(old, type[prop], "overwritable: " + prop);
}
print("OK");
diff --git a/test/mozilla/mozilla.status b/test/mozilla/mozilla.status
index 3a271309..e64959ac 100644
--- a/test/mozilla/mozilla.status
+++ b/test/mozilla/mozilla.status
@@ -1,4 +1,4 @@
-# Copyright 2009 the V8 project authors. All rights reserved.
+# 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:
@@ -69,6 +69,8 @@ js1_5/Array/regress-465980-02: SKIP
ecma_3/Date/15.9.3.2-1: SKIP
js1_2/function/Number: SKIP
+# TODO(2018): Temporarily allow timeout in debug mode.
+js1_5/GC/regress-203278-2: PASS || TIMEOUT if $mode == debug
##################### SLOW TESTS #####################
@@ -123,14 +125,14 @@ ecma/Date/15.9.2.2-4: PASS || FAIL
ecma/Date/15.9.2.2-5: PASS || FAIL
ecma/Date/15.9.2.2-6: PASS || FAIL
-# 1026139: These date tests fail on arm
-ecma/Date/15.9.5.29-1: PASS || ($ARM && FAIL)
-ecma/Date/15.9.5.34-1: PASS || ($ARM && FAIL)
-ecma/Date/15.9.5.28-1: PASS || ($ARM && FAIL)
+# 1026139: These date tests fail on arm and mips
+ecma/Date/15.9.5.29-1: PASS || (($ARM || $MIPS) && FAIL)
+ecma/Date/15.9.5.34-1: PASS || (($ARM || $MIPS) && FAIL)
+ecma/Date/15.9.5.28-1: PASS || (($ARM || $MIPS) && FAIL)
-# 1050186: Arm vm is broken; probably unrelated to dates
-ecma/Array/15.4.4.5-3: PASS || ($ARM && FAIL)
-ecma/Date/15.9.5.22-2: PASS || ($ARM && FAIL)
+# 1050186: Arm/MIPS vm is broken; probably unrelated to dates
+ecma/Array/15.4.4.5-3: PASS || (($ARM || $MIPS) && FAIL)
+ecma/Date/15.9.5.22-2: PASS || (($ARM || $MIPS) && FAIL)
# Flaky test that fails due to what appears to be a bug in the test.
# Occurs depending on current time
@@ -214,6 +216,10 @@ js1_5/Array/regress-101964: PASS || FAIL if $mode == debug
# builtin to have undefined as the receiver.
ecma/String/15.5.4.6-2: FAIL_OK
+# Fail because it expects String.prototype.split to distinguish whether
+# separator was undefined or not passed at all.
+ecma/String/15.5.4.8-2: FAIL_OK
+
# Fail because of toLowerCase and toUpperCase conversion.
ecma/String/15.5.4.11-2: FAIL_OK
ecma/String/15.5.4.11-5: FAIL_OK
@@ -227,7 +233,7 @@ ecma/String/15.5.4.12-4: FAIL_OK
ecma/String/15.5.4.12-5: FAIL_OK
# Creates a linked list of arrays until we run out of memory or timeout.
-js1_5/Regress/regress-312588: FAIL || TIMEOUT
+js1_5/Regress/regress-312588: SKIP
# Runs out of memory because it compiles huge functions.
@@ -301,6 +307,11 @@ js1_2/regexp/RegExp_multiline_as_array: FAIL_OK
js1_2/regexp/beginLine: FAIL_OK
js1_2/regexp/endLine: FAIL_OK
+# We no longer let calls to test and exec with no argument implicitly
+# use the previous input.
+js1_2/regexp/RegExp_input: FAIL_OK
+js1_2/regexp/RegExp_input_as_array: FAIL_OK
+
# To be compatible with safari typeof a regexp yields 'function';
# in firefox it yields 'object'.
@@ -411,12 +422,6 @@ js1_5/extensions/regress-435345-01: FAIL_OK
js1_5/extensions/regress-455413: FAIL_OK
-# The spec specifies reverse evaluation order for < and >=.
-# See section 11.8.2 and 11.8.5.
-# We implement the spec here but the test tests the more straigtforward order.
-ecma_3/Operators/order-01: FAIL_OK
-
-
# Uses Mozilla-specific QName, XML, XMLList and Iterator.
js1_5/Regress/regress-407323: FAIL_OK
js1_5/Regress/regress-407957: FAIL_OK
@@ -619,6 +624,10 @@ js1_5/Expressions/regress-394673: FAIL
# We do not correctly handle assignments within "with"
/ecma_3/Statements/12.10-01: FAIL
+# We do not throw an exception when a const is redeclared.
+# (We only fail section 1 of the test.)
+js1_5/Regress/regress-103602: FAIL
+
##################### MOZILLA EXTENSION TESTS #####################
ecma/extensions/15.1.2.1-1: FAIL_OK
@@ -861,3 +870,59 @@ ecma/Expressions/11.7.3: SKIP
ecma/Expressions/11.10-3: SKIP
ecma/Expressions/11.7.1: SKIP
ecma_3/RegExp/regress-209067: SKIP
+
+[ $arch == mips ]
+
+# Times out and print so much output that we need to skip it to not
+# hang the builder.
+js1_5/extensions/regress-342960: SKIP
+
+# BUG(3251229): Times out when running new crankshaft test script.
+ecma_3/RegExp/regress-311414: SKIP
+ecma/Date/15.9.5.8: SKIP
+ecma/Date/15.9.5.10-2: SKIP
+ecma/Date/15.9.5.11-2: SKIP
+ecma/Date/15.9.5.12-2: SKIP
+js1_5/Array/regress-99120-02: SKIP
+js1_5/extensions/regress-371636: SKIP
+js1_5/Regress/regress-203278-1: SKIP
+js1_5/Regress/regress-404755: SKIP
+js1_5/Regress/regress-451322: SKIP
+
+
+# BUG(1040): Allow this test to timeout.
+js1_5/GC/regress-203278-2: PASS || TIMEOUT
+
+
+[ $fast == yes && $arch == mips ]
+
+# In fast mode on mips we try to skip all tests that would time out,
+# since running the tests takes so long in the first place.
+
+js1_5/Regress/regress-280769-2: SKIP
+js1_5/Regress/regress-280769-3: SKIP
+js1_5/Regress/regress-244470: SKIP
+js1_5/Regress/regress-203278-1: SKIP
+js1_5/Regress/regress-290575: SKIP
+js1_5/Regress/regress-159334: SKIP
+js1_5/Regress/regress-321971: SKIP
+js1_5/Regress/regress-347306-01: SKIP
+js1_5/Regress/regress-280769-1: SKIP
+js1_5/Regress/regress-280769-5: SKIP
+js1_5/GC/regress-306788: SKIP
+js1_5/GC/regress-278725: SKIP
+js1_5/GC/regress-203278-3: SKIP
+js1_5/GC/regress-311497: SKIP
+js1_5/Array/regress-99120-02: SKIP
+ecma/Date/15.9.5.22-1: SKIP
+ecma/Date/15.9.5.20: SKIP
+ecma/Date/15.9.5.12-2: SKIP
+ecma/Date/15.9.5.8: SKIP
+ecma/Date/15.9.5.9: SKIP
+ecma/Date/15.9.5.11-2: SKIP
+ecma/Expressions/11.7.2: SKIP
+ecma/Expressions/11.10-2: SKIP
+ecma/Expressions/11.7.3: SKIP
+ecma/Expressions/11.10-3: SKIP
+ecma/Expressions/11.7.1: SKIP
+ecma_3/RegExp/regress-209067: SKIP
diff --git a/test/preparser/preparser.status b/test/preparser/preparser.status
index db177782..6f15fedd 100644
--- a/test/preparser/preparser.status
+++ b/test/preparser/preparser.status
@@ -31,9 +31,3 @@ prefix preparser
# escapes (we need to parse to distinguish octal escapes from valid
# back-references).
strict-octal-regexp: FAIL
-
-##############################################################################
-[ $arch == mips ]
-
-# Skip all tests on MIPS.
-*: SKIP
diff --git a/test/preparser/strict-identifiers.pyt b/test/preparser/strict-identifiers.pyt
index 72808e25..aa3d5210 100644
--- a/test/preparser/strict-identifiers.pyt
+++ b/test/preparser/strict-identifiers.pyt
@@ -138,6 +138,38 @@ setter_arg = StrictTemplate("setter-param-$id", """
var x = {set foo($id) { }};
""")
+label_normal = Template("label-normal-$id", """
+ $id: '';
+""")
+
+label_strict = StrictTemplate("label-strict-$id", """
+ $id: '';
+""")
+
+break_normal = Template("break-normal-$id", """
+ for (;;) {
+ break $id;
+ }
+""")
+
+break_strict = StrictTemplate("break-strict-$id", """
+ for (;;) {
+ break $id;
+ }
+""")
+
+continue_normal = Template("continue-normal-$id", """
+ for (;;) {
+ continue $id;
+ }
+""")
+
+continue_strict = StrictTemplate("continue-strict-$id", """
+ for (;;) {
+ continue $id;
+ }
+""")
+
non_strict_use = Template("nonstrict-$id", """
var $id = 42;
$id++;
@@ -162,6 +194,7 @@ non_strict_use = Template("nonstrict-$id", """
function $id($id) { }
x = {$id: 42};
x = {get $id() {}, set $id(value) {}};
+ $id: '';
""")
identifier_name_source = """
@@ -197,6 +230,12 @@ for id in ["eval", "arguments"]:
prefix_var({"id": id, "op":"--", "opname":"dec"}, "strict_lhs_prefix")
postfix_var({"id": id, "op":"++", "opname":"inc"}, "strict_lhs_postfix")
postfix_var({"id": id, "op":"--", "opname":"dec"}, "strict_lhs_postfix")
+ label_normal({"id": id}, None)
+ label_strict({"id": id}, None)
+ break_normal({"id": id}, None)
+ break_strict({"id": id}, None)
+ continue_normal({"id": id}, None)
+ continue_strict({"id": id}, None)
non_strict_use({"id": id}, None)
@@ -205,10 +244,13 @@ for id in ["eval", "arguments"]:
for reserved_word in reserved_words + strict_reserved_words:
if (reserved_word in strict_reserved_words):
message = "strict_reserved_word"
+ label_message = None
elif (reserved_word == "const"):
message = "unexpected_token"
+ label_message = message
else:
message = "reserved_word"
+ label_message = message
arg_name_own({"id":reserved_word}, message)
arg_name_nested({"id":reserved_word}, message)
setter_arg({"id": reserved_word}, message)
@@ -225,6 +267,19 @@ for reserved_word in reserved_words + strict_reserved_words:
read_var({"id": reserved_word}, message)
identifier_name({"id": reserved_word}, None);
identifier_name_strict({"id": reserved_word}, None);
+ label_normal({"id": reserved_word}, label_message)
+ break_normal({"id": reserved_word}, label_message)
+ continue_normal({"id": reserved_word}, label_message)
+ if (reserved_word == "const"):
+ # The error message for this case is different because
+ # ParseLabelledStatementOrExpression will try to parse this as an expression
+ # first, effectively disallowing the use in ParseVariableDeclarations, i.e.
+ # the preparser never sees that 'const' was intended to be a label.
+ label_strict({"id": reserved_word}, "strict_const")
+ else:
+ label_strict({"id": reserved_word}, message)
+ break_strict({"id": reserved_word}, message)
+ continue_strict({"id": reserved_word}, message)
# Future reserved words in strict mode behave like normal identifiers
diff --git a/test/sputnik/sputnik.status b/test/sputnik/sputnik.status
index 868509d7..a4c7d57f 100644
--- a/test/sputnik/sputnik.status
+++ b/test/sputnik/sputnik.status
@@ -30,10 +30,6 @@ def FAIL_OK = FAIL, OKAY
############################### BUGS ###################################
-# A bound function should fail on access to 'caller' and 'arguments'.
-S15.3.4.5_A1: FAIL
-S15.3.4.5_A2: FAIL
-
# '__proto__' should be treated as a normal property in JSON.
S15.12.2_A1: FAIL
@@ -46,11 +42,8 @@ S15.8.2.16_A7: PASS || FAIL_OK
S15.8.2.18_A7: PASS || FAIL_OK
S15.8.2.13_A23: PASS || FAIL_OK
-# We allow calls to regexp exec() with no arguments to fail for
-# compatibility reasons.
-S15.10.6.2_A1_T16: FAIL_OK
-S15.10.6.2_A12: FAIL_OK
-S15.10.6.3_A1_T16: FAIL_OK
+# Sputnik tests (r97) assume RegExp.prototype is an Object, not a RegExp.
+S15.10.6_A2: FAIL_OK
# We are silent in some regexp cases where the spec wants us to give
# errors, for compatibility.
@@ -132,6 +125,13 @@ S15.5.2_D2: PASS || FAIL_OK
S15.5.4.11_D1.1_T1: PASS || FAIL_OK
S15.5.4.11_D1.1_T3: PASS || FAIL_OK
S12.6.4_D1: PASS || FAIL_OK
+S15.5.4.14_A1_T6: FAIL_OK
+S15.5.4.14_A1_T7: FAIL_OK
+S15.5.4.14_A1_T8: FAIL_OK
+S15.5.4.14_A1_T9: FAIL_OK
+S15.5.4.14_A2_T7: FAIL_OK
+S15.10.2.12_A1_T1: FAIL_OK
+S15.10.2.12_A2_T1: FAIL_OK
# We allow function declarations within statements
S12.6.2_A13_T1: FAIL_OK
@@ -159,6 +159,10 @@ S11.1.5_A4.2: FAIL_OK
S9.9_A1: FAIL_OK
S9.9_A2: FAIL_OK
+# The expected evaluation order of comparison operations changed.
+S11.8.2_A2.3_T1: FAIL_OK
+S11.8.3_A2.3_T1: FAIL_OK
+
# Calls builtins without an explicit receiver which means that
# undefined is passed to the builtin. The tests expect the global
# object to be passed which was true in ES3 but not in ES5.
@@ -176,6 +180,22 @@ S15.5.4.13_A1_T3: FAIL_OK
S15.5.4.14_A1_T3: FAIL_OK
S15.5.4.15_A1_T3: FAIL_OK
+# NaN, Infinity and undefined are read-only according to ES5.
+S15.1.1.1_A2_T1: FAIL_OK # NaN
+S15.1.1.1_A2_T2: FAIL_OK # NaN
+S15.1.1.2_A2_T1: FAIL_OK # Infinity
+# S15.1.1.2_A2_T2 would fail if it weren't bogus in r97. sputnik bug #45.
+S15.1.1.3_A2_T1: FAIL_OK # undefined
+S15.1.1.3_A2_T2: FAIL_OK # undefined
+
+# Function.prototype.apply can handle arbitrary object as argument list.
+S15.3.4.3_A6_T1: FAIL_OK
+S15.3.4.3_A6_T4: FAIL_OK
+
+# Array.prototype.to[Locale]String is generic in ES5.
+S15.4.4.2_A2_T1: FAIL_OK
+S15.4.4.3_A2_T1: FAIL_OK
+
##################### SKIPPED TESTS #####################
# These tests take a looong time to run in debug mode.
@@ -194,53 +214,6 @@ S15.3_A3_T1: FAIL
# Invalid test case (recent change adding var changes semantics)
S15.3_A3_T3: FAIL
-# These tests fail because we had to add bugs to be compatible with JSC. See
-# http://code.google.com/p/chromium/issues/detail?id=1717
-S15.5.4.1_A1_T2: FAIL_OK
-S15.5.4_A1: FAIL_OK
-S15.5.4_A3: FAIL_OK
-S15.9.5.10_A1_T2: FAIL_OK
-S15.9.5.11_A1_T2: FAIL_OK
-S15.9.5.12_A1_T2: FAIL_OK
-S15.9.5.13_A1_T2: FAIL_OK
-S15.9.5.14_A1_T2: FAIL_OK
-S15.9.5.15_A1_T2: FAIL_OK
-S15.9.5.16_A1_T2: FAIL_OK
-S15.9.5.17_A1_T2: FAIL_OK
-S15.9.5.18_A1_T2: FAIL_OK
-S15.9.5.19_A1_T2: FAIL_OK
-S15.9.5.20_A1_T2: FAIL_OK
-S15.9.5.21_A1_T2: FAIL_OK
-S15.9.5.22_A1_T2: FAIL_OK
-S15.9.5.23_A1_T2: FAIL_OK
-S15.9.5.24_A1_T2: FAIL_OK
-S15.9.5.25_A1_T2: FAIL_OK
-S15.9.5.26_A1_T2: FAIL_OK
-S15.9.5.27_A1_T2: FAIL_OK
-S15.9.5.28_A1_T2: FAIL_OK
-S15.9.5.29_A1_T2: FAIL_OK
-S15.9.5.2_A1_T2: FAIL_OK
-S15.9.5.30_A1_T2: FAIL_OK
-S15.9.5.31_A1_T2: FAIL_OK
-S15.9.5.32_A1_T2: FAIL_OK
-S15.9.5.33_A1_T2: FAIL_OK
-S15.9.5.34_A1_T2: FAIL_OK
-S15.9.5.35_A1_T2: FAIL_OK
-S15.9.5.36_A1_T2: FAIL_OK
-S15.9.5.37_A1_T2: FAIL_OK
-S15.9.5.38_A1_T2: FAIL_OK
-S15.9.5.39_A1_T2: FAIL_OK
-S15.9.5.3_A1_T2: FAIL_OK
-S15.9.5.40_A1_T2: FAIL_OK
-S15.9.5.41_A1_T2: FAIL_OK
-S15.9.5.42_A1_T2: FAIL_OK
-S15.9.5.4_A1_T2: FAIL_OK
-S15.9.5.5_A1_T2: FAIL_OK
-S15.9.5.6_A1_T2: FAIL_OK
-S15.9.5.7_A1_T2: FAIL_OK
-S15.9.5.8_A1_T2: FAIL_OK
-S15.9.5.9_A1_T2: FAIL_OK
-
[ $arch == arm ]
# BUG(3251225): Tests that timeout with --nocrankshaft.
@@ -257,5 +230,14 @@ S15.1.3.2_A2.5_T1: SKIP
[ $arch == mips ]
-# Skip all tests on MIPS.
-*: SKIP
+# BUG(3251225): Tests that timeout with --nocrankshaft.
+S15.1.3.1_A2.5_T1: SKIP
+S15.1.3.2_A2.5_T1: SKIP
+S15.1.3.1_A2.4_T1: SKIP
+S15.1.3.1_A2.5_T1: SKIP
+S15.1.3.2_A2.4_T1: SKIP
+S15.1.3.2_A2.5_T1: SKIP
+S15.1.3.3_A2.3_T1: SKIP
+S15.1.3.4_A2.3_T1: SKIP
+S15.1.3.1_A2.5_T1: SKIP
+S15.1.3.2_A2.5_T1: SKIP
diff --git a/test/test262/README b/test/test262/README
index ea6b4a71..dae18433 100644
--- a/test/test262/README
+++ b/test/test262/README
@@ -4,11 +4,11 @@ tests from
http://hg.ecmascript.org/tests/test262
-at revision 128 as 'data' in this directory. Using later version
+at revision 309 as 'data' in this directory. Using later version
may be possible but the tests are only known to pass (and indeed run)
with that revision.
-hg clone -r 128 http://hg.ecmascript.org/tests/test262 data
+hg clone -r 309 http://hg.ecmascript.org/tests/test262 data
If you do update to a newer revision you may have to change the test
harness adapter code since it uses internal functionality from the
diff --git a/test/test262/test262.status b/test/test262/test262.status
index 8cee2107..67607fff 100644
--- a/test/test262/test262.status
+++ b/test/test262/test262.status
@@ -25,1330 +25,94 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+prefix test262
+def FAIL_OK = FAIL, OKAY
-#
-# ietestcenter tests.
-#
-
-prefix ietestcenter
+############################### BUGS ###################################
+# '__proto__' should be treated as a normal property in JSON.
+S15.12.2_A1: FAIL
-#
-# Deliberate differences for compatibility with other browsers
-#
-# 15.9.5.43-0-9 and 15.9.5.43-0-10. V8 doesn't throw RangeError
-# from Date.prototype.toISOString when string is not a finite number.
-# This is compatible with Firefox and Safari.
-15.9.5.43-0-9: PASS || FAIL
-15.9.5.43-0-10: PASS || FAIL
-
-#
-# Unanalyzed failures which may be bugs or deliberate differences
-#
-
-# Bug? Strict Mode - TypeError is thrown when changing the value of a Value
-# Property of the Global Object under strict mode (NaN)
-10.2.1.1.3-4-16-s: FAIL
-# Bug? Strict Mode - TypeError is thrown when changing the value of a Value
-# Property of the Global Object under strict mode (undefined)
-10.2.1.1.3-4-18-s: FAIL
-# Invalid test: https://bugs.ecmascript.org/show_bug.cgi?id=76
-10.4.2-2-c-1: FAIL
-# BUG: 11.8.2 Greater-than Operator - Partial left to right order enforced
-# when using Greater-than operator: valueOf > valueOf
-11.8.2-1: FAIL
-# BUG: 11.8.2 Greater-than Operator - Partial left to right order enforced
-# when using Greater-than operator: valueOf > toString
-11.8.2-2: FAIL
-# BUG: 11.8.2 Greater-than Operator - Partial left to right order enforced
-# when using Greater-than operator: toString > valueOf
-11.8.2-3: FAIL
-# BUG: 11.8.2 Greater-than Operator - Partial left to right order enforced
-# when using Greater-than operator: toString > toString
-11.8.2-4: FAIL
-# BUG: 11.8.3 Less-than-or-equal Operator - Partial left to right order
-# enforced when using Less-than-or-equal operator: valueOf <= valueOf
-11.8.3-1: FAIL
-# BUG: 11.8.3 Less-than-or-equal Operator - Partial left to right order
-# enforced when using Less-than-or-equal operator: valueOf <= toString
-11.8.3-2: FAIL
-# BUG: 11.8.3 Less-than-or-equal Operator - Partial left to right order
-# enforced when using Less-than-or-equal operator: toString <= valueOf
-11.8.3-3: FAIL
-# BUG: 11.8.3 Less-than-or-equal Operator - Partial left to right order
-# enforced when using Less-than-or-equal operator: toString <= toString
-11.8.3-4: FAIL
-# BUG: 11.8.3 Less-than-or-equal Operator - Partial left to right order
-# enforced when using Less-than-or-equal operator: valueOf <= valueOf
-11.8.3-5: FAIL
-# Bug? simple assignment throws TypeError if LeftHandSide is a readonly property
-# in strict mode (Global.undefined)
-11.13.1-4-27-s: FAIL
-# Bug? simple assignment throws TypeError if LeftHandSide is a readonly property
-# in strict mode (Global.Infinity)
-11.13.1-4-3-s: FAIL
-# BUG: Global.NaN is a data property with default attribute values
-15.1.1.1-0: FAIL
-# BUG: Global.Infinity is a data property with default attribute values
-15.1.1.2-0: FAIL
-# BUG: Global.undefined is a data property with default attribute values
-15.1.1.3-0: FAIL
-# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
-# for properties on built-ins (Global.NaN)
-15.2.3.3-4-178: FAIL
-# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
-# for properties on built-ins (Global.Infinity)
-15.2.3.3-4-179: FAIL
-# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
-# for properties on built-ins (Global.undefined)
-15.2.3.3-4-180: FAIL
-# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
-# for properties on built-ins (RegExp.prototype.source)
-# There is no RegExp.prototype.source
-15.2.3.3-4-212: FAIL
-# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
-# for properties on built-ins (RegExp.prototype.global)
-# There is no RegExp.prototype.global
-15.2.3.3-4-213: FAIL
-# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
-# for properties on built-ins (RegExp.prototype.ignoreCase)
-# There is no RegExp.prototype.ignoreCase
-15.2.3.3-4-214: FAIL
-# BUG: Object.getOwnPropertyDescriptor returns data desc (all false)
-# for properties on built-ins (RegExp.prototype.multiline)
-15.2.3.3-4-215: FAIL
-# Bug? Object.defineProperty - Update [[Enumerable]] attribute of 'name'
-# property to true successfully when [[Enumerable]] attribute of 'name'
-# is false and [[Configurable]] attribute of 'name' is true, the 'desc'
-# is a generic descriptor which only contains [[Enumerable]] attribute
-# as true, 'name' property is an index data property (8.12.9 step 8)
-15.2.3.6-4-82-18: FAIL
-# Bug? Object.defineProperty - Update [[Enumerable]] attribute of 'name'
-# property to false successfully when [[Enumerable]] and [[Configurable]]
-# attributes of 'name' property are true, the 'desc' is a generic
-# descriptor which only contains [Enumerable]] attribute as false and
-# 'name' property is an index accessor property (8.12.9 step 8)
-15.2.3.6-4-82-19: FAIL
-# Bug? Object.defineProperty - Update [[Enumerable]] attribute of 'name'
-# property to false successfully when [[Enumerable]] and [[Configurable]]
-# attributes of 'name' property are true, the 'desc' is a generic
-# descriptor which contains [Enumerable]] attribute as false and
-# [[Configurable]] property is true, 'name' property is an index accessor
-# property (8.12.9 step 8)
-15.2.3.6-4-82-20: FAIL
-# Bug? Object.defineProperty - Update [[Configurable]] attribute of 'name'
-# property to false successfully when [[Enumerable]] and [[Configurable]]
-# attributes of 'name' property are true, the 'desc' is a generic
-# descriptor which only contains [[Configurable]] attribute as false,
-# 'name' property is an index accessor property (8.12.9 step 8)
-15.2.3.6-4-82-21: FAIL
-# Bug? Object.defineProperty - Update [[Configurable]] attribute of 'name'
-# property to false successfully when [[Enumerable]] and [[Configurable]]
-# attributes of 'name' property are true, the 'desc' is a generic
-# descriptor which contains [[Enumerable]] attribute as true and
-# [[Configurable]] attribute is false, 'name' property is an index accessor
-# property (8.12.9 step 8)
-15.2.3.6-4-82-22: FAIL
-# Bug? Object.defineProperty - Update [[Enumerable]] and [[Configurable]]
-# attributes of 'name' property to false successfully when [[Enumerable]]
-# and [[Configurable]] attributes of 'name' property are true, the 'desc'
-# is a generic descriptor which contains [[Enumerable]] and
-# [[Configurable]] attributes as false, 'name' property is an index
-# accessor property (8.12.9 step 8)
-15.2.3.6-4-82-23: FAIL
-# Bug? Object.defineProperty - Update [[Enumerable]] attributes of 'name'
-# property to true successfully when [[Enumerable]] attribute of 'name' is
-# false and [[Configurable]] attribute of 'name' is true, the 'desc' is a
-# generic descriptor which only contains [[Enumerable]] attribute as true,
-# 'name' property is an index accessor property (8.12.9 step 8)
-15.2.3.6-4-82-24: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, test the length property of 'O'
-# is own data property (15.4.5.1 step 1)
-15.2.3.6-4-116: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, test the length property of 'O'
-# is own data property that overrides an inherited data property (15.4.5.1
-# step 1)
-15.2.3.6-4-117: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test that RangeError exception is thrown when [[Value]] field of
-# 'desc' is undefined (15.4.5.1 step 3.c)
-15.2.3.6-4-125: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test the [[Value]] field of 'desc' is null (15.4.5.1 step 3.c)
-15.2.3.6-4-126: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test the [[Value]] field of 'desc' is a boolean with value false
-# (15.4.5.1 step 3.c)
-15.2.3.6-4-127: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test the [[Value]] field of 'desc' is a boolean with value true
-# (15.4.5.1 step 3.c)
-15.2.3.6-4-128: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is not thrown when the [[Value]] field of
-# 'desc' is 0 (15.4.5.1 step 3.c)
-15.2.3.6-4-129: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is not thrown when the [[Value]] field of
-# 'desc' is +0 (15.4.5.1 step 3.c)
-15.2.3.6-4-130: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is not thrown when the [[Value]] field of
-# 'desc' is -0 (15.4.5.1 step 3.c)
-15.2.3.6-4-131: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is not thrown when the [[Value]] field of
-# 'desc' is a positive number (15.4.5.1 step 3.c)
-15.2.3.6-4-132: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is thrown when the [[Value]] field of
-# 'desc' is a negative number (15.4.5.1 step 3.c)
-15.2.3.6-4-133: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is thrown when the [[Value]] field of
-# 'desc' is +Infinity (15.4.5.1 step 3.c)
-15.2.3.6-4-134: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is thrown when the [[Value]] field of
-# 'desc' is -Infinity (15.4.5.1 step 3.c)
-15.2.3.6-4-135: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is thrown when the [[Value]] field of
-# 'desc' is NaN (15.4.5.1 step 3.c)
-15.2.3.6-4-136: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is not thrown when the [[Value]] field of
-# 'desc' is a string containing a positive number (15.4.5.1 step 3.c)
-15.2.3.6-4-137: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is thrown when the [[Value]] field of
-# 'desc' is a string containing a negative number (15.4.5.1 step 3.c)
-15.2.3.6-4-138: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is thrown when the [[Value]] field of
-# 'desc' is a string containing a decimal number (15.4.5.1 step 3.c)
-15.2.3.6-4-139: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is thrown when the [[Value]] field of
-# 'desc' is a string containing +Infinity (15.4.5.1 step 3.c)
-15.2.3.6-4-140: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is thrown when the [[Value]] field of
-# 'desc' is a string containing -Infinity (15.4.5.1 step 3.c)
-15.2.3.6-4-141: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test the [[Value]] field of 'desc' is a string containing an
-# exponential number (15.4.5.1 step 3.c)
-15.2.3.6-4-142: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test the [[Value]] field of 'desc' is a string containing a hex
-# number (15.4.5.1 step 3.c)
-15.2.3.6-4-143: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test the [[Value]] field of 'desc' is a string containing a number
-# with leading zeros (15.4.5.1 step 3.c)
-15.2.3.6-4-144: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError exception is thrown when the [[Value]] field of
-# 'desc' is a string which doesn't convert to a number (15.4.5.1 step 3.c)
-15.2.3.6-4-145: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test the [[Value]] field of 'desc' is an object which has an own
-# toString method (15.4.5.1 step 3.c)
-15.2.3.6-4-146: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test the [[Value]] field of 'desc' is an Object which has an own
-# valueOf method (15.4.5.1 step 3.c)
-15.2.3.6-4-147: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test the [[Value]] field of 'desc' is an Object which has an own
-# valueOf method that returns an object and toString method that returns a
-# string (15.4.5.1 step 3.c)
-15.2.3.6-4-148: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test the [[Value]] field of 'desc' is an Object which has an own
-# toString and valueOf method (15.4.5.1 step 3.c)
-15.2.3.6-4-149: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test TypeError is thrown when the [[Value]] field of 'desc' is an
-# Object that both toString and valueOf wouldn't return primitive value
-# (15.4.5.1 step 3.c)
-15.2.3.6-4-150: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', and the [[Value]] field of 'desc' is an Object with an own toString
-# method and an inherited valueOf method (15.4.5.1 step 3.c), test that the
-# inherited valueOf method is used
-15.2.3.6-4-151: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError is thrown when the [[Value]] field of 'desc' is a
-# positive non-integer values (15.4.5.1 step 3.c)
-15.2.3.6-4-152: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length prosperty
-# of 'O', test RangeError is thrown when the [[Value]] field of 'desc' is a
-# negative non-integer values (15.4.5.1 step 3.c)
-15.2.3.6-4-153: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test the [[Value]] field of 'desc' is boundary value 2^32 - 2
-# (15.4.5.1 step 3.c)
-15.2.3.6-4-154: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test the [[Value]] field of 'desc' is boundary value 2^32 - 1
-# (15.4.5.1 step 3.c)
-15.2.3.6-4-155: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError is thrown when the [[Value]] field of 'desc' is
-# boundary value 2^32 (15.4.5.1 step 3.c)
-15.2.3.6-4-156: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', test RangeError is thrown when the [[Value]] field of 'desc' is
-# boundary value 2^32 + 1 (15.4.5.1 step 3.c)
-15.2.3.6-4-157: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', set the [[Value]] field of 'desc' to a value greater than the
-# existing value of length (15.4.5.1 step 3.f)
-15.2.3.6-4-159: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', set the [[Value]] field of 'desc' to a value lesser than the
-# existing value of length and test that indexes beyond the new length are
-# deleted(15.4.5.1 step 3.f)
-15.2.3.6-4-161: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Writable]] attribute of the length property is set
-# to true after deleting properties with large index named if the
-# [[Writable]] field of 'desc' is absent (15.4.5.1 step 3.h)
-15.2.3.6-4-165: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Writable]] attribute of the length property is set
-# to true after deleting properties with large index named if the
-# [[Writable]] field of 'desc' is true (15.4.5.1 step 3.h)
-15.2.3.6-4-166: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Writable]] attribute of the length property is set
-# to false after deleting properties with large index named if the
-# [[Writable]] field of 'desc' is false (15.4.5.1 step 3.i.ii)
-15.2.3.6-4-167: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', whose writable attribute is being changed to false and the [[Value]]
-# field of 'desc' is less than value of the length property and also lesser
-# than an index of the array which is set to configurable:false, test that
-# new length is set to a value greater than the non-deletable index by 1,
-# writable attribute of length is set to false and TypeError exception is
-# thrown (15.4.5.1 step 3.i.iii)
-15.2.3.6-4-168: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property and also lesser than an index of the array which is set to
-# configurable: false, test that new length is set to a value greater than
-# the non-deletable index by 1, and TypeError is thrown (15.4.5.1 step
-# 3.l.i)
-15.2.3.6-4-169: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property and also lesser than an index of the array which is set to
-# configurable: false, test that new length is set to a value greater than
-# the non-deletable index by 1, writable attribute of length is set to
-# false and TypeError exception is thrown (15.4.5.1 step 3.l.ii)
-15.2.3.6-4-170: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of an inherited data
-# property with large index named in 'O' can't stop deleting index named
-# properties (15.4.5.1 step 3.l.ii)
-15.2.3.6-4-171: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of own data property with
-# large index named in 'O' that overrides an inherited data property can
-# stop deleting index named properties (15.4.5.1 step 3.l.ii)
-15.2.3.6-4-172: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of own data property with
-# large index named in 'O' that overrides an inherited accessor property
-# can stop deleting index named properties (15.4.5.1 step 3.l.ii)
-15.2.3.6-4-173: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of own accessor property
-# with large index named in 'O' can stop deleting index named properties
-# (15.4.5.1 step 3.l.ii)
-15.2.3.6-4-174: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of an inherited accessor
-# property with large index named in 'O' can't stop deleting index named
-# properties (15.4.5.1 step 3.l.ii)
-15.2.3.6-4-175: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of own accessor property
-# with large index named in 'O' that overrides an inherited data property
-# can stop deleting index named properties (15.4.5.1 step 3.l.ii)
-15.2.3.6-4-176: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of own accessor property
-# with large index named in 'O' that overrides an inherited accessor
-# property can stop deleting index named properties (15.4.5.1 step 3.l.ii)
-15.2.3.6-4-177: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the configurable large index named property of 'O' is
-# deleted (15.4.5.1 step 3.l.ii)
-15.2.3.6-4-178: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is greater than value of the length
-# property, test value of the length property is same as [[Value]]
-# (15.4.5.1 step 3.l.iii.1)
-15.2.3.6-4-179-1: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Writable]] attribute of the length property is set
-# to false at last when the [[Writable]] field of 'desc' is false and 'O'
-# doesn't contain non-configurable large index named property (15.4.5.1
-# step 3.m)
-15.2.3.6-4-181: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
-# property, 'name' is boundary value 2^32 - 2 (15.4.5.1 step 4.a)
-15.2.3.6-4-183: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
-# property, test TypeError is thrown if the [[Writable]] attribute of the
-# length property in 'O' is false and value of 'name' equals to value of
-# the length property (15.4.5.1 step 4.b)
-15.2.3.6-4-188: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
-# property, test TypeError is thrown if the [[Writable]] attribute of the
-# length property in 'O' is false and value of 'name' is greater than value
-# of the length property (15.4.5.1 step 4.b)
-15.2.3.6-4-189: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
-# property, 'desc' is accessor descriptor, test updating all attribute
-# values of 'name' (15.4.5.1 step 4.c)
-15.2.3.6-4-209: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
-# property, name is accessor property and 'desc' is accessor descriptor,
-# test updating the [[Enumerable]] attribute value of 'name' (15.4.5.1 step
-# 4.c)
-15.2.3.6-4-271: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
-# property, name is accessor property and 'desc' is accessor descriptor,
-# test updating the [[Configurable]] attribute value of 'name' (15.4.5.1
-# step 4.c)
-15.2.3.6-4-272: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
-# property, name is accessor property and 'desc' is accessor descriptor,
-# test updating multiple attribute values of 'name' (15.4.5.1 step 4.c)
-15.2.3.6-4-273: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
-# property, test the length property of 'O' is set as ToUint32('name') + 1
-# if ToUint32('name') equals to value of the length property in 'O'
-# (15.4.5.1 step 4.e.ii)
-15.2.3.6-4-275: FAIL
-# Bug? Object.defineProperty - 'O' is an Array, 'name' is an array index named
-# property, test the length property of 'O' is set as ToUint32('name') + 1
-# if ToUint32('name') is greater than value of the length property in 'O'
-# (15.4.5.1 step 4.e.ii)
-15.2.3.6-4-276: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-# formal parameters, 'name' is own accessor property of 'O' which is also
-# defined in [[ParameterMap]] of 'O', and 'desc' is accessor descriptor,
-# test updating multiple attribute values of 'name' (10.6
-# [[DefineOwnProperty]] step 3 and 5.a.i)
-15.2.3.6-4-291-1: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object, 'name' is own
-# accessor property of 'O', and 'desc' is accessor descriptor, test
-# updating multiple attribute values of 'name' (10.6 [[DefineOwnProperty]]
-# step 3)
-15.2.3.6-4-291: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-# formal parameters, 'name' is own property of 'O' which is also defined in
-# [[ParameterMap]] of 'O', and 'desc' is data descriptor, test updating
-# multiple attribute values of 'name' (10.6 [[DefineOwnProperty]] step 3
-# and 5.b)
-15.2.3.6-4-292-1: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-# formal parameters, 'name' is own data property of 'O' which is also
-# defined in [[ParameterMap]] of 'O', test TypeError is thrown when
-# updating the [[Value]] attribute value of 'name' which is defined as
-# unwritable and non-configurable (10.6 [[DefineOwnProperty]] step 4 and
-# step 5b)
-15.2.3.6-4-293-2: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-# formal parameters, 'name' is own data property of 'O' which is also
-# defined in [[ParameterMap]] of 'O', test TypeError is not thrown when
-# updating the [[Value]] attribute value of 'name' which is defined as
-# non-writable and configurable (10.6 [[DefineOwnProperty]] step 3 and step
-# 5.b)
-15.2.3.6-4-293-3: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-# formal parameters, 'name' is own data property of 'O' which is also
-# defined in [[ParameterMap]] of 'O', test TypeError is thrown when
-# updating the [[Writable]] attribute value of 'name' which is defined as
-# non-configurable (10.6 [[DefineOwnProperty]] step 4 and 5b)
-15.2.3.6-4-294-1: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-# formal parameters, 'name' is own data property of 'O' which is also
-# defined in [[ParameterMap]] of 'O', test TypeError is thrown when
-# updating the [[Enumerable]] attribute value of 'name' which is defined as
-# non-configurable (10.6 [[DefineOwnProperty]] step 4 and step 5b)
-15.2.3.6-4-295-1: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object of a function that has
-# formal parameters, 'name' is own data property of 'O' which is also
-# defined in [[ParameterMap]] of 'O', test TypeError is thrown when
-# updating the [[Configurable]] attribute value of 'name' which is defined
-# as non-configurable (10.6 [[DefineOwnProperty]] step 4 and step 5b)
-15.2.3.6-4-296-1: FAIL
-# Bug? Object.defineProperty - 'O' is an Arguments object, 'name' is an index
-# named accessor property of 'O' but not defined in [[ParameterMap]] of
-# 'O', and 'desc' is accessor descriptor, test updating multiple attribute
-# values of 'name' (10.6 [[DefineOwnProperty]] step 3)
-15.2.3.6-4-303: FAIL
-# Bug? ES5 Attributes - indexed property 'P' with attributes [[Writable]]: true,
-# [[Enumerable]]: true, [[Configurable]]: false is writable using simple
-# assignment, 'O' is an Arguments object
-15.2.3.6-4-333-11: FAIL
-# Bug? ES5 Attributes - Updating indexed data property 'P' whose attributes are
-# [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: true to an
-# accessor property, 'A' is an Array object (8.12.9 - step 9.b.i)
-15.2.3.6-4-360-1: FAIL
-# Bug? ES5 Attributes - Updating indexed data property 'P' whose attributes are
-# [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: true to an
-# accessor property, 'O' is an Arguments object (8.12.9 - step 9.b.i)
-15.2.3.6-4-360-6: FAIL
-# Bug? ES5 Attributes - Updating indexed data property 'P' whose attributes are
-# [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: true to an
-# accessor property, 'O' is the global object (8.12.9 - step 9.b.i)
-15.2.3.6-4-360-7: FAIL
-# Bug? ES5 Attributes - [[Value]] attribute of data property is the activex host
-# object
-15.2.3.6-4-401: FAIL
-# Bug? ES5 Attributes - Failed to add a property to an object when the object's
-# object has a property with same name and [[Writable]] attribute is set to
-# false (Number instance)
+# V8 Bug: http://code.google.com/p/v8/issues/detail?id=1475
15.2.3.6-4-405: FAIL
-# Bug? ES5 Attributes - Failed to add a property to an object when the object's
-# prototype has a property with the same name and [[Writable]] set to false
-# (JSON)
15.2.3.6-4-410: FAIL
-# Bug? ES5 Attributes - Failed to add properties to an object when the object's
-# prototype has properties with the same name and [[Writable]] set to false
-# (Object.create)
15.2.3.6-4-415: FAIL
-# Bug? ES5 Attributes - Failed to add a property to an object when the object's
-# prototype has a property with the same name and [[Writable]] set to
-# false(Function.prototype.bind)
15.2.3.6-4-420: FAIL
-# Bug? ES5 Attributes - all attributes in Array.prototype.indexOf are correct
-15.2.3.6-4-612: FAIL
-# Bug? ES5 Attributes - all attributes in Object.lastIndexOf are correct
-15.2.3.6-4-613: FAIL
-# Bug? ES5 Attributes - all attributes in Array.prototype.every are correct
-15.2.3.6-4-614: FAIL
-# Bug? ES5 Attributes - all attributes in Array.prototype.some are correct
-15.2.3.6-4-615: FAIL
-# Bug? ES5 Attributes - all attributes in Array.prototype.forEach are correct
-15.2.3.6-4-616: FAIL
-# Bug? ES5 Attributes - all attributes in Array.prototype.map are correct
-15.2.3.6-4-617: FAIL
-# Bug? ES5 Attributes - all attributes in Array.prototype.filter are correct
-15.2.3.6-4-618: FAIL
-# Bug? ES5 Attributes - all attributes in Array.prototype.reduce are correct
-15.2.3.6-4-619: FAIL
-# Bug? ES5 Attributes - all attributes in Array.prototype.reduceRight are
-# correct
-15.2.3.6-4-620: FAIL
-# Bug? ES5 Attributes - all attributes in String.prototype.trim are correct
-15.2.3.6-4-621: FAIL
-# Bug? ES5 Attributes - all attributes in Date.prototype.toISOString are correct
-15.2.3.6-4-623: FAIL
-# Bug? ES5 Attributes - all attributes in Date.prototype.toJSON are correct
-15.2.3.6-4-624: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, test the length property of
-# 'O' is own data property (15.4.5.1 step 1)
-15.2.3.7-6-a-112: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, test the length property of
-# 'O' is own data property that overrides an inherited data property
-# (15.4.5.1 step 1)
-15.2.3.7-6-a-113: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', test RangeError is thrown when setting the [[Value]] field of 'desc'
-# to undefined (15.4.5.1 step 3.c)
-15.2.3.7-6-a-121: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', test setting the [[Value]] field of 'desc' to null actuall is set to
-# 0 (15.4.5.1 step 3.c)
-15.2.3.7-6-a-122: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is a boolean with value false
-# (15.4.5.1 step 3.c)
-15.2.3.7-6-a-123: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is a boolean with value true
-# (15.4.5.1 step 3.c)
-15.2.3.7-6-a-124: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is 0 (15.4.5.1 step 3.c)
-15.2.3.7-6-a-125: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is +0 (15.4.5.1 step 3.c)
-15.2.3.7-6-a-126: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is -0 (15.4.5.1 step 3.c)
-15.2.3.7-6-a-127: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is positive number (15.4.5.1
-# step 3.c)
-15.2.3.7-6-a-128: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is negative number (15.4.5.1
-# step 3.c)
-15.2.3.7-6-a-129: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is +Infinity (15.4.5.1 step
-# 3.c)
-15.2.3.7-6-a-130: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is -Infinity (15.4.5.1 step
-# 3.c)
-15.2.3.7-6-a-131: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is NaN (15.4.5.1 step 3.c)
-15.2.3.7-6-a-132: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is a string containing a
-# positive number (15.4.5.1 step 3.c)
-15.2.3.7-6-a-133: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is a string containing a
-# negative number (15.4.5.1 step 3.c)
-15.2.3.7-6-a-134: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is a string containing a
-# decimal number (15.4.5.1 step 3.c)
-15.2.3.7-6-a-135: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is a string containing
-# +Infinity (15.4.5.1 step 3.c)
-15.2.3.7-6-a-136: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is a string containing
-# -Infinity (15.4.5.1 step 3.c)
-15.2.3.7-6-a-137: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is a string containing an
-# exponential number (15.4.5.1 step 3.c)
-15.2.3.7-6-a-138: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is a string containing an hex
-# number (15.4.5.1 step 3.c)
-15.2.3.7-6-a-139: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is a string containing an
-# leading zero number (15.4.5.1 step 3.c)
-15.2.3.7-6-a-140: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', test the [[Value]] field of 'desc' is a string which doesn't convert
-# to a number (15.4.5.1 step 3.c)
-15.2.3.7-6-a-141: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', test the [[Value]] field of 'desc' is an Object which has an own
-# toString method (15.4.5.1 step 3.c)
-15.2.3.7-6-a-142: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is an Object which has an own
-# valueOf method (15.4.5.1 step 3.c)
-15.2.3.7-6-a-143: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is an Object which has an own
-# valueOf method that returns an object and toString method that returns a
-# string (15.4.5.1 step 3.c)
-15.2.3.7-6-a-144: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is an Object which has an own
-# toString and valueOf method (15.4.5.1 step 3.c)
-15.2.3.7-6-a-145: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test TypeError is thrown when the [[Value]] field of 'desc' is an
-# Object that both toString and valueOf wouldn't return primitive value
-# (15.4.5.1 step 3.c)
-15.2.3.7-6-a-146: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test using inherited valueOf method when the [[Value]] field of
-# 'desc' is an Objec with an own toString and inherited valueOf methods
-# (15.4.5.1 step 3.c)
-15.2.3.7-6-a-147: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test RangeError is thrown when the [[Value]] field of 'desc' is
-# positive non-integer values (15.4.5.1 step 3.c)
-15.2.3.7-6-a-148: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test RangeError is thrown when the [[Value]] field of 'desc' is
-# negative non-integer values (15.4.5.1 step 3.c)
-15.2.3.7-6-a-149: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is boundary value 2^32 - 2
-# (15.4.5.1 step 3.c)
-15.2.3.7-6-a-150: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test the [[Value]] field of 'desc' is boundary value 2^32 - 1
-# (15.4.5.1 step 3.c)
-15.2.3.7-6-a-151: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test RangeError is thrown when the [[Value]] field of 'desc' is
-# boundary value 2^32 (15.4.5.1 step 3.c)
-15.2.3.7-6-a-152: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'name' is the length property
-# of 'O', test RangeError is thrown when the [[Value]] field of 'desc' is
-# boundary value 2^32 + 1 (15.4.5.1 step 3.c)
-15.2.3.7-6-a-153: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', test the [[Value]] field of 'desc' which is greater than value of
-# the length property is defined into 'O' without deleting any property
-# with large index named (15.4.5.1 step 3.f)
-15.2.3.7-6-a-155: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', test the [[Value]] field of 'desc' which is less than value of the
-# length property is defined into 'O' with deleting properties with large
-# index named (15.4.5.1 step 3.f)
-15.2.3.7-6-a-157: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Writable]] attribute of the length property is set
-# to true at last after deleting properties with large index named if the
-# [[Writable]] field of 'desc' is absent (15.4.5.1 step 3.h)
-15.2.3.7-6-a-161: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Writable]] attribute of the length property is set
-# to true at last after deleting properties with large index named if the
-# [[Writable]] field of 'desc' is true (15.4.5.1 step 3.h)
-15.2.3.7-6-a-162: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Writable]] attribute of the length property is set
-# to false at last after deleting properties with large index named if the
-# [[Writable]] field of 'desc' is false (15.4.5.1 step 3.i.ii)
-15.2.3.7-6-a-163: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Writable]] attribute of the length property in 'O'
-# is set as true before deleting properties with large index named
-# (15.4.5.1 step 3.i.iii)
-15.2.3.7-6-a-164: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the length property is decreased by 1 (15.4.5.1 step
-# 3.l.i)
-15.2.3.7-6-a-165: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of own data property with
-# large index named in 'O' can stop deleting index named properties
-# (15.4.5.1 step 3.l.ii)
-15.2.3.7-6-a-166: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of inherited data property
-# with large index named in 'O' can't stop deleting index named properties
-# (15.4.5.1 step 3.l.ii)
-15.2.3.7-6-a-167: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of own data property with
-# large index named in 'O' that overrides inherited data property can stop
-# deleting index named properties (15.4.5.1 step 3.l.ii)
-15.2.3.7-6-a-168: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of own data property with
-# large index named in 'O' that overrides inherited accessor property can
-# stop deleting index named properties (15.4.5.1 step 3.l.ii)
-15.2.3.7-6-a-169: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of own accessor property
-# with large index named in 'O' can stop deleting index named properties
-# (15.4.5.1 step 3.l.ii)
-15.2.3.7-6-a-170: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of inherited accessor
-# property with large index named in 'O' can't stop deleting index named
-# properties (15.4.5.1 step 3.l.ii)
-15.2.3.7-6-a-171: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of own accessor property
-# with large index named in 'O' that overrides inherited data property can
-# stop deleting index named properties (15.4.5.1 step 3.l.ii)
-15.2.3.7-6-a-172: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Configurable]] attribute of own accessor property
-# with large index named in 'O' that overrides inherited accessor property
-# can stop deleting index named properties (15.4.5.1 step 3.l.ii)
-15.2.3.7-6-a-173: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the configurable large index named property of 'O' can be
-# deleted (15.4.5.1 step 3.l.ii)
-15.2.3.7-6-a-174: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test value of the length property is set to the last
-# non-configurable index named property of 'O' plus 1 (15.4.5.1 step
-# 3.l.iii.1)
-15.2.3.7-6-a-175: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Writable]] attribute of the length property is set
-# to false at last when the [[Writable]] field of 'desc' is false and 'O'
-# contains non-configurable large index named property (15.4.5.1 step
-# 3.l.iii.2)
-15.2.3.7-6-a-176: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is the length property of
-# 'O', the [[Value]] field of 'desc' is less than value of the length
-# property, test the [[Writable]] attribute of the length property is set
-# to false at last when the [[Writable]] field of 'desc' is false and 'O'
-# doesn't contain non-configurable large index named property (15.4.5.1
-# step 3.m)
-15.2.3.7-6-a-177: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
-# property, 'P' is boundary value 2^32 - 2 (15.4.5.1 step 4.a)
-15.2.3.7-6-a-179: FAIL
-# Bug? Object.defineProperties - TypeError is thrown if 'O' is an Array, 'P' is
-# an array index named property,[[Writable]] attribute of the length
-# property in 'O' is false, value of 'P' is equal to value of the length
-# property in 'O' (15.4.5.1 step 4.b)
-15.2.3.7-6-a-184: FAIL
-# Bug? Object.defineProperties - TypeError is thrown if 'O' is an Array, 'P' is
-# an array index named property,[[Writable]] attribute of the length
-# property in 'O' is false, value of 'P' is bigger than value of the length
-# property in 'O' (15.4.5.1 step 4.b)
-15.2.3.7-6-a-185: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
-# property, 'desc' is accessor descriptor, test updating all attribute
-# values of 'P' (15.4.5.1 step 4.c)
-15.2.3.7-6-a-205: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
-# property that already exists on 'O' is accessor property and 'desc' is
-# accessor descriptor, test updating the [[Enumerable]] attribute value of
-# 'P' (15.4.5.1 step 4.c)
-15.2.3.7-6-a-260: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
-# property that already exists on 'O' is accessor property and 'desc' is
-# accessor descriptor, test updating the [[Configurable]] attribute value
-# of 'P' (15.4.5.1 step 4.c)
-15.2.3.7-6-a-261: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
-# property that already exists on 'O' is accessor property and 'desc' is
-# accessor descriptor, test updating multiple attribute values of 'P'
-# (15.4.5.1 step 4.c)
-15.2.3.7-6-a-262: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
-# property, test the length property of 'O' is set as ToUint32('P') + 1 if
-# ToUint32('P') equals to value of the length property in 'O' (15.4.5.1
-# step 4.e.ii)
-15.2.3.7-6-a-264: FAIL
-# Bug? Object.defineProperties - 'O' is an Array, 'P' is an array index named
-# property, test the length property of 'O' is set as ToUint32('P') + 1 if
-# ToUint32('P') is greater than value of the length property in 'O'
-# (15.4.5.1 step 4.e.ii)
-15.2.3.7-6-a-265: FAIL
-# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own accessor
-# property of 'O' which is also defined in [[ParameterMap]] of 'O', and
-# 'desc' is accessor descriptor, test updating multiple attribute values of
-# 'P' (10.6 [[DefineOwnProperty]] step 3)
-15.2.3.7-6-a-280: FAIL
-# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own data
-# property of 'O' which is also defined in [[ParameterMap]] of 'O', and
-# 'desc' is data descriptor, test updating multiple attribute values of 'P'
-# (10.6 [[DefineOwnProperty]] step 3)
-15.2.3.7-6-a-281: FAIL
-# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own data
-# property of 'O' which is also defined in [[ParameterMap]] of 'O', test
-# TypeError is thrown when updating the [[Value]] attribute value of 'P'
-# whose writable and configurable attributes are false (10.6
-# [[DefineOwnProperty]] step 4)
-15.2.3.7-6-a-282: FAIL
-# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own data
-# property of 'O' which is also defined in [[ParameterMap]] of 'O', test
-# TypeError is thrown when updating the [[Writable]] attribute value of 'P'
-# which is defined as non-configurable (10.6 [[DefineOwnProperty]] step 4)
-15.2.3.7-6-a-283: FAIL
-# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own data
-# property of 'O' which is also defined in [[ParameterMap]] of 'O', test
-# TypeError is thrown when updating the [[Enumerable]] attribute value of
-# 'P' which is defined as non-configurable (10.6 [[DefineOwnProperty]] step
-# 4)
-15.2.3.7-6-a-284: FAIL
-# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is own data
-# property of 'O' which is also defined in [[ParameterMap]] of 'O', test
-# TypeError is thrown when updating the [[Configurable]] attribute value of
-# 'P' which is defined as non-configurable (10.6 [[DefineOwnProperty]] step
-# 4)
-15.2.3.7-6-a-285: FAIL
-# Bug? Object.defineProperties - 'O' is an Arguments object, 'P' is an array
-# index named accessor property of 'O' but not defined in [[ParameterMap]]
-# of 'O', and 'desc' is accessor descriptor, test updating multiple
-# attribute values of 'P' (10.6 [[DefineOwnProperty]] step 3)
-15.2.3.7-6-a-292: FAIL
-# Bug? Strict Mode - 'this' value is a string which cannot be converted to
-# wrapper objects when the function is called with an array of arguments
-15.3.4.3-1-s: FAIL
-# Bug? Strict Mode - 'this' value is a number which cannot be converted to
-# wrapper objects when the function is called with an array of arguments
-15.3.4.3-2-s: FAIL
-# Bug? Strict Mode - 'this' value is a boolean which cannot be converted to
-# wrapper objects when the function is called with an array of arguments
-15.3.4.3-3-s: FAIL
-# Bug? Function.prototype.bind - [[Get]] attribute of 'caller' property in 'F'
-# is thrower
-15.3.4.5-20-2: FAIL
-# Bug? Function.prototype.bind - [[Set]] attribute of 'caller' property in 'F'
-# is thrower
-15.3.4.5-20-3: FAIL
-# Bug? Function.prototype.bind - [[Get]] attribute of 'arguments' property in
-# 'F' is thrower
-15.3.4.5-21-2: FAIL
-# Bug? Function.prototype.bind - [[Set]] attribute of 'arguments' property in
-# 'F' is thrower
-15.3.4.5-21-3: FAIL
-# Bug? Array.prototype.indexOf - decreasing length of array does not delete
-# non-configurable properties
-15.4.4.14-9-a-19: FAIL
-# Bug? Array.prototype.indexOf - element to be retrieved is own accessor
-# property that overrides an inherited data property on an Array
-15.4.4.14-9-b-i-11: FAIL
-# Bug? Array.prototype.indexOf - element to be retrieved is own accessor
-# property that overrides an inherited accessor property on an Array
-15.4.4.14-9-b-i-13: FAIL
-# Bug? Array.prototype.indexOf - element to be retrieved is own accessor
-# property without a get function on an Array
-15.4.4.14-9-b-i-17: FAIL
-# Bug? Array.prototype.indexOf - element to be retrieved is own accessor
-# property without a get function that overrides an inherited accessor
-# property on an Array
-15.4.4.14-9-b-i-19: FAIL
-# Bug? Array.prototype.indexOf - side-effects are visible in subsequent
-# iterations on an Array
-15.4.4.14-9-b-i-28: FAIL
-# Bug? Array.prototype.indexOf - terminates iteration on unhandled exception on
-# an Array
-15.4.4.14-9-b-i-30: FAIL
-# Bug? Array.prototype.lastIndexOf - deleting property of prototype causes
-# prototype index property not to be visited on an Array
-15.4.4.15-8-a-14: FAIL
-# Bug? Array.prototype.lastIndexOf - decreasing length of array does not delete
-# non-configurable properties
-15.4.4.15-8-a-19: FAIL
-# Bug? Array.prototype.lastIndexOf - element to be retrieved is own accessor
-# property that overrides an inherited data property on an Array
-15.4.4.15-8-b-i-11: FAIL
-# Bug? Array.prototype.lastIndexOf - element to be retrieved is own accessor
-# property that overrides an inherited accessor property on an Array
-15.4.4.15-8-b-i-13: FAIL
-# Bug? Array.prototype.lastIndexOf - element to be retrieved is own accessor
-# property without a get function on an Array
-15.4.4.15-8-b-i-17: FAIL
-# Bug? Array.prototype.lastIndexOf - side-effects are visible in subsequent
-# iterations on an Array
-15.4.4.15-8-b-i-28: FAIL
-# Bug? Array.prototype.lastIndexOf terminates iteration on unhandled exception
-# on an Array
-15.4.4.15-8-b-i-30: FAIL
-# Bug? Array.prototype.every applied to boolean primitive
-15.4.4.16-1-3: FAIL
-# Bug? Array.prototype.every applied to number primitive
-15.4.4.16-1-5: FAIL
-# Bug? Array.prototype.every applied to string primitive
-15.4.4.16-1-7: FAIL
-# Bug? Array.prototype.every - side effects produced by step 2 are visible when
-# an exception occurs
-15.4.4.16-4-8: FAIL
-# Bug? Array.prototype.every - side effects produced by step 3 are visible when
-# an exception occurs
-15.4.4.16-4-9: FAIL
-# Bug? Array.prototype.every - the exception is not thrown if exception was
-# thrown by step 2
-15.4.4.16-4-10: FAIL
-# Bug? Array.prototype.every - the exception is not thrown if exception was
-# thrown by step 3
-15.4.4.16-4-11: FAIL
-# Bug? Array.prototype.every - calling with no callbackfn is the same as passing
-# undefined for callbackfn
-15.4.4.16-4-15: FAIL
-# Bug? Array.prototype.every - decreasing length of array does not delete
-# non-configurable properties
-15.4.4.16-7-b-16: FAIL
-# Bug? Array.prototype.every - element to be retrieved is own accessor property
-# on an Array
-15.4.4.16-7-c-i-10: FAIL
-# Bug? Array.prototype.every - element to be retrieved is own accessor property
-# that overrides an inherited data property on an Array
-15.4.4.16-7-c-i-12: FAIL
-# Bug? Array.prototype.every - element to be retrieved is own accessor property
-# that overrides an inherited accessor property on an Array
-15.4.4.16-7-c-i-14: FAIL
-# Bug? Array.prototype.every - element to be retrieved is own accessor property
-# without a get function on an Array
-15.4.4.16-7-c-i-18: FAIL
-# Bug? Array.prototype.every - element to be retrieved is own accessor property
-# without a get function that overrides an inherited accessor property on
-# an Array
-15.4.4.16-7-c-i-20: FAIL
-# Bug? Array.prototype.every - element changed by getter on previous iterations
-# is observed on an Array
-15.4.4.16-7-c-i-28: FAIL
-# Bug? Array.prototype.some applied to boolean primitive
-15.4.4.17-1-3: FAIL
-# Bug? Array.prototype.some applied to number primitive
-15.4.4.17-1-5: FAIL
-# Bug? Array.prototype.some applied to applied to string primitive
-15.4.4.17-1-7: FAIL
-# Bug? Array.prototype.some - side effects produced by step 2 are visible when
-# an exception occurs
-15.4.4.17-4-8: FAIL
-# Bug? Array.prototype.some - side effects produced by step 3 are visible when
-# an exception occurs
-15.4.4.17-4-9: FAIL
-# Bug? Array.prototype.some - the exception is not thrown if exception was
-# thrown by step 2
-15.4.4.17-4-10: FAIL
-# Bug? Array.prototype.some - the exception is not thrown if exception was
-# thrown by step 3
-15.4.4.17-4-11: FAIL
-# Bug? Array.prototype.some - calling with no callbackfn is the same as passing
-# undefined for callbackfn
-15.4.4.17-4-15: FAIL
-# Bug? Array.prototype.some - decreasing length of array does not delete
-# non-configurable properties
-15.4.4.17-7-b-16: FAIL
-# Bug? Array.prototype.some - element to be retrieved is own accessor property
-# on an Array
-15.4.4.17-7-c-i-10: FAIL
-# Bug? Array.prototype.some - element to be retrieved is own accessor property
-# that overrides an inherited data property on an Array
-15.4.4.17-7-c-i-12: FAIL
-# Bug? Array.prototype.some - element to be retrieved is own accessor property
-# that overrides an inherited accessor property on an Array
-15.4.4.17-7-c-i-14: FAIL
-# Bug? Array.prototype.some - element to be retrieved is own accessor property
-# without a get function on an Array
-15.4.4.17-7-c-i-18: FAIL
-# Bug? Array.prototype.some - element to be retrieved is own accessor property
-# without a get function that overrides an inherited accessor property on
-# an Array
-15.4.4.17-7-c-i-20: FAIL
-# Bug? Array.prototype.some - element changed by getter on previous iterations
-# is observed on an Array
-15.4.4.17-7-c-i-28: FAIL
-# Bug? Array.prototype.forEach applied to boolean primitive
-15.4.4.18-1-3: FAIL
-# Bug? Array.prototype.forEach applied to number primitive
-15.4.4.18-1-5: FAIL
-# Bug? Array.prototype.forEach applied to string primitive
-15.4.4.18-1-7: FAIL
-# Bug? Array.prototype.forEach - side effects produced by step 2 are visible
-# when an exception occurs
-15.4.4.18-4-8: FAIL
-# Bug? Array.prototype.forEach - side effects produced by step 3 are visible
-# when an exception occurs
-15.4.4.18-4-9: FAIL
-# Bug? Array.prototype.forEach - the exception is not thrown if exception was
-# thrown by step 2
-15.4.4.18-4-10: FAIL
-# Bug? Array.prototype.forEach - the exception is not thrown if exception was
-# thrown by step 3
-15.4.4.18-4-11: FAIL
-# Bug? Array.prototype.forEach - calling with no callbackfn is the same as
-# passing undefined for callbackfn
-15.4.4.18-4-15: FAIL
-# Bug? Array.prototype.forEach - decreasing length of array does not delete
-# non-configurable properties
-15.4.4.18-7-b-16: FAIL
-# Bug? Array.prototype.forEach - element to be retrieved is own accessor
-# property on an Array
-15.4.4.18-7-c-i-10: FAIL
-# Bug? Array.prototype.forEach - element to be retrieved is own accessor
-# property that overrides an inherited data property on an Array
-15.4.4.18-7-c-i-12: FAIL
-# Bug? Array.prototype.forEach - element to be retrieved is own accessor
-# property that overrides an inherited accessor property on an Array
-15.4.4.18-7-c-i-14: FAIL
-# Bug? Array.prototype.forEach - element to be retrieved is own accessor
-# property without a get function on an Array
-15.4.4.18-7-c-i-18: FAIL
-# Bug? Array.prototype.forEach - element to be retrieved is own accessor
-# property without a get function that overrides an inherited accessor
-# property on an Array
-15.4.4.18-7-c-i-20: FAIL
-# Bug? Array.prototype.forEach - element changed by getter on previous
-# iterations is observed on an Array
-15.4.4.18-7-c-i-28: FAIL
-# Bug? Array.prototype.map - applied to boolean primitive
-15.4.4.19-1-3: FAIL
-# Bug? Array.prototype.map - applied to number primitive
-15.4.4.19-1-5: FAIL
-# Bug? Array.prototype.map - applied to string primitive
-15.4.4.19-1-7: FAIL
-# Bug? Array.prototype.map - Side effects produced by step 2 are visible when an
-# exception occurs
-15.4.4.19-4-8: FAIL
-# Bug? Array.prototype.map - Side effects produced by step 3 are visible when an
-# exception occurs
-15.4.4.19-4-9: FAIL
-# Bug? Array.prototype.map - the exception is not thrown if exception was thrown
-# by step 2
-15.4.4.19-4-10: FAIL
-# Bug? Array.prototype.map - the exception is not thrown if exception was thrown
-# by step 3
-15.4.4.19-4-11: FAIL
-# Bug? Array.prototype.map - calling with no callbackfn is the same as passing
-# undefined for callbackfn
-15.4.4.19-4-15: FAIL
-# Bug? Array.prototype.map - decreasing length of array does not delete
-# non-configurable properties
-15.4.4.19-8-b-16: FAIL
-# Bug? Array.prototype.map - element to be retrieved is own accessor property on
-# an Array
-15.4.4.19-8-c-i-10: FAIL
-# Bug? Array.prototype.map - element to be retrieved is own accessor property
-# that overrides an inherited data property on an Array
-15.4.4.19-8-c-i-12: FAIL
-# Bug? Array.prototype.map - element to be retrieved is own accessor property
-# that overrides an inherited accessor property on an Array
-15.4.4.19-8-c-i-14: FAIL
-# Bug? Array.prototype.map - element to be retrieved is own accessor property
-# without a get function on an Array
-15.4.4.19-8-c-i-18: FAIL
-# Bug? Array.prototype.map - element to be retrieved is own accessor property
-# without a get function that overrides an inherited accessor property on
-# an Array
-15.4.4.19-8-c-i-19: FAIL
-# Bug? Array.prototype.map - element changed by getter on previous iterations is
-# observed on an Array
-15.4.4.19-8-c-i-28: FAIL
-# Bug? Array.prototype.filter applied to boolean primitive
-15.4.4.20-1-3: FAIL
-# Bug? Array.prototype.filter applied to number primitive
-15.4.4.20-1-5: FAIL
-# Bug? Array.prototype.filter applied to string primitive
-15.4.4.20-1-7: FAIL
-# Bug? Array.prototype.filter - side effects produced by step 2 are visible when
-# an exception occurs
-15.4.4.20-4-8: FAIL
-# Bug? Array.prototype.filter - side effects produced by step 3 are visible when
-# an exception occurs
-15.4.4.20-4-9: FAIL
-# Bug? Array.prototype.filter - the exception is not thrown if exception was
-# thrown by step 2
-15.4.4.20-4-10: FAIL
-# Bug? Array.prototype.filter - the exception is not thrown if exception was
-# thrown by step 3
-15.4.4.20-4-11: FAIL
-# Bug? Array.prototype.filter - calling with no callbackfn is the same as
-# passing undefined for callbackfn
-15.4.4.20-4-15: FAIL
-# Bug? Array.prototype.filter - properties can be added to prototype after
-# current position are visited on an Array-like object
-15.4.4.20-9-b-6: FAIL
-# Bug? Array.prototype.filter - decreasing length of array does not delete
-# non-configurable properties
-15.4.4.20-9-b-16: FAIL
-# Bug? Array.prototype.filter - element to be retrieved is own data property
-# that overrides an inherited accessor property on an Array
-15.4.4.20-9-c-i-6: FAIL
-# Bug? Array.prototype.filter - element to be retrieved is own accessor property
-# on an Array
-15.4.4.20-9-c-i-10: FAIL
-# Bug? Array.prototype.filter - element to be retrieved is own accessor property
-# that overrides an inherited data property on an Array
-15.4.4.20-9-c-i-12: FAIL
-# Bug? Array.prototype.filter - element to be retrieved is own accessor property
-# that overrides an inherited accessor property on an Array
-15.4.4.20-9-c-i-14: FAIL
-# Bug? Array.prototype.filter - element to be retrieved is inherited accessor
-# property on an Array
-15.4.4.20-9-c-i-16: FAIL
-# Bug? Array.prototype.filter - element to be retrieved is own accessor property
-# without a get function on an Array
-15.4.4.20-9-c-i-18: FAIL
-# Bug? Array.prototype.filter - element to be retrieved is own accessor property
-# without a get function that overrides an inherited accessor property on
-# an Array
-15.4.4.20-9-c-i-20: FAIL
-# Bug? Array.prototype.filter - element to be retrieved is inherited accessor
-# property without a get function on an Array
-15.4.4.20-9-c-i-22: FAIL
-# Bug? Array.prototype.filter - element changed by getter on previous iterations
-# is observed on an Array
-15.4.4.20-9-c-i-28: FAIL
-# Bug? Array.prototype.reduce applied to boolean primitive
-15.4.4.21-1-3: FAIL
-# Bug? Array.prototype.reduce applied to number primitive
-15.4.4.21-1-5: FAIL
-# Bug? Array.prototype.reduce applied to string primitive
-15.4.4.21-1-7: FAIL
-# Bug? Array.prototype.reduce - side effects produced by step 2 are visible when
-# an exception occurs
-15.4.4.21-4-8: FAIL
-# Bug? Array.prototype.reduce - side effects produced by step 3 are visible when
-# an exception occurs
-15.4.4.21-4-9: FAIL
-# Bug? Array.prototype.reduce - the exception is not thrown if exception was
-# thrown by step 2
-15.4.4.21-4-10: FAIL
-# Bug? Array.prototype.reduce - the exception is not thrown if exception was
-# thrown by step 3
-15.4.4.21-4-11: FAIL
-# Bug? Array.prototype.reduce - calling with no callbackfn is the same as
-# passing undefined for callbackfn
-15.4.4.21-4-15: FAIL
-# Bug? Array.prototype.reduce - decreasing length of array in step 8 does not
-# delete non-configurable properties
-15.4.4.21-9-b-16: FAIL
-# Bug? Array.prototype.reduce - decreasing length of array does not delete
-# non-configurable properties
-15.4.4.21-9-b-29: FAIL
-# Bug? Array.prototype.reduceRight applied to boolean primitive
-15.4.4.22-1-3: FAIL
-# Bug? Array.prototype.reduceRight applied to number primitive
-15.4.4.22-1-5: FAIL
-# Bug? Array.prototype.reduceRight applied to string primitive
-15.4.4.22-1-7: FAIL
-# Bug? Array.prototype.reduceRight - side effects produced by step 2 are visible
-# when an exception occurs
-15.4.4.22-4-8: FAIL
-# Bug? Array.prototype.reduceRight - side effects produced by step 3 are visible
-# when an exception occurs
-15.4.4.22-4-9: FAIL
-# Bug? Array.prototype.reduceRight - the exception is not thrown if exception
-# was thrown by step 2
-15.4.4.22-4-10: FAIL
-# Bug? Array.prototype.reduceRight - the exception is not thrown if exception
-# was thrown by step 3
-15.4.4.22-4-11: FAIL
-# Bug? Array.prototype.reduceRight - calling with no callbackfn is the same as
-# passing undefined for callbackfn
-15.4.4.22-4-15: FAIL
-# Bug? Array.prototype.reduceRight - element to be retrieved is own accessor
-# property that overrides an inherited data property on an Array
-15.4.4.22-8-b-iii-1-12: FAIL
-# Bug? Array.prototype.reduceRight - element to be retrieved is own accessor
-# property without a get function on an Array
-15.4.4.22-8-b-iii-1-18: FAIL
-# Bug? Array.prototype.reduceRight - element to be retrieved is own accessor
-# property without a get function that overrides an inherited accessor
-# property on an Array
-15.4.4.22-8-b-iii-1-20: FAIL
-# Bug? Array.prototype.reduceRight - element changed by getter on current
-# iteration is observed in subsequent iterations on an Array
-15.4.4.22-8-b-iii-1-30: FAIL
-# Bug? Array.prototype.reduceRight - Exception in getter terminate iteration on
-# an Array
-15.4.4.22-8-b-iii-1-33: FAIL
-# Bug? Array.prototype.reduceRight - modifications to length don't change number
-# of iterations in step 9
-15.4.4.22-8-b-2: FAIL
-# Bug? Array.prototype.reduceRight - deleting own property in step 8 causes
-# deleted index property not to be visited on an Array
-15.4.4.22-9-b-9: FAIL
-# Bug? Array.prototype.reduceRight - deleting own property with prototype
-# property in step 8 causes prototype index property to be visited on an
-# Array
-15.4.4.22-9-b-13: FAIL
-# Bug? Array.prototype.reduceRight - decreasing length of array in step 8 does
-# not delete non-configurable properties
-15.4.4.22-9-b-16: FAIL
-# Bug? Array.prototype.reduceRight - deleting property of prototype causes
-# deleted index property not to be visited on an Array
-15.4.4.22-9-b-24: FAIL
-# Bug? Array.prototype.reduceRight - deleting own property with prototype
-# property causes prototype index property to be visited on an Array
-15.4.4.22-9-b-26: FAIL
-# Bug? Array.prototype.reduceRight - decreasing length of array does not delete
-# non-configurable properties
-15.4.4.22-9-b-29: FAIL
-# Bug? Array.prototype.reduceRight - element changed by getter on previous
-# iterations is observed on an Array
-15.4.4.22-9-c-i-30: FAIL
-# Bug? Array.prototype.reduceRight - modifications to length will change number
-# of iterations
-15.4.4.22-9-9: FAIL
-# Bug? String.prototype.trim - 'S' is a string with all WhiteSpace
-15.5.4.20-3-2: FAIL
-# Bug? String.prototype.trim - 'S' is a string with all union of WhiteSpace and
-# LineTerminator
-15.5.4.20-3-3: FAIL
-# Bug? String.prototype.trim - 'S' is a string start with union of all
-# LineTerminator and all WhiteSpace
-15.5.4.20-3-4: FAIL
-# Bug? String.prototype.trim - 'S' is a string end with union of all
-# LineTerminator and all WhiteSpace
-15.5.4.20-3-5: FAIL
-# Bug? String.prototype.trim - 'S' is a string start with union of all
-# LineTerminator and all WhiteSpace and end with union of all
-# LineTerminator and all WhiteSpace
-15.5.4.20-3-6: FAIL
-# Bug? String.prototype.trim handles whitepace and lineterminators (\\uFEFFabc)
-15.5.4.20-4-10: FAIL
-# Bug? String.prototype.trim handles whitepace and lineterminators (abc\\uFEFF)
-15.5.4.20-4-18: FAIL
-# Bug? String.prototype.trim handles whitepace and lineterminators
-# (\\uFEFF\\uFEFF)
-15.5.4.20-4-34: FAIL
-# Bug? Date.prototype.toISOString - RangeError is thrown when value of date is
-# Date(1970, 0, -99999999, 0, 0, 0, -1), the time zone is UTC(0)
-15.9.5.43-0-8: FAIL
-# Bug? Date.prototype.toISOString - RangeError is not thrown when value of date
-# is Date(1970, 0, 100000001, 0, 0, 0, -1), the time zone is UTC(0)
-15.9.5.43-0-11: FAIL
-# Bug? Date.prototype.toISOString - RangeError is not thrown when value of date
-# is Date(1970, 0, 100000001, 0, 0, 0, 0), the time zone is UTC(0)
-15.9.5.43-0-12: FAIL
-# Bug? Date.prototype.toISOString - RangeError is thrown when value of date is
-# Date(1970, 0, 100000001, 0, 0, 0, 1), the time zone is UTC(0)
-15.9.5.43-0-13: FAIL
-# Bug? Date.prototype.toISOString - when value of year is -Infinity
-# Date.prototype.toISOString throw the RangeError
-15.9.5.43-0-14: FAIL
-# Bug? Date.prototype.toISOString - value of year is Infinity
-# Date.prototype.toISOString throw the RangeError
-15.9.5.43-0-15: FAIL
-# Bug? RegExp - the thrown error is SyntaxError instead of RegExpError when 'F'
-# contains any character other than 'g', 'i', or 'm'
-15.10.4.1-3: FAIL
-# Bug? RegExp.prototype is itself a RegExp
-15.10.6: FAIL
-# Bug? RegExp.prototype.source is of type String
-15.10.7.1-1: FAIL
-# Bug? RegExp.prototype.source is a data property with default attribute values
-# (false)
-15.10.7.1-2: FAIL
-# Bug? RegExp.prototype.global is of type Boolean
-15.10.7.2-1: FAIL
-# Bug? RegExp.prototype.global is a data property with default attribute values
-# (false)
-15.10.7.2-2: FAIL
-# Bug? RegExp.prototype.ignoreCase is of type Boolean
-15.10.7.3-1: FAIL
-# Bug? RegExp.prototype.ignoreCase is a data property with default attribute
-# values (false)
-15.10.7.3-2: FAIL
-# Bug? RegExp.prototype.multiline is of type Boolean
-15.10.7.4-1: FAIL
-# Bug? RegExp.prototype.multiline is a data property with default attribute
-# values (false)
-15.10.7.4-2: FAIL
-# Bug? RegExp.prototype.lastIndex is of type Number
-15.10.7.5-1: FAIL
-# Bug? RegExp.prototype.lastIndex is a data property with specified attribute
-# values
-15.10.7.5-2: FAIL
-# Bug? Error.prototype.toString return the value of 'msg' when 'name' is empty
-# string and 'msg' isn't undefined
-15.11.4.4-8-1: FAIL
+
+##################### DELIBERATE INCOMPATIBILITIES #####################
+
+# We deliberately treat arguments to parseInt() with a leading zero as
+# octal numbers in order to not break the web.
+S15.1.2.2_A5.1_T1: FAIL_OK
+
+# This tests precision of Math.tan and Math.sin. The implementation for those
+# trigonometric functions are platform/compiler dependent. Furthermore, the
+# expectation values by far deviates from the actual result given by an
+# arbitrary-precision calculator, making those tests partly bogus.
+S15.8.2.16_A7: PASS || FAIL_OK
+S15.8.2.18_A7: PASS || FAIL_OK
+
+# We are more lenient in which string character escapes we allow than
+# the spec (7.8.4 p. 19) wants us to be. This is for compatibility.
+S7.8.4_A6.1_T4: FAIL_OK
+S7.8.4_A6.2_T1: FAIL_OK
+S7.8.4_A6.2_T2: FAIL_OK
+S7.8.4_A7.1_T4: FAIL_OK
+S7.8.4_A7.2_T1: FAIL_OK
+S7.8.4_A7.2_T2: FAIL_OK
+S7.8.4_A7.2_T3: FAIL_OK
+S7.8.4_A7.2_T4: FAIL_OK
+S7.8.4_A7.2_T5: FAIL_OK
+S7.8.4_A7.2_T6: FAIL_OK
+
+# Linux and Mac defaults to extended 80 bit floating point format in the FPU.
+# We follow the other major JS engines by keeping this default.
+S8.5_A2.2: PASS if ($system != linux || $arch == x64), FAIL_OK if ($system == linux && $arch != x64)
+S8.5_A2.1: PASS if ($system != linux || $arch == x64), FAIL_OK if ($system == linux && $arch != x64)
+
+############################ INVALID TESTS #############################
+
+# The reference value calculated by Test262 is incorrect if you run these tests
+# in PST/PDT between first Sunday in March and first Sunday in April. The DST
+# switch was moved in 2007 whereas Test262 bases the reference value on 2000.
+# Test262 Bug: https://bugs.ecmascript.org/show_bug.cgi?id=293
+S15.9.3.1_A5_T1: PASS || FAIL_OK
+S15.9.3.1_A5_T2: PASS || FAIL_OK
+S15.9.3.1_A5_T3: PASS || FAIL_OK
+S15.9.3.1_A5_T4: PASS || FAIL_OK
+S15.9.3.1_A5_T5: PASS || FAIL_OK
+S15.9.3.1_A5_T6: PASS || FAIL_OK
+
+############################ SKIPPED TESTS #############################
+
+# These tests take a looong time to run in debug mode.
+S15.1.3.2_A2.5_T1: PASS, SKIP if $mode == debug
+S15.1.3.1_A2.5_T1: PASS, SKIP if $mode == debug
+
+[ $arch == arm ]
+
+# BUG(3251225): Tests that timeout with --nocrankshaft.
+S15.1.3.1_A2.5_T1: SKIP
+S15.1.3.2_A2.5_T1: SKIP
+S15.1.3.1_A2.4_T1: SKIP
+S15.1.3.1_A2.5_T1: SKIP
+S15.1.3.2_A2.4_T1: SKIP
+S15.1.3.2_A2.5_T1: SKIP
+S15.1.3.3_A2.3_T1: SKIP
+S15.1.3.4_A2.3_T1: SKIP
+S15.1.3.1_A2.5_T1: SKIP
+S15.1.3.2_A2.5_T1: SKIP
+
+[ $arch == mips ]
+
+# BUG(3251225): Tests that timeout with --nocrankshaft.
+S15.1.3.1_A2.5_T1: SKIP
+S15.1.3.2_A2.5_T1: SKIP
+S15.1.3.1_A2.4_T1: SKIP
+S15.1.3.1_A2.5_T1: SKIP
+S15.1.3.2_A2.4_T1: SKIP
+S15.1.3.2_A2.5_T1: SKIP
+S15.1.3.3_A2.3_T1: SKIP
+S15.1.3.4_A2.3_T1: SKIP
+S15.1.3.1_A2.5_T1: SKIP
+S15.1.3.2_A2.5_T1: SKIP
diff --git a/test/test262/testcfg.py b/test/test262/testcfg.py
index 94820460..294b39c9 100644
--- a/test/test262/testcfg.py
+++ b/test/test262/testcfg.py
@@ -29,8 +29,14 @@
import test
import os
from os.path import join, exists
+import urllib
+import hashlib
+import tarfile
+TEST_262_ARCHIVE_REVISION = '3a890174343c' # This is the r309 revision.
+TEST_262_ARCHIVE_MD5 = 'be5d4cfbe69cef70430907b8f3a92b50'
+TEST_262_URL = 'http://hg.ecmascript.org/tests/test262/archive/%s.tar.bz2'
TEST_262_HARNESS = ['sta.js']
@@ -43,10 +49,10 @@ class Test262TestCase(test.TestCase):
self.root = root
def IsNegative(self):
- return self.filename.endswith('-n.js')
+ return '@negative' in self.GetSource()
def GetLabel(self):
- return "%s test262 %s %s" % (self.mode, self.GetGroup(), self.GetName())
+ return "%s test262 %s" % (self.mode, self.GetName())
def IsFailureOutput(self, output):
if output.exit_code != 0:
@@ -55,7 +61,6 @@ class Test262TestCase(test.TestCase):
def GetCommand(self):
result = self.context.GetVmCommand(self, self.mode)
- result += ['-e', 'var window = this']
result += self.framework
result.append(self.filename)
return result
@@ -63,9 +68,6 @@ class Test262TestCase(test.TestCase):
def GetName(self):
return self.path[-1]
- def GetGroup(self):
- return self.path[0]
-
def GetSource(self):
return open(self.filename).read()
@@ -75,13 +77,14 @@ class Test262TestConfiguration(test.TestConfiguration):
def __init__(self, context, root):
super(Test262TestConfiguration, self).__init__(context, root)
- def AddIETestCenter(self, tests, current_path, path, mode):
- current_root = join(self.root, 'data', 'test', 'suite', 'ietestcenter')
+ def ListTests(self, current_path, path, mode, variant_flags):
+ testroot = join(self.root, 'data', 'test', 'suite')
harness = [join(self.root, 'data', 'test', 'harness', f)
for f in TEST_262_HARNESS]
harness += [join(self.root, 'harness-adapt.js')]
- for root, dirs, files in os.walk(current_root):
- for dotted in [x for x in dirs if x.startswith('.')]:
+ tests = []
+ for root, dirs, files in os.walk(testroot):
+ for dotted in [x for x in dirs if x.startswith('.')]:
dirs.remove(dotted)
dirs.sort()
root_path = root[len(self.root):].split(os.path.sep)
@@ -89,27 +92,35 @@ class Test262TestConfiguration(test.TestConfiguration):
files.sort()
for file in files:
if file.endswith('.js'):
- if self.Contains(path, root_path):
- test_path = ['ietestcenter', file[:-3]]
+ test_path = ['test262', file[:-3]]
+ if self.Contains(path, test_path):
test = Test262TestCase(join(root, file), test_path, self.context,
self.root, mode, harness)
tests.append(test)
-
- def AddSputnikConvertedTests(self, tests, current_path, path, mode):
- # To be enabled
- pass
-
- def AddSputnikTests(self, tests, current_path, path, mode):
- # To be enabled
- pass
-
- def ListTests(self, current_path, path, mode, variant_flags):
- tests = []
- self.AddIETestCenter(tests, current_path, path, mode)
- self.AddSputnikConvertedTests(tests, current_path, path, mode)
- self.AddSputnikTests(tests, current_path, path, mode)
return tests
+ def DownloadData(self):
+ revision = TEST_262_ARCHIVE_REVISION
+ archive_url = TEST_262_URL % revision
+ archive_name = join(self.root, 'test262-%s.tar.bz2' % revision)
+ directory_name = join(self.root, "test262-%s" % revision)
+ if not exists(directory_name) or not exists(archive_name):
+ if not exists(archive_name):
+ print "Downloading test data from %s ..." % archive_url
+ urllib.urlretrieve(archive_url, archive_name)
+ if not exists(directory_name):
+ print "Extracting test262-%s.tar.bz2 ..." % revision
+ md5 = hashlib.md5()
+ with open(archive_name,'rb') as f:
+ for chunk in iter(lambda: f.read(8192), ''):
+ md5.update(chunk)
+ if md5.hexdigest() != TEST_262_ARCHIVE_MD5:
+ raise Exception("Hash mismatch of test data file")
+ archive = tarfile.open(archive_name, 'r:bz2')
+ archive.extractall(join(self.root))
+ if not exists(join(self.root, 'data')):
+ os.symlink(directory_name, join(self.root, 'data'))
+
def GetBuildRequirements(self):
return ['d8']