diff options
author | Michaƫl Zasso <mic.besace@gmail.com> | 2015-10-06 08:42:38 +0200 |
---|---|---|
committer | Ali Ijaz Sheikh <ofrobots@google.com> | 2015-10-14 11:20:34 -0700 |
commit | d8011d1683fe0d977de2bea1147f5213d4490c5a (patch) | |
tree | 54967df8dc1732e59eef39e5c5b39fe99ad88977 /deps/v8/test | |
parent | d1a2e5357ef0357cec9b516fa9ac78cc38a984aa (diff) | |
download | node-new-d8011d1683fe0d977de2bea1147f5213d4490c5a.tar.gz |
deps: upgrade V8 to 4.6.85.23
PR-URL: https://github.com/nodejs/node/pull/3351
Reviewed-By: indutny - Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/v8/test')
289 files changed, 12600 insertions, 3173 deletions
diff --git a/deps/v8/test/benchmarks/testcfg.py b/deps/v8/test/benchmarks/testcfg.py index 2a65037754..0c3698bd60 100644 --- a/deps/v8/test/benchmarks/testcfg.py +++ b/deps/v8/test/benchmarks/testcfg.py @@ -31,10 +31,25 @@ import shutil import subprocess import tarfile +from testrunner.local import statusfile from testrunner.local import testsuite from testrunner.objects import testcase +class BenchmarksVariantGenerator(testsuite.VariantGenerator): + # Both --nocrankshaft and --stressopt are very slow. Add TF but without + # always opt to match the way the benchmarks are run for performance + # testing. + def FilterVariantsByTest(self, testcase): + if testcase.outcomes and statusfile.OnlyStandardVariant( + testcase.outcomes): + return self.standard_variant + return self.fast_variants + + def GetFlagSets(self, testcase, variant): + return testsuite.FAST_VARIANT_FLAGS[variant] + + class BenchmarksTestSuite(testsuite.TestSuite): def __init__(self, name, root): @@ -182,11 +197,8 @@ class BenchmarksTestSuite(testsuite.TestSuite): os.chdir(old_cwd) - def VariantFlags(self, testcase, default_flags): - # Both --nocrankshaft and --stressopt are very slow. Add TF but without - # always opt to match the way the benchmarks are run for performance - # testing. - return [[], ["--turbo"]] + def _VariantGeneratorFactory(self): + return BenchmarksVariantGenerator def GetSuite(name, root): diff --git a/deps/v8/test/cctest/OWNERS b/deps/v8/test/cctest/OWNERS index 93565c5a7a..ea8a397300 100644 --- a/deps/v8/test/cctest/OWNERS +++ b/deps/v8/test/cctest/OWNERS @@ -3,3 +3,10 @@ per-file *-mips*=gergely.kis@imgtec.com per-file *-mips*=akos.palfi@imgtec.com per-file *-mips*=balazs.kilvady@imgtec.com per-file *-mips*=dusan.milosavljevic@imgtec.com +per-file *-ppc*=dstence@us.ibm.com +per-file *-ppc*=joransiu@ca.ibm.com +per-file *-ppc*=jyan@ca.ibm.com +per-file *-ppc*=mbrandy@us.ibm.com +per-file *-ppc*=michael_dawson@ca.ibm.com +per-file *-x87*=chunyang.dai@intel.com +per-file *-x87*=weiliang.lin@intel.com diff --git a/deps/v8/test/cctest/cctest.cc b/deps/v8/test/cctest/cctest.cc index 851096ddce..72be29c383 100644 --- a/deps/v8/test/cctest/cctest.cc +++ b/deps/v8/test/cctest/cctest.cc @@ -29,7 +29,7 @@ #include "test/cctest/cctest.h" #include "include/libplatform/libplatform.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "test/cctest/print-extension.h" #include "test/cctest/profiler-extension.h" #include "test/cctest/trace-extension.h" @@ -93,6 +93,12 @@ void CcTest::Run() { } callback_(); if (initialize_) { + if (v8::Locker::IsActive()) { + v8::Locker locker(isolate_); + EmptyMessageQueues(isolate_); + } else { + EmptyMessageQueues(isolate_); + } isolate_->Exit(); } } @@ -132,7 +138,10 @@ static void PrintTestList(CcTest* current) { class CcTestArrayBufferAllocator : public v8::ArrayBuffer::Allocator { - virtual void* Allocate(size_t length) { return malloc(length); } + virtual void* Allocate(size_t length) { + void* data = AllocateUninitialized(length); + return data == NULL ? data : memset(data, 0, length); + } virtual void* AllocateUninitialized(size_t length) { return malloc(length); } virtual void Free(void* data, size_t length) { free(data); } // TODO(dslomov): Remove when v8:2823 is fixed. diff --git a/deps/v8/test/cctest/cctest.gyp b/deps/v8/test/cctest/cctest.gyp index 8f0c58d38e..10207c1038 100644 --- a/deps/v8/test/cctest/cctest.gyp +++ b/deps/v8/test/cctest/cctest.gyp @@ -49,8 +49,6 @@ 'compiler/codegen-tester.h', 'compiler/function-tester.h', 'compiler/graph-builder-tester.h', - 'compiler/simplified-graph-builder.cc', - 'compiler/simplified-graph-builder.h', 'compiler/test-basic-block-profiler.cc', 'compiler/test-branch-combine.cc', 'compiler/test-changes-lowering.cc', @@ -78,12 +76,15 @@ 'compiler/test-run-jsexceptions.cc', 'compiler/test-run-jsops.cc', 'compiler/test-run-machops.cc', + 'compiler/test-run-native-calls.cc', 'compiler/test-run-properties.cc', 'compiler/test-run-stackcheck.cc', 'compiler/test-run-stubs.cc', 'compiler/test-run-variables.cc', 'compiler/test-simplified-lowering.cc', 'cctest.cc', + 'interpreter/test-bytecode-generator.cc', + 'interpreter/test-interpreter.cc', 'gay-fixed.cc', 'gay-precision.cc', 'gay-shortest.cc', @@ -145,6 +146,7 @@ 'test-representation.cc', 'test-sampler-api.cc', 'test-serialize.cc', + 'test-simd.cc', 'test-spaces.cc', 'test-strings.cc', 'test-symbols.cc', @@ -274,6 +276,11 @@ }, { 'dependencies': ['../../tools/gyp/v8.gyp:v8'], }], + ['v8_wasm!=0', { + 'dependencies': [ + '../../third_party/wasm/test/cctest/wasm/wasm.gyp:wasm_cctest' + ], + }], ], }, { diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h index cc9edc801f..5c19195208 100644 --- a/deps/v8/test/cctest/cctest.h +++ b/deps/v8/test/cctest/cctest.h @@ -28,6 +28,7 @@ #ifndef CCTEST_H_ #define CCTEST_H_ +#include "include/libplatform/libplatform.h" #include "src/v8.h" #ifndef TEST @@ -107,6 +108,7 @@ class CcTest { typedef void (TestFunction)(); CcTest(TestFunction* callback, const char* file, const char* name, const char* dependency, bool enabled, bool initialize); + ~CcTest() { i::DeleteArray(file_); } void Run(); static CcTest* last() { return last_; } CcTest* prev() { return prev_; } @@ -405,14 +407,6 @@ static inline v8::MaybeLocal<v8::Value> CompileRun( } -// Compiles source as an ES6 module. -static inline v8::Local<v8::Value> CompileRunModule(const char* source) { - v8::ScriptCompiler::Source script_source(v8_str(source)); - return v8::ScriptCompiler::CompileModule(v8::Isolate::GetCurrent(), - &script_source)->Run(); -} - - static inline v8::Local<v8::Value> CompileRun(v8::Local<v8::String> source) { return v8::Script::Compile(source)->Run(); } @@ -594,26 +588,11 @@ static inline void EnableDebugger() { static inline void DisableDebugger() { v8::Debug::SetDebugEventListener(NULL); } -// Helper class for new allocations tracking and checking. -// To use checking of JS allocations tracking in a test, -// just create an instance of this class. -class HeapObjectsTracker { - public: - HeapObjectsTracker() { - heap_profiler_ = i::Isolate::Current()->heap_profiler(); - CHECK_NOT_NULL(heap_profiler_); - heap_profiler_->StartHeapObjectsTracking(true); - } - - ~HeapObjectsTracker() { - i::Isolate::Current()->heap()->CollectAllAvailableGarbage(); - CHECK_EQ(0, heap_profiler_->heap_object_map()->FindUntrackedObjects()); - heap_profiler_->StopHeapObjectsTracking(); - } - - private: - i::HeapProfiler* heap_profiler_; -}; +static inline void EmptyMessageQueues(v8::Isolate* isolate) { + while (v8::platform::PumpMessageLoop(v8::internal::V8::GetCurrentPlatform(), + isolate)) + ; +} class InitializedHandleScope { diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status index 68c570edcc..013d0bf0da 100644 --- a/deps/v8/test/cctest/cctest.status +++ b/deps/v8/test/cctest/cctest.status @@ -96,6 +96,10 @@ # BUG(2340). Preprocessing stack traces is disabled at the moment. 'test-heap/PreprocessStackTrace': [FAIL], + # BUG(4333). Function name inferrer does not work for ES6 clases. + 'test-func-name-inference/UpperCaseClass': [FAIL], + 'test-func-name-inference/LowerCaseClass': [FAIL], + ############################################################################## # TurboFan compiler failures. @@ -104,7 +108,6 @@ 'test-heap-profiler/ManyLocalsInSharedContext': [PASS, NO_VARIANTS], 'test-serialize/SerializeToplevelLargeCodeObject': [PASS, NO_VARIANTS], 'test-debug/ThreadedDebugging': [PASS, NO_VARIANTS], - 'test-debug/DebugBreakLoop': [PASS, NO_VARIANTS], # BUG(3742). 'test-mark-compact/MarkCompactCollector': [PASS, ['arch==arm', NO_VARIANTS]], @@ -127,6 +130,9 @@ # TODO(machenbach, mvstanton): Flaky in debug on all platforms. 'test-lockers/LockerUnlocker': [PASS, ['mode == debug', FLAKY]], + + # BUG(4141). + 'test-alloc/CodeRange': [PASS, FLAKY], }], # ALWAYS ############################################################################## @@ -173,7 +179,6 @@ 'test-api/ExternalFloatArray': [SKIP], 'test-api/Float32Array': [SKIP], 'test-api/Float64Array': [SKIP], - 'test-debug/DebugBreakLoop': [SKIP], }], # 'arch == arm64 and mode == debug and simulator_run == True' ############################################################################## diff --git a/deps/v8/test/cctest/compiler/c-signature.h b/deps/v8/test/cctest/compiler/c-signature.h index 83b3328a3b..8eaf6325f2 100644 --- a/deps/v8/test/cctest/compiler/c-signature.h +++ b/deps/v8/test/cctest/compiler/c-signature.h @@ -69,6 +69,10 @@ class CSignature : public MachineSignature { } } + static CSignature* FromMachine(Zone* zone, MachineSignature* msig) { + return reinterpret_cast<CSignature*>(msig); + } + static CSignature* New(Zone* zone, MachineType ret, MachineType p1 = kMachNone, MachineType p2 = kMachNone, MachineType p3 = kMachNone, MachineType p4 = kMachNone, diff --git a/deps/v8/test/cctest/compiler/call-tester.h b/deps/v8/test/cctest/compiler/call-tester.h index dc265ea5fa..31a6d0f93b 100644 --- a/deps/v8/test/cctest/compiler/call-tester.h +++ b/deps/v8/test/cctest/compiler/call-tester.h @@ -304,6 +304,21 @@ class CallHelper { Isolate* isolate_; }; +// A call helper that calls the given code object assuming C calling convention. +template <typename T> +class CodeRunner : public CallHelper<T> { + public: + CodeRunner(Isolate* isolate, Handle<Code> code, CSignature* csig) + : CallHelper<T>(isolate, csig), code_(code) {} + virtual ~CodeRunner() {} + + virtual byte* Generate() { return code_->entry(); } + + private: + Handle<Code> code_; +}; + + } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/compiler/codegen-tester.cc b/deps/v8/test/cctest/compiler/codegen-tester.cc index d05b282293..98957c7f01 100644 --- a/deps/v8/test/cctest/compiler/codegen-tester.cc +++ b/deps/v8/test/cctest/compiler/codegen-tester.cc @@ -368,8 +368,6 @@ void Int32BinopInputShapeTester::RunRight( } -#if V8_TURBOFAN_TARGET - TEST(ParametersEqual) { RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); Node* p1 = m.Parameter(1); @@ -572,5 +570,3 @@ TEST(RunBinopTester) { FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(*i, bt.call(-11.25, *i)); } } } - -#endif // V8_TURBOFAN_TARGET diff --git a/deps/v8/test/cctest/compiler/codegen-tester.h b/deps/v8/test/cctest/compiler/codegen-tester.h index bc6d938ce1..d8ecc02fc2 100644 --- a/deps/v8/test/cctest/compiler/codegen-tester.h +++ b/deps/v8/test/cctest/compiler/codegen-tester.h @@ -34,8 +34,10 @@ class RawMachineAssemblerTester : public HandleAndZoneScope, p2, p3, p4)), RawMachineAssembler( main_isolate(), new (main_zone()) Graph(main_zone()), - CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1, - p2, p3, p4), + Linkage::GetSimplifiedCDescriptor( + main_zone(), + CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, + p1, p2, p3, p4)), kMachPtr, InstructionSelector::SupportedMachineOperatorFlags()) {} void CheckNumber(double expected, Object* number) { diff --git a/deps/v8/test/cctest/compiler/function-tester.h b/deps/v8/test/cctest/compiler/function-tester.h index 54c62ab634..56ab514c65 100644 --- a/deps/v8/test/cctest/compiler/function-tester.h +++ b/deps/v8/test/cctest/compiler/function-tester.h @@ -13,15 +13,13 @@ #include "src/compiler/linkage.h" #include "src/compiler/pipeline.h" #include "src/execution.h" -#include "src/full-codegen.h" +#include "src/full-codegen/full-codegen.h" #include "src/handles.h" #include "src/objects-inl.h" #include "src/parser.h" #include "src/rewriter.h" #include "src/scopes.h" -#define USE_CRANKSHAFT 0 - namespace v8 { namespace internal { namespace compiler { @@ -156,7 +154,6 @@ class FunctionTester : public InitializedHandleScope { Handle<JSFunction> Compile(Handle<JSFunction> function) { // TODO(titzer): make this method private. -#if V8_TURBOFAN_TARGET Zone zone; ParseInfo parse_info(&zone, function); CompilationInfo info(&parse_info); @@ -181,19 +178,6 @@ class FunctionTester : public InitializedHandleScope { CHECK(!code.is_null()); info.context()->native_context()->AddOptimizedCode(*code); function->ReplaceCode(*code); -#elif USE_CRANKSHAFT - Handle<Code> unoptimized = Handle<Code>(function->code()); - Handle<Code> code = Compiler::GetOptimizedCode(function, unoptimized, - Compiler::NOT_CONCURRENT); - CHECK(!code.is_null()); -#if ENABLE_DISASSEMBLER - if (FLAG_print_opt_code) { - CodeTracer::Scope tracing_scope(isolate->GetCodeTracer()); - code->Disassemble("test code", tracing_scope.file()); - } -#endif - function->ReplaceCode(*code); -#endif return function; } @@ -212,7 +196,6 @@ class FunctionTester : public InitializedHandleScope { // Compile the given machine graph instead of the source of the function // and replace the JSFunction's code with the result. Handle<JSFunction> CompileGraph(Graph* graph) { - CHECK(Pipeline::SupportedTarget()); Zone zone; ParseInfo parse_info(&zone, function); CompilationInfo info(&parse_info); diff --git a/deps/v8/test/cctest/compiler/graph-builder-tester.h b/deps/v8/test/cctest/compiler/graph-builder-tester.h index 7270293e0f..41c1e384be 100644 --- a/deps/v8/test/cctest/compiler/graph-builder-tester.h +++ b/deps/v8/test/cctest/compiler/graph-builder-tester.h @@ -9,13 +9,12 @@ #include "test/cctest/cctest.h" #include "src/compiler/common-operator.h" -#include "src/compiler/graph-builder.h" #include "src/compiler/linkage.h" #include "src/compiler/machine-operator.h" +#include "src/compiler/operator-properties.h" #include "src/compiler/pipeline.h" #include "src/compiler/simplified-operator.h" #include "test/cctest/compiler/call-tester.h" -#include "test/cctest/compiler/simplified-graph-builder.h" namespace v8 { namespace internal { @@ -29,6 +28,12 @@ class GraphAndBuilders { main_machine_(zone), main_simplified_(zone) {} + Graph* graph() const { return main_graph_; } + Zone* zone() const { return graph()->zone(); } + CommonOperatorBuilder* common() { return &main_common_; } + MachineOperatorBuilder* machine() { return &main_machine_; } + SimplifiedOperatorBuilder* simplified() { return &main_simplified_; } + protected: // Prefixed with main_ to avoid naming conflicts. Graph* main_graph_; @@ -40,9 +45,8 @@ class GraphAndBuilders { template <typename ReturnType> class GraphBuilderTester : public HandleAndZoneScope, - private GraphAndBuilders, - public CallHelper<ReturnType>, - public SimplifiedGraphBuilder { + public GraphAndBuilders, + public CallHelper<ReturnType> { public: explicit GraphBuilderTester(MachineType p0 = kMachNone, MachineType p1 = kMachNone, @@ -54,8 +58,8 @@ class GraphBuilderTester : public HandleAndZoneScope, main_isolate(), CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1, p2, p3, p4)), - SimplifiedGraphBuilder(main_isolate(), main_graph_, &main_common_, - &main_machine_, &main_simplified_), + effect_(NULL), + return_(NULL), parameters_(main_zone()->template NewArray<Node*>(parameter_count())) { Begin(static_cast<int>(parameter_count())); InitParameters(); @@ -68,16 +72,214 @@ class GraphBuilderTester : public HandleAndZoneScope, return parameters_[index]; } - Factory* factory() const { return isolate()->factory(); } + Isolate* isolate() { return main_isolate(); } + Factory* factory() { return isolate()->factory(); } + + // Initialize graph and builder. + void Begin(int num_parameters) { + DCHECK(graph()->start() == NULL); + Node* start = graph()->NewNode(common()->Start(num_parameters + 3)); + graph()->SetStart(start); + effect_ = start; + } + + void Return(Node* value) { + return_ = + graph()->NewNode(common()->Return(), value, effect_, graph()->start()); + effect_ = NULL; + } + + // Close the graph. + void End() { + Node* end = graph()->NewNode(common()->End(1), return_); + graph()->SetEnd(end); + } + + Node* PointerConstant(void* value) { + intptr_t intptr_value = reinterpret_cast<intptr_t>(value); + return kPointerSize == 8 ? NewNode(common()->Int64Constant(intptr_value)) + : Int32Constant(static_cast<int>(intptr_value)); + } + Node* Int32Constant(int32_t value) { + return NewNode(common()->Int32Constant(value)); + } + Node* HeapConstant(Handle<HeapObject> object) { + Unique<HeapObject> val = Unique<HeapObject>::CreateUninitialized(object); + return NewNode(common()->HeapConstant(val)); + } + + Node* BooleanNot(Node* a) { return NewNode(simplified()->BooleanNot(), a); } + + Node* NumberEqual(Node* a, Node* b) { + return NewNode(simplified()->NumberEqual(), a, b); + } + Node* NumberLessThan(Node* a, Node* b) { + return NewNode(simplified()->NumberLessThan(), a, b); + } + Node* NumberLessThanOrEqual(Node* a, Node* b) { + return NewNode(simplified()->NumberLessThanOrEqual(), a, b); + } + Node* NumberAdd(Node* a, Node* b) { + return NewNode(simplified()->NumberAdd(), a, b); + } + Node* NumberSubtract(Node* a, Node* b) { + return NewNode(simplified()->NumberSubtract(), a, b); + } + Node* NumberMultiply(Node* a, Node* b) { + return NewNode(simplified()->NumberMultiply(), a, b); + } + Node* NumberDivide(Node* a, Node* b) { + return NewNode(simplified()->NumberDivide(), a, b); + } + Node* NumberModulus(Node* a, Node* b) { + return NewNode(simplified()->NumberModulus(), a, b); + } + Node* NumberToInt32(Node* a) { + return NewNode(simplified()->NumberToInt32(), a); + } + Node* NumberToUint32(Node* a) { + return NewNode(simplified()->NumberToUint32(), a); + } + + Node* StringEqual(Node* a, Node* b) { + return NewNode(simplified()->StringEqual(), a, b); + } + Node* StringLessThan(Node* a, Node* b) { + return NewNode(simplified()->StringLessThan(), a, b); + } + Node* StringLessThanOrEqual(Node* a, Node* b) { + return NewNode(simplified()->StringLessThanOrEqual(), a, b); + } + + Node* ChangeTaggedToInt32(Node* a) { + return NewNode(simplified()->ChangeTaggedToInt32(), a); + } + Node* ChangeTaggedToUint32(Node* a) { + return NewNode(simplified()->ChangeTaggedToUint32(), a); + } + Node* ChangeTaggedToFloat64(Node* a) { + return NewNode(simplified()->ChangeTaggedToFloat64(), a); + } + Node* ChangeInt32ToTagged(Node* a) { + return NewNode(simplified()->ChangeInt32ToTagged(), a); + } + Node* ChangeUint32ToTagged(Node* a) { + return NewNode(simplified()->ChangeUint32ToTagged(), a); + } + Node* ChangeFloat64ToTagged(Node* a) { + return NewNode(simplified()->ChangeFloat64ToTagged(), a); + } + Node* ChangeBoolToBit(Node* a) { + return NewNode(simplified()->ChangeBoolToBit(), a); + } + Node* ChangeBitToBool(Node* a) { + return NewNode(simplified()->ChangeBitToBool(), a); + } + + Node* LoadField(const FieldAccess& access, Node* object) { + return NewNode(simplified()->LoadField(access), object); + } + Node* StoreField(const FieldAccess& access, Node* object, Node* value) { + return NewNode(simplified()->StoreField(access), object, value); + } + Node* LoadElement(const ElementAccess& access, Node* object, Node* index) { + return NewNode(simplified()->LoadElement(access), object, index); + } + Node* StoreElement(const ElementAccess& access, Node* object, Node* index, + Node* value) { + return NewNode(simplified()->StoreElement(access), object, index, value); + } + + Node* NewNode(const Operator* op) { + return MakeNode(op, 0, static_cast<Node**>(NULL)); + } + + Node* NewNode(const Operator* op, Node* n1) { return MakeNode(op, 1, &n1); } + + Node* NewNode(const Operator* op, Node* n1, Node* n2) { + Node* buffer[] = {n1, n2}; + return MakeNode(op, arraysize(buffer), buffer); + } + + Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) { + Node* buffer[] = {n1, n2, n3}; + return MakeNode(op, arraysize(buffer), buffer); + } + + Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) { + Node* buffer[] = {n1, n2, n3, n4}; + return MakeNode(op, arraysize(buffer), buffer); + } + + Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4, + Node* n5) { + Node* buffer[] = {n1, n2, n3, n4, n5}; + return MakeNode(op, arraysize(buffer), buffer); + } + + Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4, + Node* n5, Node* n6) { + Node* nodes[] = {n1, n2, n3, n4, n5, n6}; + return MakeNode(op, arraysize(nodes), nodes); + } + + Node* NewNode(const Operator* op, int value_input_count, + Node** value_inputs) { + return MakeNode(op, value_input_count, value_inputs); + } protected: + Node* MakeNode(const Operator* op, int value_input_count, + Node** value_inputs) { + DCHECK(op->ValueInputCount() == value_input_count); + + DCHECK(!OperatorProperties::HasContextInput(op)); + DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op)); + bool has_control = op->ControlInputCount() == 1; + bool has_effect = op->EffectInputCount() == 1; + + DCHECK(op->ControlInputCount() < 2); + DCHECK(op->EffectInputCount() < 2); + + Node* result = NULL; + if (!has_control && !has_effect) { + result = graph()->NewNode(op, value_input_count, value_inputs); + } else { + int input_count_with_deps = value_input_count; + if (has_control) ++input_count_with_deps; + if (has_effect) ++input_count_with_deps; + Node** buffer = zone()->template NewArray<Node*>(input_count_with_deps); + memcpy(buffer, value_inputs, kPointerSize * value_input_count); + Node** current_input = buffer + value_input_count; + if (has_effect) { + *current_input++ = effect_; + } + if (has_control) { + *current_input++ = graph()->start(); + } + result = graph()->NewNode(op, input_count_with_deps, buffer); + if (has_effect) { + effect_ = result; + } + // This graph builder does not support control flow. + CHECK_EQ(0, op->ControlOutputCount()); + } + + return result; + } + virtual byte* Generate() { - if (!Pipeline::SupportedBackend()) return NULL; if (code_.is_null()) { Zone* zone = graph()->zone(); CallDescriptor* desc = Linkage::GetSimplifiedCDescriptor(zone, this->csig_); code_ = Pipeline::GenerateCodeForTesting(main_isolate(), desc, graph()); +#ifdef ENABLE_DISASSEMBLER + if (!code_.is_null() && FLAG_print_opt_code) { + OFStream os(stdout); + code_.ToHandleChecked()->Disassemble("test code", os); + } +#endif } return code_.ToHandleChecked()->entry(); } @@ -92,6 +294,8 @@ class GraphBuilderTester : public HandleAndZoneScope, size_t parameter_count() const { return this->csig_->parameter_count(); } private: + Node* effect_; + Node* return_; Node** parameters_; MaybeHandle<Code> code_; }; diff --git a/deps/v8/test/cctest/compiler/instruction-selector-tester.h b/deps/v8/test/cctest/compiler/instruction-selector-tester.h deleted file mode 100644 index 3a28b2e5df..0000000000 --- a/deps/v8/test/cctest/compiler/instruction-selector-tester.h +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_ -#define V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_ - -#include <deque> -#include <set> - -#include "src/compiler/instruction-selector.h" -#include "src/compiler/raw-machine-assembler.h" -#include "src/ostreams.h" -#include "test/cctest/cctest.h" - -namespace v8 { -namespace internal { -namespace compiler { - -typedef std::set<int> VirtualRegisterSet; - -enum InstructionSelectorTesterMode { kTargetMode, kInternalMode }; - -class InstructionSelectorTester : public HandleAndZoneScope, - public RawMachineAssembler { - public: - enum Mode { kTargetMode, kInternalMode }; - - static const int kParameterCount = 3; - static MachineType* BuildParameterArray(Zone* zone) { - MachineType* array = zone->NewArray<MachineType>(kParameterCount); - for (int i = 0; i < kParameterCount; ++i) { - array[i] = kMachInt32; - } - return array; - } - - InstructionSelectorTester() - : RawMachineAssembler( - new (main_zone()) Graph(main_zone()), - new (main_zone()) MachineCallDescriptorBuilder( - kMachInt32, kParameterCount, BuildParameterArray(main_zone())), - kMachPtr) {} - - void SelectInstructions(CpuFeature feature) { - SelectInstructions(InstructionSelector::Features(feature)); - } - - void SelectInstructions(CpuFeature feature1, CpuFeature feature2) { - SelectInstructions(InstructionSelector::Features(feature1, feature2)); - } - - void SelectInstructions(Mode mode = kTargetMode) { - SelectInstructions(InstructionSelector::Features(), mode); - } - - void SelectInstructions(InstructionSelector::Features features, - Mode mode = kTargetMode) { - OFStream out(stdout); - Schedule* schedule = Export(); - CHECK_NE(0, graph()->NodeCount()); - CompilationInfo info(main_isolate(), main_zone()); - Linkage linkage(&info, call_descriptor()); - InstructionSequence sequence(&linkage, graph(), schedule); - SourcePositionTable source_positions(graph()); - InstructionSelector selector(&sequence, &source_positions, features); - selector.SelectInstructions(); - out << "--- Code sequence after instruction selection --- " << endl - << sequence; - for (InstructionSequence::const_iterator i = sequence.begin(); - i != sequence.end(); ++i) { - Instruction* instr = *i; - if (instr->opcode() < 0) continue; - if (mode == kTargetMode) { - switch (ArchOpcodeField::decode(instr->opcode())) { -#define CASE(Name) \ - case k##Name: \ - break; - TARGET_ARCH_OPCODE_LIST(CASE) -#undef CASE - default: - continue; - } - } - code.push_back(instr); - } - for (int vreg = 0; vreg < sequence.VirtualRegisterCount(); ++vreg) { - if (sequence.IsDouble(vreg)) { - CHECK(!sequence.IsReference(vreg)); - doubles.insert(vreg); - } - if (sequence.IsReference(vreg)) { - CHECK(!sequence.IsDouble(vreg)); - references.insert(vreg); - } - } - immediates.assign(sequence.immediates().begin(), - sequence.immediates().end()); - } - - int32_t ToInt32(const InstructionOperand* operand) const { - size_t i = operand->index(); - CHECK(i < immediates.size()); - CHECK_EQ(InstructionOperand::IMMEDIATE, operand->kind()); - return immediates[i].ToInt32(); - } - - std::deque<Instruction*> code; - VirtualRegisterSet doubles; - VirtualRegisterSet references; - std::deque<Constant> immediates; -}; - - -static inline void CheckSameVreg(InstructionOperand* exp, - InstructionOperand* val) { - CHECK_EQ(InstructionOperand::UNALLOCATED, exp->kind()); - CHECK_EQ(InstructionOperand::UNALLOCATED, val->kind()); - CHECK_EQ(UnallocatedOperand::cast(exp)->virtual_register(), - UnallocatedOperand::cast(val)->virtual_register()); -} - -} // namespace compiler -} // namespace internal -} // namespace v8 - -#endif // V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_ diff --git a/deps/v8/test/cctest/compiler/simplified-graph-builder.cc b/deps/v8/test/cctest/compiler/simplified-graph-builder.cc deleted file mode 100644 index 4d57719eff..0000000000 --- a/deps/v8/test/cctest/compiler/simplified-graph-builder.cc +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "test/cctest/compiler/simplified-graph-builder.h" - -#include "src/compiler/operator-properties.h" - -namespace v8 { -namespace internal { -namespace compiler { - -SimplifiedGraphBuilder::SimplifiedGraphBuilder( - Isolate* isolate, Graph* graph, CommonOperatorBuilder* common, - MachineOperatorBuilder* machine, SimplifiedOperatorBuilder* simplified) - : GraphBuilder(isolate, graph), - effect_(NULL), - return_(NULL), - common_(common), - machine_(machine), - simplified_(simplified) {} - - -void SimplifiedGraphBuilder::Begin(int num_parameters) { - DCHECK(graph()->start() == NULL); - Node* start = graph()->NewNode(common()->Start(num_parameters + 3)); - graph()->SetStart(start); - effect_ = start; -} - - -void SimplifiedGraphBuilder::Return(Node* value) { - return_ = - graph()->NewNode(common()->Return(), value, effect_, graph()->start()); - effect_ = NULL; -} - - -void SimplifiedGraphBuilder::End() { - Node* end = graph()->NewNode(common()->End(1), return_); - graph()->SetEnd(end); -} - - -Node* SimplifiedGraphBuilder::MakeNode(const Operator* op, - int value_input_count, - Node** value_inputs, bool incomplete) { - DCHECK(op->ValueInputCount() == value_input_count); - - DCHECK(!OperatorProperties::HasContextInput(op)); - DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op)); - bool has_control = op->ControlInputCount() == 1; - bool has_effect = op->EffectInputCount() == 1; - - DCHECK(op->ControlInputCount() < 2); - DCHECK(op->EffectInputCount() < 2); - - Node* result = NULL; - if (!has_control && !has_effect) { - result = graph()->NewNode(op, value_input_count, value_inputs, incomplete); - } else { - int input_count_with_deps = value_input_count; - if (has_control) ++input_count_with_deps; - if (has_effect) ++input_count_with_deps; - Node** buffer = zone()->NewArray<Node*>(input_count_with_deps); - memcpy(buffer, value_inputs, kPointerSize * value_input_count); - Node** current_input = buffer + value_input_count; - if (has_effect) { - *current_input++ = effect_; - } - if (has_control) { - *current_input++ = graph()->start(); - } - result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete); - if (has_effect) { - effect_ = result; - } - // This graph builder does not support control flow. - CHECK_EQ(0, op->ControlOutputCount()); - } - - return result; -} - -} // namespace compiler -} // namespace internal -} // namespace v8 diff --git a/deps/v8/test/cctest/compiler/simplified-graph-builder.h b/deps/v8/test/cctest/compiler/simplified-graph-builder.h deleted file mode 100644 index 50c51d5ed8..0000000000 --- a/deps/v8/test/cctest/compiler/simplified-graph-builder.h +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8_CCTEST_COMPILER_SIMPLIFIED_GRAPH_BUILDER_H_ -#define V8_CCTEST_COMPILER_SIMPLIFIED_GRAPH_BUILDER_H_ - -#include "src/compiler/common-operator.h" -#include "src/compiler/graph-builder.h" -#include "src/compiler/machine-operator.h" -#include "src/compiler/simplified-operator.h" -#include "test/cctest/cctest.h" -#include "test/cctest/compiler/call-tester.h" - -namespace v8 { -namespace internal { -namespace compiler { - -class SimplifiedGraphBuilder : public GraphBuilder { - public: - SimplifiedGraphBuilder(Isolate* isolate, Graph* graph, - CommonOperatorBuilder* common, - MachineOperatorBuilder* machine, - SimplifiedOperatorBuilder* simplified); - virtual ~SimplifiedGraphBuilder() {} - - Zone* zone() const { return graph()->zone(); } - CommonOperatorBuilder* common() const { return common_; } - MachineOperatorBuilder* machine() const { return machine_; } - SimplifiedOperatorBuilder* simplified() const { return simplified_; } - - // Initialize graph and builder. - void Begin(int num_parameters); - - void Return(Node* value); - - // Close the graph. - void End(); - - Node* PointerConstant(void* value) { - intptr_t intptr_value = reinterpret_cast<intptr_t>(value); - return kPointerSize == 8 ? NewNode(common()->Int64Constant(intptr_value)) - : Int32Constant(static_cast<int>(intptr_value)); - } - Node* Int32Constant(int32_t value) { - return NewNode(common()->Int32Constant(value)); - } - Node* HeapConstant(Handle<HeapObject> object) { - Unique<HeapObject> val = Unique<HeapObject>::CreateUninitialized(object); - return NewNode(common()->HeapConstant(val)); - } - - Node* BooleanNot(Node* a) { return NewNode(simplified()->BooleanNot(), a); } - - Node* NumberEqual(Node* a, Node* b) { - return NewNode(simplified()->NumberEqual(), a, b); - } - Node* NumberLessThan(Node* a, Node* b) { - return NewNode(simplified()->NumberLessThan(), a, b); - } - Node* NumberLessThanOrEqual(Node* a, Node* b) { - return NewNode(simplified()->NumberLessThanOrEqual(), a, b); - } - Node* NumberAdd(Node* a, Node* b) { - return NewNode(simplified()->NumberAdd(), a, b); - } - Node* NumberSubtract(Node* a, Node* b) { - return NewNode(simplified()->NumberSubtract(), a, b); - } - Node* NumberMultiply(Node* a, Node* b) { - return NewNode(simplified()->NumberMultiply(), a, b); - } - Node* NumberDivide(Node* a, Node* b) { - return NewNode(simplified()->NumberDivide(), a, b); - } - Node* NumberModulus(Node* a, Node* b) { - return NewNode(simplified()->NumberModulus(), a, b); - } - Node* NumberToInt32(Node* a) { - return NewNode(simplified()->NumberToInt32(), a); - } - Node* NumberToUint32(Node* a) { - return NewNode(simplified()->NumberToUint32(), a); - } - - Node* StringEqual(Node* a, Node* b) { - return NewNode(simplified()->StringEqual(), a, b); - } - Node* StringLessThan(Node* a, Node* b) { - return NewNode(simplified()->StringLessThan(), a, b); - } - Node* StringLessThanOrEqual(Node* a, Node* b) { - return NewNode(simplified()->StringLessThanOrEqual(), a, b); - } - - Node* ChangeTaggedToInt32(Node* a) { - return NewNode(simplified()->ChangeTaggedToInt32(), a); - } - Node* ChangeTaggedToUint32(Node* a) { - return NewNode(simplified()->ChangeTaggedToUint32(), a); - } - Node* ChangeTaggedToFloat64(Node* a) { - return NewNode(simplified()->ChangeTaggedToFloat64(), a); - } - Node* ChangeInt32ToTagged(Node* a) { - return NewNode(simplified()->ChangeInt32ToTagged(), a); - } - Node* ChangeUint32ToTagged(Node* a) { - return NewNode(simplified()->ChangeUint32ToTagged(), a); - } - Node* ChangeFloat64ToTagged(Node* a) { - return NewNode(simplified()->ChangeFloat64ToTagged(), a); - } - Node* ChangeBoolToBit(Node* a) { - return NewNode(simplified()->ChangeBoolToBit(), a); - } - Node* ChangeBitToBool(Node* a) { - return NewNode(simplified()->ChangeBitToBool(), a); - } - - Node* LoadField(const FieldAccess& access, Node* object) { - return NewNode(simplified()->LoadField(access), object); - } - Node* StoreField(const FieldAccess& access, Node* object, Node* value) { - return NewNode(simplified()->StoreField(access), object, value); - } - Node* LoadElement(const ElementAccess& access, Node* object, Node* index) { - return NewNode(simplified()->LoadElement(access), object, index); - } - Node* StoreElement(const ElementAccess& access, Node* object, Node* index, - Node* value) { - return NewNode(simplified()->StoreElement(access), object, index, value); - } - - protected: - virtual Node* MakeNode(const Operator* op, int value_input_count, - Node** value_inputs, bool incomplete) final; - - private: - Node* effect_; - Node* return_; - CommonOperatorBuilder* common_; - MachineOperatorBuilder* machine_; - SimplifiedOperatorBuilder* simplified_; -}; - -} // namespace compiler -} // namespace internal -} // namespace v8 - -#endif // V8_CCTEST_COMPILER_SIMPLIFIED_GRAPH_BUILDER_H_ diff --git a/deps/v8/test/cctest/compiler/test-basic-block-profiler.cc b/deps/v8/test/cctest/compiler/test-basic-block-profiler.cc index fa4da9a736..7d7690bad6 100644 --- a/deps/v8/test/cctest/compiler/test-basic-block-profiler.cc +++ b/deps/v8/test/cctest/compiler/test-basic-block-profiler.cc @@ -8,8 +8,6 @@ #include "test/cctest/cctest.h" #include "test/cctest/compiler/codegen-tester.h" -#if V8_TURBOFAN_TARGET - using namespace v8::internal; using namespace v8::internal::compiler; @@ -110,5 +108,3 @@ TEST(ProfileLoop) { m.Expect(arraysize(expected), expected); } } - -#endif // V8_TURBOFAN_TARGET diff --git a/deps/v8/test/cctest/compiler/test-branch-combine.cc b/deps/v8/test/cctest/compiler/test-branch-combine.cc index 58202a61b0..06d380a6a2 100644 --- a/deps/v8/test/cctest/compiler/test-branch-combine.cc +++ b/deps/v8/test/cctest/compiler/test-branch-combine.cc @@ -8,8 +8,6 @@ #include "test/cctest/compiler/codegen-tester.h" #include "test/cctest/compiler/value-helper.h" -#if V8_TURBOFAN_TARGET - using namespace v8::internal; using namespace v8::internal::compiler; @@ -459,4 +457,3 @@ TEST(BranchCombineFloat64Compares) { } } } -#endif // V8_TURBOFAN_TARGET diff --git a/deps/v8/test/cctest/compiler/test-changes-lowering.cc b/deps/v8/test/cctest/compiler/test-changes-lowering.cc index 04b5b9176b..b6b48bdac4 100644 --- a/deps/v8/test/cctest/compiler/test-changes-lowering.cc +++ b/deps/v8/test/cctest/compiler/test-changes-lowering.cc @@ -147,7 +147,6 @@ TEST(RunChangeTaggedToInt32) { ChangesLoweringTester<int32_t> t(kMachAnyTagged); t.BuildAndLower(t.simplified()->ChangeTaggedToInt32()); - if (Pipeline::SupportedTarget()) { FOR_INT32_INPUTS(i) { int32_t input = *i; @@ -167,7 +166,6 @@ TEST(RunChangeTaggedToInt32) { int32_t result = t.Call(*number); CHECK_EQ(input, result); } - } } } @@ -177,7 +175,6 @@ TEST(RunChangeTaggedToUint32) { ChangesLoweringTester<uint32_t> t(kMachAnyTagged); t.BuildAndLower(t.simplified()->ChangeTaggedToUint32()); - if (Pipeline::SupportedTarget()) { FOR_UINT32_INPUTS(i) { uint32_t input = *i; @@ -198,7 +195,6 @@ TEST(RunChangeTaggedToUint32) { CHECK_EQ(static_cast<int32_t>(input), static_cast<int32_t>(result)); } } - } } @@ -211,7 +207,7 @@ TEST(RunChangeTaggedToFloat64) { t.machine()->Store(StoreRepresentation(kMachFloat64, kNoWriteBarrier)), &result); - if (Pipeline::SupportedTarget()) { + { FOR_INT32_INPUTS(i) { int32_t input = *i; @@ -234,7 +230,7 @@ TEST(RunChangeTaggedToFloat64) { } } - if (Pipeline::SupportedTarget()) { + { FOR_FLOAT64_INPUTS(i) { double input = *i; { @@ -257,13 +253,13 @@ TEST(RunChangeBoolToBit) { ChangesLoweringTester<int32_t> t(kMachAnyTagged); t.BuildAndLower(t.simplified()->ChangeBoolToBit()); - if (Pipeline::SupportedTarget()) { + { Object* true_obj = t.heap()->true_value(); int32_t result = t.Call(true_obj); CHECK_EQ(1, result); } - if (Pipeline::SupportedTarget()) { + { Object* false_obj = t.heap()->false_value(); int32_t result = t.Call(false_obj); CHECK_EQ(0, result); @@ -275,122 +271,15 @@ TEST(RunChangeBitToBool) { ChangesLoweringTester<Object*> t(kMachInt32); t.BuildAndLower(t.simplified()->ChangeBitToBool()); - if (Pipeline::SupportedTarget()) { + { Object* result = t.Call(1); Object* true_obj = t.heap()->true_value(); CHECK_EQ(true_obj, result); } - if (Pipeline::SupportedTarget()) { + { Object* result = t.Call(0); Object* false_obj = t.heap()->false_value(); CHECK_EQ(false_obj, result); } } - - -#if V8_TURBOFAN_BACKEND -// TODO(titzer): disabled on ARM - -TEST(RunChangeInt32ToTaggedSmi) { - ChangesLoweringTester<Object*> t; - int32_t input; - t.BuildLoadAndLower(t.simplified()->ChangeInt32ToTagged(), - t.machine()->Load(kMachInt32), &input); - - if (Pipeline::SupportedTarget()) { - FOR_INT32_INPUTS(i) { - input = *i; - if (!Smi::IsValid(input)) continue; - Object* result = t.Call(); - t.CheckNumber(static_cast<double>(input), result); - } - } -} - - -TEST(RunChangeUint32ToTaggedSmi) { - ChangesLoweringTester<Object*> t; - uint32_t input; - t.BuildLoadAndLower(t.simplified()->ChangeUint32ToTagged(), - t.machine()->Load(kMachUint32), &input); - - if (Pipeline::SupportedTarget()) { - FOR_UINT32_INPUTS(i) { - input = *i; - if (input > static_cast<uint32_t>(Smi::kMaxValue)) continue; - Object* result = t.Call(); - double expected = static_cast<double>(input); - t.CheckNumber(expected, result); - } - } -} - - -TEST(RunChangeInt32ToTagged) { - ChangesLoweringTester<Object*> t; - int32_t input; - t.BuildLoadAndLower(t.simplified()->ChangeInt32ToTagged(), - t.machine()->Load(kMachInt32), &input); - - if (Pipeline::SupportedTarget()) { - for (int m = 0; m < 3; m++) { // Try 3 GC modes. - FOR_INT32_INPUTS(i) { - if (m == 0) CcTest::heap()->EnableInlineAllocation(); - if (m == 1) CcTest::heap()->DisableInlineAllocation(); - if (m == 2) SimulateFullSpace(CcTest::heap()->new_space()); - - input = *i; - Object* result = t.CallWithPotentialGC<Object>(); - t.CheckNumber(static_cast<double>(input), result); - } - } - } -} - - -TEST(RunChangeUint32ToTagged) { - ChangesLoweringTester<Object*> t; - uint32_t input; - t.BuildLoadAndLower(t.simplified()->ChangeUint32ToTagged(), - t.machine()->Load(kMachUint32), &input); - - if (Pipeline::SupportedTarget()) { - for (int m = 0; m < 3; m++) { // Try 3 GC modes. - FOR_UINT32_INPUTS(i) { - if (m == 0) CcTest::heap()->EnableInlineAllocation(); - if (m == 1) CcTest::heap()->DisableInlineAllocation(); - if (m == 2) SimulateFullSpace(CcTest::heap()->new_space()); - - input = *i; - Object* result = t.CallWithPotentialGC<Object>(); - double expected = static_cast<double>(input); - t.CheckNumber(expected, result); - } - } - } -} - - -TEST(RunChangeFloat64ToTagged) { - ChangesLoweringTester<Object*> t; - double input; - t.BuildLoadAndLower(t.simplified()->ChangeFloat64ToTagged(), - t.machine()->Load(kMachFloat64), &input); - - if (Pipeline::SupportedTarget()) { - for (int m = 0; m < 3; m++) { // Try 3 GC modes. - FOR_FLOAT64_INPUTS(i) { - if (m == 0) CcTest::heap()->EnableInlineAllocation(); - if (m == 1) CcTest::heap()->DisableInlineAllocation(); - if (m == 2) SimulateFullSpace(CcTest::heap()->new_space()); - - input = *i; - Object* result = t.CallWithPotentialGC<Object>(); - t.CheckNumber(input, result); - } - } - } -} - -#endif // V8_TURBOFAN_BACKEND diff --git a/deps/v8/test/cctest/compiler/test-linkage.cc b/deps/v8/test/cctest/compiler/test-linkage.cc index 252c43133e..29da5890ea 100644 --- a/deps/v8/test/cctest/compiler/test-linkage.cc +++ b/deps/v8/test/cctest/compiler/test-linkage.cc @@ -19,8 +19,6 @@ #include "src/compiler/schedule.h" #include "test/cctest/cctest.h" -#if V8_TURBOFAN_TARGET - using namespace v8::internal; using namespace v8::internal::compiler; @@ -80,7 +78,7 @@ TEST(TestLinkageCodeStubIncoming) { CompilationInfo info(&stub, isolate, &zone); CallDescriptor* descriptor = Linkage::ComputeIncoming(&zone, &info); CHECK(descriptor); - CHECK_EQ(1, static_cast<int>(descriptor->JSParameterCount())); + CHECK_EQ(0, static_cast<int>(descriptor->StackParameterCount())); CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount())); CHECK_EQ(Operator::kNoProperties, descriptor->properties()); CHECK_EQ(false, descriptor->IsJSFunctionCall()); @@ -113,5 +111,3 @@ TEST(TestLinkageRuntimeCall) { TEST(TestLinkageStubCall) { // TODO(titzer): test linkage creation for outgoing stub calls. } - -#endif // V8_TURBOFAN_TARGET diff --git a/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc b/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc index ad05273995..b59f181f5e 100644 --- a/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc +++ b/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc @@ -36,7 +36,7 @@ struct TestHelper : public HandleAndZoneScope { CHECK(Rewriter::Rewrite(&parse_info)); CHECK(Scope::Analyze(&parse_info)); - Scope* scope = info.function()->scope(); + Scope* scope = info.literal()->scope(); AstValueFactory* factory = parse_info.ast_value_factory(); CHECK(scope); diff --git a/deps/v8/test/cctest/compiler/test-operator.cc b/deps/v8/test/cctest/compiler/test-operator.cc index e635da797d..0ac33637da 100644 --- a/deps/v8/test/cctest/compiler/test-operator.cc +++ b/deps/v8/test/cctest/compiler/test-operator.cc @@ -69,10 +69,10 @@ TEST(TestOperator_Equals) { } -static SmartArrayPointer<const char> OperatorToString(Operator* op) { +static v8::base::SmartArrayPointer<const char> OperatorToString(Operator* op) { std::ostringstream os; os << *op; - return SmartArrayPointer<const char>(StrDup(os.str().c_str())); + return v8::base::SmartArrayPointer<const char>(StrDup(os.str().c_str())); } diff --git a/deps/v8/test/cctest/compiler/test-pipeline.cc b/deps/v8/test/cctest/compiler/test-pipeline.cc index 84550d502a..8996718644 100644 --- a/deps/v8/test/cctest/compiler/test-pipeline.cc +++ b/deps/v8/test/cctest/compiler/test-pipeline.cc @@ -21,13 +21,8 @@ static void RunPipeline(Zone* zone, const char* source) { CompilationInfo info(&parse_info); Pipeline pipeline(&info); -#if V8_TURBOFAN_TARGET Handle<Code> code = pipeline.GenerateCode(); - CHECK(Pipeline::SupportedTarget()); CHECK(!code.is_null()); -#else - USE(pipeline); -#endif } diff --git a/deps/v8/test/cctest/compiler/test-run-deopt.cc b/deps/v8/test/cctest/compiler/test-run-deopt.cc index d895924324..aedf668f44 100644 --- a/deps/v8/test/cctest/compiler/test-run-deopt.cc +++ b/deps/v8/test/cctest/compiler/test-run-deopt.cc @@ -4,14 +4,13 @@ #include "src/v8.h" +#include "src/frames-inl.h" #include "test/cctest/cctest.h" #include "test/cctest/compiler/function-tester.h" using namespace v8::internal; using namespace v8::internal::compiler; -#if V8_TURBOFAN_TARGET - static void IsOptimized(const v8::FunctionCallbackInfo<v8::Value>& args) { JavaScriptFrameIterator it(CcTest::i_isolate()); JavaScriptFrame* frame = it.frame(); @@ -103,7 +102,6 @@ TEST(DeoptExceptionHandlerFinally) { #endif } -#endif TEST(DeoptTrivial) { FLAG_allow_natives_syntax = true; diff --git a/deps/v8/test/cctest/compiler/test-run-inlining.cc b/deps/v8/test/cctest/compiler/test-run-inlining.cc index 7f8ae25619..1b2559fc5f 100644 --- a/deps/v8/test/cctest/compiler/test-run-inlining.cc +++ b/deps/v8/test/cctest/compiler/test-run-inlining.cc @@ -4,10 +4,9 @@ #include "src/v8.h" +#include "src/frames-inl.h" #include "test/cctest/compiler/function-tester.h" -#if V8_TURBOFAN_TARGET - using namespace v8::internal; using namespace v8::internal::compiler; @@ -574,5 +573,3 @@ TEST(InlineMutuallyRecursive) { InstallAssertInlineCountHelper(CcTest::isolate()); T.CheckCall(T.Val(42), T.Val(1)); } - -#endif // V8_TURBOFAN_TARGET diff --git a/deps/v8/test/cctest/compiler/test-run-jscalls.cc b/deps/v8/test/cctest/compiler/test-run-jscalls.cc index 8de2d7a214..893c2fa460 100644 --- a/deps/v8/test/cctest/compiler/test-run-jscalls.cc +++ b/deps/v8/test/cctest/compiler/test-run-jscalls.cc @@ -132,20 +132,6 @@ TEST(ConstructorCall) { // TODO(titzer): factor these out into test-runtime-calls.cc -TEST(RuntimeCallCPP1) { - FLAG_allow_natives_syntax = true; - FunctionTester T("(function(a) { return %ToBool(a); })"); - - T.CheckCall(T.true_value(), T.Val(23), T.undefined()); - T.CheckCall(T.true_value(), T.Val(4.2), T.undefined()); - T.CheckCall(T.true_value(), T.Val("str"), T.undefined()); - T.CheckCall(T.true_value(), T.true_value(), T.undefined()); - T.CheckCall(T.false_value(), T.false_value(), T.undefined()); - T.CheckCall(T.false_value(), T.undefined(), T.undefined()); - T.CheckCall(T.false_value(), T.Val(0.0), T.undefined()); -} - - TEST(RuntimeCallCPP2) { FLAG_allow_natives_syntax = true; FunctionTester T("(function(a,b) { return %NumberAdd(a, b); })"); diff --git a/deps/v8/test/cctest/compiler/test-run-machops.cc b/deps/v8/test/cctest/compiler/test-run-machops.cc index b1fc36968f..8b14dab46c 100644 --- a/deps/v8/test/cctest/compiler/test-run-machops.cc +++ b/deps/v8/test/cctest/compiler/test-run-machops.cc @@ -13,8 +13,6 @@ #include "test/cctest/compiler/codegen-tester.h" #include "test/cctest/compiler/value-helper.h" -#if V8_TURBOFAN_TARGET - using namespace v8::base; using namespace v8::internal; using namespace v8::internal::compiler; @@ -82,7 +80,14 @@ TEST(CodeGenInt32Binop) { } -#if V8_TURBOFAN_BACKEND_64 +TEST(CodeGenNop) { + RawMachineAssemblerTester<void> m; + m.Return(m.Int32Constant(0)); + m.GenerateCode(); +} + + +#if V8_TARGET_ARCH_64_BIT static Node* Int64Input(RawMachineAssemblerTester<int64_t>* m, int index) { switch (index) { case 0: @@ -136,7 +141,7 @@ TEST(CodeGenInt64Binop) { // TODO(titzer): add tests that run 64-bit integer operations. -#endif // V8_TURBOFAN_BACKEND_64 +#endif // V8_TARGET_ARCH_64_BIT TEST(RunGoto) { @@ -5274,5 +5279,3 @@ TEST(RunCallCFunction8) { } #endif // USE_SIMULATOR - -#endif // V8_TURBOFAN_TARGET diff --git a/deps/v8/test/cctest/compiler/test-run-native-calls.cc b/deps/v8/test/cctest/compiler/test-run-native-calls.cc new file mode 100644 index 0000000000..2e255c7729 --- /dev/null +++ b/deps/v8/test/cctest/compiler/test-run-native-calls.cc @@ -0,0 +1,985 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/assembler.h" +#include "src/codegen.h" +#include "src/compiler/linkage.h" +#include "src/compiler/machine-type.h" +#include "src/compiler/raw-machine-assembler.h" + +#include "test/cctest/cctest.h" +#include "test/cctest/compiler/codegen-tester.h" +#include "test/cctest/compiler/graph-builder-tester.h" +#include "test/cctest/compiler/value-helper.h" + +using namespace v8::base; +using namespace v8::internal; +using namespace v8::internal::compiler; + +typedef RawMachineAssembler::Label MLabel; + +#if V8_TARGET_ARCH_ARM64 +// TODO(titzer): fix native stack parameters on arm64 +#define DISABLE_NATIVE_STACK_PARAMS true +#else +#define DISABLE_NATIVE_STACK_PARAMS false +#endif + +namespace { +typedef float float32; +typedef double float64; + +// Picks a representative pair of integers from the given range. +// If there are less than {max_pairs} possible pairs, do them all, otherwise try +// to select a representative set. +class Pairs { + public: + Pairs(int max_pairs, int range) + : range_(range), + max_pairs_(std::min(max_pairs, range_ * range_)), + counter_(0) {} + + bool More() { return counter_ < max_pairs_; } + + void Next(int* r0, int* r1, bool same_is_ok) { + do { + // Find the next pair. + if (exhaustive()) { + *r0 = counter_ % range_; + *r1 = counter_ / range_; + } else { + // Try each integer at least once for both r0 and r1. + int index = counter_ / 2; + if (counter_ & 1) { + *r0 = index % range_; + *r1 = index / range_; + } else { + *r1 = index % range_; + *r0 = index / range_; + } + } + counter_++; + if (same_is_ok) break; + if (*r0 == *r1) { + if (counter_ >= max_pairs_) { + // For the last hurrah, reg#0 with reg#n-1 + *r0 = 0; + *r1 = range_ - 1; + break; + } + } + } while (true); + + DCHECK(*r0 >= 0 && *r0 < range_); + DCHECK(*r1 >= 0 && *r1 < range_); + } + + private: + int range_; + int max_pairs_; + int counter_; + bool exhaustive() { return max_pairs_ == (range_ * range_); } +}; + + +// Pairs of general purpose registers. +class RegisterPairs : public Pairs { + public: + RegisterPairs() : Pairs(100, Register::kMaxNumAllocatableRegisters) {} +}; + + +// Pairs of double registers. +class Float32RegisterPairs : public Pairs { + public: + Float32RegisterPairs() + : Pairs(100, DoubleRegister::NumAllocatableAliasedRegisters()) {} +}; + + +// Pairs of double registers. +class Float64RegisterPairs : public Pairs { + public: + Float64RegisterPairs() + : Pairs(100, DoubleRegister::NumAllocatableAliasedRegisters()) {} +}; + + +// Helper for allocating either an GP or FP reg, or the next stack slot. +struct Allocator { + Allocator(int* gp, int gpc, int* fp, int fpc) + : gp_count(gpc), + gp_offset(0), + gp_regs(gp), + fp_count(fpc), + fp_offset(0), + fp_regs(fp), + stack_offset(0) {} + + int gp_count; + int gp_offset; + int* gp_regs; + + int fp_count; + int fp_offset; + int* fp_regs; + + int stack_offset; + + LinkageLocation Next(MachineType type) { + if (IsFloatingPoint(type)) { + // Allocate a floating point register/stack location. + if (fp_offset < fp_count) { + return LinkageLocation::ForRegister(fp_regs[fp_offset++]); + } else { + int offset = -1 - stack_offset; + stack_offset += StackWords(type); + return LinkageLocation::ForCallerFrameSlot(offset); + } + } else { + // Allocate a general purpose register/stack location. + if (gp_offset < gp_count) { + return LinkageLocation::ForRegister(gp_regs[gp_offset++]); + } else { + int offset = -1 - stack_offset; + stack_offset += StackWords(type); + return LinkageLocation::ForCallerFrameSlot(offset); + } + } + } + bool IsFloatingPoint(MachineType type) { + return RepresentationOf(type) == kRepFloat32 || + RepresentationOf(type) == kRepFloat64; + } + int StackWords(MachineType type) { + // TODO(titzer): hack. float32 occupies 8 bytes on stack. + int size = (RepresentationOf(type) == kRepFloat32 || + RepresentationOf(type) == kRepFloat64) + ? kDoubleSize + : ElementSizeOf(type); + return size <= kPointerSize ? 1 : size / kPointerSize; + } + void Reset() { + fp_offset = 0; + gp_offset = 0; + stack_offset = 0; + } +}; + + +class RegisterConfig { + public: + RegisterConfig(Allocator& p, Allocator& r) : params(p), rets(r) {} + + CallDescriptor* Create(Zone* zone, MachineSignature* msig) { + rets.Reset(); + params.Reset(); + + LocationSignature::Builder locations(zone, msig->return_count(), + msig->parameter_count()); + // Add return location(s). + const int return_count = static_cast<int>(locations.return_count_); + for (int i = 0; i < return_count; i++) { + locations.AddReturn(rets.Next(msig->GetReturn(i))); + } + + // Add register and/or stack parameter(s). + const int parameter_count = static_cast<int>(msig->parameter_count()); + for (int i = 0; i < parameter_count; i++) { + locations.AddParam(params.Next(msig->GetParam(i))); + } + + const RegList kCalleeSaveRegisters = 0; + const RegList kCalleeSaveFPRegisters = 0; + + MachineType target_type = compiler::kMachAnyTagged; + LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); + int stack_param_count = params.stack_offset; + return new (zone) CallDescriptor( // -- + CallDescriptor::kCallCodeObject, // kind + target_type, // target MachineType + target_loc, // target location + msig, // machine_sig + locations.Build(), // location_sig + stack_param_count, // stack_parameter_count + compiler::Operator::kNoProperties, // properties + kCalleeSaveRegisters, // callee-saved registers + kCalleeSaveFPRegisters, // callee-saved fp regs + CallDescriptor::kNoFlags, // flags + "c-call"); + } + + private: + Allocator& params; + Allocator& rets; +}; + +const int kMaxParamCount = 64; + +MachineType kIntTypes[kMaxParamCount + 1] = { + kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, + kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, + kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, + kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, + kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, + kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, + kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, + kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, + kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, + kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, + kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32}; + + +// For making uniform int32 signatures shorter. +class Int32Signature : public MachineSignature { + public: + explicit Int32Signature(int param_count) + : MachineSignature(1, param_count, kIntTypes) { + CHECK(param_count <= kMaxParamCount); + } +}; + + +Handle<Code> CompileGraph(const char* name, CallDescriptor* desc, Graph* graph, + Schedule* schedule = nullptr) { + Isolate* isolate = CcTest::InitIsolateOnce(); + Handle<Code> code = + Pipeline::GenerateCodeForTesting(isolate, desc, graph, schedule); + CHECK(!code.is_null()); +#ifdef ENABLE_DISASSEMBLER + if (FLAG_print_opt_code) { + OFStream os(stdout); + code->Disassemble(name, os); + } +#endif + return code; +} + + +Handle<Code> WrapWithCFunction(Handle<Code> inner, CallDescriptor* desc) { + Zone zone; + MachineSignature* msig = + const_cast<MachineSignature*>(desc->GetMachineSignature()); + int param_count = static_cast<int>(msig->parameter_count()); + GraphAndBuilders caller(&zone); + { + GraphAndBuilders& b = caller; + Node* start = b.graph()->NewNode(b.common()->Start(param_count + 3)); + b.graph()->SetStart(start); + Unique<HeapObject> unique = Unique<HeapObject>::CreateUninitialized(inner); + Node* target = b.graph()->NewNode(b.common()->HeapConstant(unique)); + + // Add arguments to the call. + Node** args = zone.NewArray<Node*>(param_count + 3); + int index = 0; + args[index++] = target; + for (int i = 0; i < param_count; i++) { + args[index] = b.graph()->NewNode(b.common()->Parameter(i), start); + index++; + } + args[index++] = start; // effect. + args[index++] = start; // control. + + // Build the call and return nodes. + Node* call = + b.graph()->NewNode(b.common()->Call(desc), param_count + 3, args); + Node* ret = b.graph()->NewNode(b.common()->Return(), call, call, start); + b.graph()->SetEnd(ret); + } + + CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, msig); + + return CompileGraph("wrapper", cdesc, caller.graph()); +} + + +template <typename CType> +class ArgsBuffer { + public: + static const int kMaxParamCount = 64; + + explicit ArgsBuffer(int count, int seed = 1) : count_(count), seed_(seed) { + // initialize the buffer with "seed 0" + seed_ = 0; + Mutate(); + seed_ = seed; + } + + class Sig : public MachineSignature { + public: + explicit Sig(int param_count) + : MachineSignature(1, param_count, MachTypes()) { + CHECK(param_count <= kMaxParamCount); + } + }; + + static MachineType* MachTypes() { + MachineType t = MachineTypeForC<CType>(); + static MachineType kTypes[kMaxParamCount + 1] = { + t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, + t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, + t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t}; + return kTypes; + } + + Node* MakeConstant(RawMachineAssembler& raw, int32_t value) { + return raw.Int32Constant(value); + } + + Node* MakeConstant(RawMachineAssembler& raw, int64_t value) { + return raw.Int64Constant(value); + } + + Node* MakeConstant(RawMachineAssembler& raw, float32 value) { + return raw.Float32Constant(value); + } + + Node* MakeConstant(RawMachineAssembler& raw, float64 value) { + return raw.Float64Constant(value); + } + + Node* LoadInput(RawMachineAssembler& raw, Node* base, int index) { + Node* offset = raw.Int32Constant(index * sizeof(CType)); + return raw.Load(MachineTypeForC<CType>(), base, offset); + } + + Node* StoreOutput(RawMachineAssembler& raw, Node* value) { + Node* base = raw.PointerConstant(&output); + Node* offset = raw.Int32Constant(0); + return raw.Store(MachineTypeForC<CType>(), base, offset, value); + } + + // Computes the next set of inputs by updating the {input} array. + void Mutate(); + + void Reset() { memset(input, 0, sizeof(input)); } + + int count_; + int seed_; + CType input[kMaxParamCount]; + CType output; +}; + + +template <> +void ArgsBuffer<int32_t>::Mutate() { + uint32_t base = 1111111111u * seed_; + for (int j = 0; j < count_ && j < kMaxParamCount; j++) { + input[j] = static_cast<int32_t>(256 + base + j + seed_ * 13); + } + output = -1; + seed_++; +} + + +template <> +void ArgsBuffer<int64_t>::Mutate() { + uint64_t base = 11111111111111111ull * seed_; + for (int j = 0; j < count_ && j < kMaxParamCount; j++) { + input[j] = static_cast<int64_t>(256 + base + j + seed_ * 13); + } + output = -1; + seed_++; +} + + +template <> +void ArgsBuffer<float32>::Mutate() { + float64 base = -33.25 * seed_; + for (int j = 0; j < count_ && j < kMaxParamCount; j++) { + input[j] = 256 + base + j + seed_ * 13; + } + output = std::numeric_limits<float32>::quiet_NaN(); + seed_++; +} + + +template <> +void ArgsBuffer<float64>::Mutate() { + float64 base = -111.25 * seed_; + for (int j = 0; j < count_ && j < kMaxParamCount; j++) { + input[j] = 256 + base + j + seed_ * 13; + } + output = std::numeric_limits<float64>::quiet_NaN(); + seed_++; +} + + +int ParamCount(CallDescriptor* desc) { + return static_cast<int>(desc->GetMachineSignature()->parameter_count()); +} + + +template <typename CType> +class Computer { + public: + static void Run(CallDescriptor* desc, + void (*build)(CallDescriptor*, RawMachineAssembler&), + CType (*compute)(CallDescriptor*, CType* inputs), + int seed = 1) { + int num_params = ParamCount(desc); + CHECK_LE(num_params, kMaxParamCount); + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + Handle<Code> inner = Handle<Code>::null(); + { + // Build the graph for the computation. + Zone zone; + Graph graph(&zone); + RawMachineAssembler raw(isolate, &graph, desc); + build(desc, raw); + inner = CompileGraph("Compute", desc, &graph, raw.Export()); + } + + CSignature0<int32_t> csig; + ArgsBuffer<CType> io(num_params, seed); + + { + // constant mode. + Handle<Code> wrapper = Handle<Code>::null(); + { + // Wrap the above code with a callable function that passes constants. + Zone zone; + Graph graph(&zone); + CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); + RawMachineAssembler raw(isolate, &graph, cdesc); + Unique<HeapObject> unique = + Unique<HeapObject>::CreateUninitialized(inner); + Node* target = raw.HeapConstant(unique); + Node** args = zone.NewArray<Node*>(num_params); + for (int i = 0; i < num_params; i++) { + args[i] = io.MakeConstant(raw, io.input[i]); + } + + Node* call = raw.CallN(desc, target, args); + Node* store = io.StoreOutput(raw, call); + USE(store); + raw.Return(raw.Int32Constant(seed)); + wrapper = + CompileGraph("Compute-wrapper-const", cdesc, &graph, raw.Export()); + } + + CodeRunner<int32_t> runnable(isolate, wrapper, &csig); + + // Run the code, checking it against the reference. + CType expected = compute(desc, io.input); + int32_t check_seed = runnable.Call(); + CHECK_EQ(seed, check_seed); + CHECK_EQ(expected, io.output); + } + + { + // buffer mode. + Handle<Code> wrapper = Handle<Code>::null(); + { + // Wrap the above code with a callable function that loads from {input}. + Zone zone; + Graph graph(&zone); + CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); + RawMachineAssembler raw(isolate, &graph, cdesc); + Node* base = raw.PointerConstant(io.input); + Unique<HeapObject> unique = + Unique<HeapObject>::CreateUninitialized(inner); + Node* target = raw.HeapConstant(unique); + Node** args = zone.NewArray<Node*>(kMaxParamCount); + for (int i = 0; i < num_params; i++) { + args[i] = io.LoadInput(raw, base, i); + } + + Node* call = raw.CallN(desc, target, args); + Node* store = io.StoreOutput(raw, call); + USE(store); + raw.Return(raw.Int32Constant(seed)); + wrapper = CompileGraph("Compute-wrapper", cdesc, &graph, raw.Export()); + } + + CodeRunner<int32_t> runnable(isolate, wrapper, &csig); + + // Run the code, checking it against the reference. + for (int i = 0; i < 5; i++) { + CType expected = compute(desc, io.input); + int32_t check_seed = runnable.Call(); + CHECK_EQ(seed, check_seed); + CHECK_EQ(expected, io.output); + io.Mutate(); + } + } + } +}; + +} // namespace + + +static void TestInt32Sub(CallDescriptor* desc) { + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + Zone zone; + GraphAndBuilders inner(&zone); + { + // Build the add function. + GraphAndBuilders& b = inner; + Node* start = b.graph()->NewNode(b.common()->Start(5)); + b.graph()->SetStart(start); + Node* p0 = b.graph()->NewNode(b.common()->Parameter(0), start); + Node* p1 = b.graph()->NewNode(b.common()->Parameter(1), start); + Node* add = b.graph()->NewNode(b.machine()->Int32Sub(), p0, p1); + Node* ret = b.graph()->NewNode(b.common()->Return(), add, start, start); + b.graph()->SetEnd(ret); + } + + Handle<Code> inner_code = CompileGraph("Int32Sub", desc, inner.graph()); + Handle<Code> wrapper = WrapWithCFunction(inner_code, desc); + MachineSignature* msig = + const_cast<MachineSignature*>(desc->GetMachineSignature()); + CodeRunner<int32_t> runnable(isolate, wrapper, + CSignature::FromMachine(&zone, msig)); + + FOR_INT32_INPUTS(i) { + FOR_INT32_INPUTS(j) { + int32_t expected = static_cast<int32_t>(static_cast<uint32_t>(*i) - + static_cast<uint32_t>(*j)); + int32_t result = runnable.Call(*i, *j); + CHECK_EQ(expected, result); + } + } +} + + +static void CopyTwentyInt32(CallDescriptor* desc) { + if (DISABLE_NATIVE_STACK_PARAMS) return; + + const int kNumParams = 20; + int32_t input[kNumParams]; + int32_t output[kNumParams]; + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + Handle<Code> inner = Handle<Code>::null(); + { + // Writes all parameters into the output buffer. + Zone zone; + Graph graph(&zone); + RawMachineAssembler raw(isolate, &graph, desc); + Node* base = raw.PointerConstant(output); + for (int i = 0; i < kNumParams; i++) { + Node* offset = raw.Int32Constant(i * sizeof(int32_t)); + raw.Store(kMachInt32, base, offset, raw.Parameter(i)); + } + raw.Return(raw.Int32Constant(42)); + inner = CompileGraph("CopyTwentyInt32", desc, &graph, raw.Export()); + } + + CSignature0<int32_t> csig; + Handle<Code> wrapper = Handle<Code>::null(); + { + // Loads parameters from the input buffer and calls the above code. + Zone zone; + Graph graph(&zone); + CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig); + RawMachineAssembler raw(isolate, &graph, cdesc); + Node* base = raw.PointerConstant(input); + Unique<HeapObject> unique = Unique<HeapObject>::CreateUninitialized(inner); + Node* target = raw.HeapConstant(unique); + Node** args = zone.NewArray<Node*>(kNumParams); + for (int i = 0; i < kNumParams; i++) { + Node* offset = raw.Int32Constant(i * sizeof(int32_t)); + args[i] = raw.Load(kMachInt32, base, offset); + } + + Node* call = raw.CallN(desc, target, args); + raw.Return(call); + wrapper = + CompileGraph("CopyTwentyInt32-wrapper", cdesc, &graph, raw.Export()); + } + + CodeRunner<int32_t> runnable(isolate, wrapper, &csig); + + // Run the code, checking it correctly implements the memcpy. + for (int i = 0; i < 5; i++) { + uint32_t base = 1111111111u * i; + for (int j = 0; j < kNumParams; j++) { + input[j] = static_cast<int32_t>(base + 13 * j); + } + + memset(output, 0, sizeof(output)); + CHECK_EQ(42, runnable.Call()); + + for (int j = 0; j < kNumParams; j++) { + CHECK_EQ(input[j], output[j]); + } + } +} + + +static void Test_RunInt32SubWithRet(int retreg) { + Int32Signature sig(2); + Zone zone; + RegisterPairs pairs; + while (pairs.More()) { + int parray[2]; + int rarray[] = {retreg}; + pairs.Next(&parray[0], &parray[1], false); + Allocator params(parray, 2, nullptr, 0); + Allocator rets(rarray, 1, nullptr, 0); + RegisterConfig config(params, rets); + CallDescriptor* desc = config.Create(&zone, &sig); + TestInt32Sub(desc); + } +} + + +// Separate tests for parallelization. +#define TEST_INT32_SUB_WITH_RET(x) \ + TEST(Run_Int32Sub_all_allocatable_pairs_##x) { \ + if (Register::kMaxNumAllocatableRegisters > x) Test_RunInt32SubWithRet(x); \ + } + + +TEST_INT32_SUB_WITH_RET(0) +TEST_INT32_SUB_WITH_RET(1) +TEST_INT32_SUB_WITH_RET(2) +TEST_INT32_SUB_WITH_RET(3) +TEST_INT32_SUB_WITH_RET(4) +TEST_INT32_SUB_WITH_RET(5) +TEST_INT32_SUB_WITH_RET(6) +TEST_INT32_SUB_WITH_RET(7) +TEST_INT32_SUB_WITH_RET(8) +TEST_INT32_SUB_WITH_RET(9) +TEST_INT32_SUB_WITH_RET(10) +TEST_INT32_SUB_WITH_RET(11) +TEST_INT32_SUB_WITH_RET(12) +TEST_INT32_SUB_WITH_RET(13) +TEST_INT32_SUB_WITH_RET(14) +TEST_INT32_SUB_WITH_RET(15) +TEST_INT32_SUB_WITH_RET(16) +TEST_INT32_SUB_WITH_RET(17) +TEST_INT32_SUB_WITH_RET(18) +TEST_INT32_SUB_WITH_RET(19) + + +TEST(Run_Int32Sub_all_allocatable_single) { + if (DISABLE_NATIVE_STACK_PARAMS) return; + Int32Signature sig(2); + RegisterPairs pairs; + while (pairs.More()) { + Zone zone; + int parray[1]; + int rarray[1]; + pairs.Next(&rarray[0], &parray[0], true); + Allocator params(parray, 1, nullptr, 0); + Allocator rets(rarray, 1, nullptr, 0); + RegisterConfig config(params, rets); + CallDescriptor* desc = config.Create(&zone, &sig); + TestInt32Sub(desc); + } +} + + +TEST(Run_CopyTwentyInt32_all_allocatable_pairs) { + if (DISABLE_NATIVE_STACK_PARAMS) return; + Int32Signature sig(20); + RegisterPairs pairs; + while (pairs.More()) { + Zone zone; + int parray[2]; + int rarray[] = {0}; + pairs.Next(&parray[0], &parray[1], false); + Allocator params(parray, 2, nullptr, 0); + Allocator rets(rarray, 1, nullptr, 0); + RegisterConfig config(params, rets); + CallDescriptor* desc = config.Create(&zone, &sig); + CopyTwentyInt32(desc); + } +} + + +template <typename CType> +static void Run_Computation( + CallDescriptor* desc, void (*build)(CallDescriptor*, RawMachineAssembler&), + CType (*compute)(CallDescriptor*, CType* inputs), int seed = 1) { + Computer<CType>::Run(desc, build, compute, seed); +} + + +static uint32_t coeff[] = {1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, + 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, + 79, 83, 89, 97, 101, 103, 107, 109, 113}; + + +static void Build_Int32_WeightedSum(CallDescriptor* desc, + RawMachineAssembler& raw) { + Node* result = raw.Int32Constant(0); + for (int i = 0; i < ParamCount(desc); i++) { + Node* term = raw.Int32Mul(raw.Parameter(i), raw.Int32Constant(coeff[i])); + result = raw.Int32Add(result, term); + } + raw.Return(result); +} + + +static int32_t Compute_Int32_WeightedSum(CallDescriptor* desc, int32_t* input) { + uint32_t result = 0; + for (int i = 0; i < ParamCount(desc); i++) { + result += static_cast<uint32_t>(input[i]) * coeff[i]; + } + return static_cast<int32_t>(result); +} + + +static void Test_Int32_WeightedSum_of_size(int count) { + if (DISABLE_NATIVE_STACK_PARAMS) return; + Int32Signature sig(count); + for (int p0 = 0; p0 < Register::kMaxNumAllocatableRegisters; p0++) { + Zone zone; + + int parray[] = {p0}; + int rarray[] = {0}; + Allocator params(parray, 1, nullptr, 0); + Allocator rets(rarray, 1, nullptr, 0); + RegisterConfig config(params, rets); + CallDescriptor* desc = config.Create(&zone, &sig); + Run_Computation<int32_t>(desc, Build_Int32_WeightedSum, + Compute_Int32_WeightedSum, 257 + count); + } +} + + +// Separate tests for parallelization. +#define TEST_INT32_WEIGHTEDSUM(x) \ + TEST(Run_Int32_WeightedSum_##x) { Test_Int32_WeightedSum_of_size(x); } + + +TEST_INT32_WEIGHTEDSUM(1) +TEST_INT32_WEIGHTEDSUM(2) +TEST_INT32_WEIGHTEDSUM(3) +TEST_INT32_WEIGHTEDSUM(4) +TEST_INT32_WEIGHTEDSUM(5) +TEST_INT32_WEIGHTEDSUM(7) +TEST_INT32_WEIGHTEDSUM(9) +TEST_INT32_WEIGHTEDSUM(11) +TEST_INT32_WEIGHTEDSUM(17) +TEST_INT32_WEIGHTEDSUM(19) + + +template <int which> +static void Build_Select(CallDescriptor* desc, RawMachineAssembler& raw) { + raw.Return(raw.Parameter(which)); +} + + +template <typename CType, int which> +static CType Compute_Select(CallDescriptor* desc, CType* inputs) { + return inputs[which]; +} + + +template <typename CType, int which> +static void RunSelect(CallDescriptor* desc) { + int count = ParamCount(desc); + if (count <= which) return; + Run_Computation<CType>(desc, Build_Select<which>, + Compute_Select<CType, which>, + 1044 + which + 3 * sizeof(CType)); +} + + +template <int which> +void Test_Int32_Select() { + if (DISABLE_NATIVE_STACK_PARAMS) return; + + int parray[] = {0}; + int rarray[] = {0}; + Allocator params(parray, 1, nullptr, 0); + Allocator rets(rarray, 1, nullptr, 0); + RegisterConfig config(params, rets); + + Zone zone; + + for (int i = which + 1; i <= 64; i++) { + Int32Signature sig(i); + CallDescriptor* desc = config.Create(&zone, &sig); + RunSelect<int32_t, which>(desc); + } +} + + +// Separate tests for parallelization. +#define TEST_INT32_SELECT(x) \ + TEST(Run_Int32_Select_##x) { Test_Int32_Select<x>(); } + + +TEST_INT32_SELECT(0) +TEST_INT32_SELECT(1) +TEST_INT32_SELECT(2) +TEST_INT32_SELECT(3) +TEST_INT32_SELECT(4) +TEST_INT32_SELECT(5) +TEST_INT32_SELECT(6) +TEST_INT32_SELECT(11) +TEST_INT32_SELECT(15) +TEST_INT32_SELECT(19) +TEST_INT32_SELECT(45) +TEST_INT32_SELECT(62) +TEST_INT32_SELECT(63) + + +TEST(Int64Select_registers) { + if (Register::kMaxNumAllocatableRegisters < 2) return; + if (kPointerSize < 8) return; // TODO(titzer): int64 on 32-bit platforms + + int rarray[] = {0}; + ArgsBuffer<int64_t>::Sig sig(2); + + RegisterPairs pairs; + Zone zone; + while (pairs.More()) { + int parray[2]; + pairs.Next(&parray[0], &parray[1], false); + Allocator params(parray, 2, nullptr, 0); + Allocator rets(rarray, 1, nullptr, 0); + RegisterConfig config(params, rets); + + CallDescriptor* desc = config.Create(&zone, &sig); + RunSelect<int64_t, 0>(desc); + RunSelect<int64_t, 1>(desc); + } +} + + +TEST(Float32Select_registers) { + if (RegisterConfiguration::ArchDefault()->num_double_registers() < 2) return; + + int rarray[] = {0}; + ArgsBuffer<float32>::Sig sig(2); + + Float32RegisterPairs pairs; + Zone zone; + while (pairs.More()) { + int parray[2]; + pairs.Next(&parray[0], &parray[1], false); + Allocator params(nullptr, 0, parray, 2); + Allocator rets(nullptr, 0, rarray, 1); + RegisterConfig config(params, rets); + + CallDescriptor* desc = config.Create(&zone, &sig); + RunSelect<float32, 0>(desc); + RunSelect<float32, 1>(desc); + } +} + + +TEST(Float64Select_registers) { + if (RegisterConfiguration::ArchDefault()->num_double_registers() < 2) return; + + int rarray[] = {0}; + ArgsBuffer<float64>::Sig sig(2); + + Float64RegisterPairs pairs; + Zone zone; + while (pairs.More()) { + int parray[2]; + pairs.Next(&parray[0], &parray[1], false); + Allocator params(nullptr, 0, parray, 2); + Allocator rets(nullptr, 0, rarray, 1); + RegisterConfig config(params, rets); + + CallDescriptor* desc = config.Create(&zone, &sig); + RunSelect<float64, 0>(desc); + RunSelect<float64, 1>(desc); + } +} + + +TEST(Float32Select_stack_params_return_reg) { + if (DISABLE_NATIVE_STACK_PARAMS) return; + int rarray[] = {0}; + Allocator params(nullptr, 0, nullptr, 0); + Allocator rets(nullptr, 0, rarray, 1); + RegisterConfig config(params, rets); + + Zone zone; + for (int count = 1; count < 6; count++) { + ArgsBuffer<float32>::Sig sig(count); + CallDescriptor* desc = config.Create(&zone, &sig); + RunSelect<float32, 0>(desc); + RunSelect<float32, 1>(desc); + RunSelect<float32, 2>(desc); + RunSelect<float32, 3>(desc); + RunSelect<float32, 4>(desc); + RunSelect<float32, 5>(desc); + } +} + + +TEST(Float64Select_stack_params_return_reg) { + if (DISABLE_NATIVE_STACK_PARAMS) return; + int rarray[] = {0}; + Allocator params(nullptr, 0, nullptr, 0); + Allocator rets(nullptr, 0, rarray, 1); + RegisterConfig config(params, rets); + + Zone zone; + for (int count = 1; count < 6; count++) { + ArgsBuffer<float64>::Sig sig(count); + CallDescriptor* desc = config.Create(&zone, &sig); + RunSelect<float64, 0>(desc); + RunSelect<float64, 1>(desc); + RunSelect<float64, 2>(desc); + RunSelect<float64, 3>(desc); + RunSelect<float64, 4>(desc); + RunSelect<float64, 5>(desc); + } +} + + +template <typename CType, int which> +static void Build_Select_With_Call(CallDescriptor* desc, + RawMachineAssembler& raw) { + Handle<Code> inner = Handle<Code>::null(); + int num_params = ParamCount(desc); + CHECK_LE(num_params, kMaxParamCount); + { + Isolate* isolate = CcTest::InitIsolateOnce(); + // Build the actual select. + Zone zone; + Graph graph(&zone); + RawMachineAssembler raw(isolate, &graph, desc); + raw.Return(raw.Parameter(which)); + inner = CompileGraph("Select-indirection", desc, &graph, raw.Export()); + CHECK(!inner.is_null()); + CHECK(inner->IsCode()); + } + + { + // Build a call to the function that does the select. + Unique<HeapObject> unique = Unique<HeapObject>::CreateUninitialized(inner); + Node* target = raw.HeapConstant(unique); + Node** args = raw.zone()->NewArray<Node*>(num_params); + for (int i = 0; i < num_params; i++) { + args[i] = raw.Parameter(i); + } + + Node* call = raw.CallN(desc, target, args); + raw.Return(call); + } +} + + +TEST(Float64StackParamsToStackParams) { + if (DISABLE_NATIVE_STACK_PARAMS) return; + + int rarray[] = {0}; + Allocator params(nullptr, 0, nullptr, 0); + Allocator rets(nullptr, 0, rarray, 1); + + Zone zone; + ArgsBuffer<float64>::Sig sig(2); + RegisterConfig config(params, rets); + CallDescriptor* desc = config.Create(&zone, &sig); + + Run_Computation<float64>(desc, Build_Select_With_Call<float64, 0>, + Compute_Select<float64, 0>, 1098); + + Run_Computation<float64>(desc, Build_Select_With_Call<float64, 1>, + Compute_Select<float64, 1>, 1099); +} diff --git a/deps/v8/test/cctest/compiler/test-run-properties.cc b/deps/v8/test/cctest/compiler/test-run-properties.cc index d4442f7a85..b7677f7fd2 100644 --- a/deps/v8/test/cctest/compiler/test-run-properties.cc +++ b/deps/v8/test/cctest/compiler/test-run-properties.cc @@ -21,16 +21,15 @@ static void TypedArrayLoadHelper(const char* array_type) { values_builder.AddFormatted("a[%d] = 0x%08x;", i, kValues[i]); } - // Note that below source creates two different typed arrays with distinct - // elements kind to get coverage for both access patterns: - // - IsFixedTypedArrayElementsKind(x) - // - IsExternalArrayElementsKind(y) + // Note that below source creates two different typed arrays with the same + // elements kind to get coverage for both (on heap / with external backing + // store) access patterns. const char* source = "(function(a) {" " var x = (a = new %sArray(%d)); %s;" " var y = (a = new %sArray(%d)); %s; %%TypedArrayGetBuffer(y);" " if (!%%HasFixed%sElements(x)) %%AbortJS('x');" - " if (!%%HasExternal%sElements(y)) %%AbortJS('y');" + " if (!%%HasFixed%sElements(y)) %%AbortJS('y');" " function f(a,b) {" " a = a | 0; b = b | 0;" " return x[a] + y[b];" @@ -84,16 +83,15 @@ static void TypedArrayStoreHelper(const char* array_type) { values_builder.AddFormatted("a[%d] = 0x%08x;", i, kValues[i]); } - // Note that below source creates two different typed arrays with distinct - // elements kind to get coverage for both access patterns: - // - IsFixedTypedArrayElementsKind(x) - // - IsExternalArrayElementsKind(y) + // Note that below source creates two different typed arrays with the same + // elements kind to get coverage for both (on heap/with external backing + // store) access patterns. const char* source = "(function(a) {" " var x = (a = new %sArray(%d)); %s;" " var y = (a = new %sArray(%d)); %s; %%TypedArrayGetBuffer(y);" " if (!%%HasFixed%sElements(x)) %%AbortJS('x');" - " if (!%%HasExternal%sElements(y)) %%AbortJS('y');" + " if (!%%HasFixed%sElements(y)) %%AbortJS('y');" " function f(a,b) {" " a = a | 0; b = b | 0;" " var t = x[a];" diff --git a/deps/v8/test/cctest/compiler/test-run-stubs.cc b/deps/v8/test/cctest/compiler/test-run-stubs.cc index 9c7998d7af..607efa135b 100644 --- a/deps/v8/test/cctest/compiler/test-run-stubs.cc +++ b/deps/v8/test/cctest/compiler/test-run-stubs.cc @@ -14,23 +14,21 @@ #include "src/parser.h" #include "test/cctest/compiler/function-tester.h" -#if V8_TURBOFAN_TARGET - using namespace v8::internal; using namespace v8::internal::compiler; -TEST(RunMathFloorStub) { +TEST(RunOptimizedMathFloorStub) { HandleAndZoneScope scope; Isolate* isolate = scope.main_isolate(); // Create code and an accompanying descriptor. - MathFloorStub stub(isolate); + MathFloorStub stub(isolate, TurboFanIC::CALL_FROM_OPTIMIZED_CODE); Handle<Code> code = stub.GenerateCode(); Zone* zone = scope.main_zone(); - CompilationInfo info(&stub, isolate, zone); CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info); + Handle<FixedArray> tv = isolate->factory()->NewFixedArray(10); // Create a function to call the code using the descriptor. Graph graph(zone); @@ -45,10 +43,13 @@ TEST(RunMathFloorStub) { Node* numberParam = graph.NewNode(common.Parameter(1), start); Unique<HeapObject> u = Unique<HeapObject>::CreateImmovable(code); Node* theCode = graph.NewNode(common.HeapConstant(u)); + Unique<HeapObject> tvu = Unique<HeapObject>::CreateImmovable(tv); + Node* vector = graph.NewNode(common.HeapConstant(tvu)); Node* dummyContext = graph.NewNode(common.NumberConstant(0.0)); - Node* call = graph.NewNode(common.Call(descriptor), theCode, - js.UndefinedConstant(), js.UndefinedConstant(), - numberParam, dummyContext, start, start); + Node* call = + graph.NewNode(common.Call(descriptor), theCode, js.UndefinedConstant(), + js.OneConstant(), vector, js.UndefinedConstant(), + numberParam, dummyContext, start, start); Node* ret = graph.NewNode(common.Return(), call, call, start); Node* end = graph.NewNode(common.End(1), ret); graph.SetStart(start); @@ -143,5 +144,3 @@ TEST(RunStringAddTFStub) { Handle<Object> result = ft.Call(leftArg, rightArg).ToHandleChecked(); CHECK(String::Equals(ft.Val("linksrechts"), Handle<String>::cast(result))); } - -#endif // V8_TURBOFAN_TARGET diff --git a/deps/v8/test/cctest/compiler/test-simplified-lowering.cc b/deps/v8/test/cctest/compiler/test-simplified-lowering.cc index 022e01690b..2a642c1589 100644 --- a/deps/v8/test/cctest/compiler/test-simplified-lowering.cc +++ b/deps/v8/test/cctest/compiler/test-simplified-lowering.cc @@ -110,14 +110,12 @@ TEST(RunNumberToInt32_float64) { t.LowerAllNodes(); t.GenerateCode(); - if (Pipeline::SupportedTarget()) { FOR_FLOAT64_INPUTS(i) { input = *i; int32_t expected = DoubleToInt32(*i); t.Call(); CHECK_EQ(expected, result); } - } } @@ -139,7 +137,6 @@ TEST(RunNumberToUint32_float64) { t.LowerAllNodes(); t.GenerateCode(); - if (Pipeline::SupportedTarget()) { FOR_FLOAT64_INPUTS(i) { input = *i; uint32_t expected = DoubleToUint32(*i); @@ -147,7 +144,6 @@ TEST(RunNumberToUint32_float64) { CHECK_EQ(static_cast<int32_t>(expected), static_cast<int32_t>(result)); } } -} // Create a simple JSObject with a unique map. @@ -168,12 +164,10 @@ TEST(RunLoadMap) { t.LowerAllNodes(); t.GenerateCode(); - if (Pipeline::SupportedTarget()) { - Handle<JSObject> src = TestObject(); - Handle<Map> src_map(src->map()); - Object* result = t.Call(*src); // TODO(titzer): raw pointers in call - CHECK_EQ(*src_map, result); - } + Handle<JSObject> src = TestObject(); + Handle<Map> src_map(src->map()); + Object* result = t.Call(*src); // TODO(titzer): raw pointers in call + CHECK_EQ(*src_map, result); } @@ -186,7 +180,6 @@ TEST(RunStoreMap) { t.LowerAllNodes(); t.GenerateCode(); - if (Pipeline::SupportedTarget()) { Handle<JSObject> src = TestObject(); Handle<Map> src_map(src->map()); Handle<JSObject> dst = TestObject(); @@ -194,7 +187,6 @@ TEST(RunStoreMap) { t.Call(*src_map, *dst); // TODO(titzer): raw pointers in call CHECK(*src_map == dst->map()); } -} TEST(RunLoadProperties) { @@ -206,12 +198,10 @@ TEST(RunLoadProperties) { t.LowerAllNodes(); t.GenerateCode(); - if (Pipeline::SupportedTarget()) { Handle<JSObject> src = TestObject(); Handle<FixedArray> src_props(src->properties()); Object* result = t.Call(*src); // TODO(titzer): raw pointers in call CHECK_EQ(*src_props, result); - } } @@ -225,7 +215,6 @@ TEST(RunLoadStoreMap) { t.LowerAllNodes(); t.GenerateCode(); - if (Pipeline::SupportedTarget()) { Handle<JSObject> src = TestObject(); Handle<Map> src_map(src->map()); Handle<JSObject> dst = TestObject(); @@ -234,7 +223,6 @@ TEST(RunLoadStoreMap) { CHECK(result->IsMap()); CHECK_EQ(*src_map, result); CHECK(*src_map == dst->map()); - } } @@ -248,7 +236,6 @@ TEST(RunLoadStoreFixedArrayIndex) { t.LowerAllNodes(); t.GenerateCode(); - if (Pipeline::SupportedTarget()) { Handle<FixedArray> array = t.factory()->NewFixedArray(2); Handle<JSObject> src = TestObject(); Handle<JSObject> dst = TestObject(); @@ -258,7 +245,6 @@ TEST(RunLoadStoreFixedArrayIndex) { CHECK_EQ(*src, result); CHECK_EQ(*src, array->get(0)); CHECK_EQ(*src, array->get(1)); - } } @@ -279,7 +265,6 @@ TEST(RunLoadStoreArrayBuffer) { t.LowerAllNodes(); t.GenerateCode(); - if (Pipeline::SupportedTarget()) { Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer(); Runtime::SetupArrayBufferAllocatingData(t.isolate(), array, array_length); uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store()); @@ -296,7 +281,6 @@ TEST(RunLoadStoreArrayBuffer) { CHECK_EQ(data[i], expected); } } -} TEST(RunLoadFieldFromUntaggedBase) { @@ -312,8 +296,6 @@ TEST(RunLoadFieldFromUntaggedBase) { t.Return(load); t.LowerAllNodes(); - if (!Pipeline::SupportedTarget()) continue; - for (int j = -5; j <= 5; j++) { Smi* expected = Smi::FromInt(j); smis[i] = expected; @@ -337,8 +319,6 @@ TEST(RunStoreFieldToUntaggedBase) { t.Return(p0); t.LowerAllNodes(); - if (!Pipeline::SupportedTarget()) continue; - for (int j = -5; j <= 5; j++) { Smi* expected = Smi::FromInt(j); smis[i] = Smi::FromInt(-100); @@ -365,8 +345,6 @@ TEST(RunLoadElementFromUntaggedBase) { t.Return(load); t.LowerAllNodes(); - if (!Pipeline::SupportedTarget()) continue; - for (int k = -5; k <= 5; k++) { Smi* expected = Smi::FromInt(k); smis[i + j] = expected; @@ -394,8 +372,6 @@ TEST(RunStoreElementFromUntaggedBase) { t.Return(p0); t.LowerAllNodes(); - if (!Pipeline::SupportedTarget()) continue; - for (int k = -5; k <= 5; k++) { Smi* expected = Smi::FromInt(k); smis[i + j] = Smi::FromInt(-100); @@ -462,10 +438,8 @@ class AccessTester : public HandleAndZoneScope { t.LowerAllNodes(); t.GenerateCode(); - if (Pipeline::SupportedTarget()) { Object* result = t.Call(); CHECK_EQ(t.isolate()->heap()->true_value(), result); - } } // Create and run code that copies the field in either {untagged_array} @@ -484,10 +458,8 @@ class AccessTester : public HandleAndZoneScope { t.LowerAllNodes(); t.GenerateCode(); - if (Pipeline::SupportedTarget()) { Object* result = t.Call(); CHECK_EQ(t.isolate()->heap()->true_value(), result); - } } // Create and run code that copies the elements from {this} to {that}. @@ -525,10 +497,8 @@ class AccessTester : public HandleAndZoneScope { t.LowerAllNodes(); t.GenerateCode(); - if (Pipeline::SupportedTarget()) { Object* result = t.Call(); CHECK_EQ(t.isolate()->heap()->true_value(), result); - } #endif } @@ -596,13 +566,11 @@ static void RunAccessTest(MachineType rep, E* original_elements, size_t num) { } else { a.RunCopyElement(i, i + 1); // Test element read/write. } - if (Pipeline::SupportedTarget()) { // verify. for (int j = 0; j < num_elements; j++) { E expect = j == (i + 1) ? original_elements[i] : original_elements[j]; CHECK_EQ(expect, a.GetElement(j)); } - } } } } @@ -612,10 +580,8 @@ static void RunAccessTest(MachineType rep, E* original_elements, size_t num) { AccessTester<E> a(tf == 1, rep, original_elements, num); AccessTester<E> b(tt == 1, rep, original_elements, num); a.RunCopyElements(&b); - if (Pipeline::SupportedTarget()) { // verify. for (int i = 0; i < num_elements; i++) { CHECK_EQ(a.GetElement(i), b.GetElement(i)); - } } } } @@ -668,7 +634,7 @@ TEST(RunAccessTests_Smi) { RunAccessTest<Smi*>(kMachAnyTagged, data, arraysize(data)); } -#if V8_TURBOFAN_TARGET + TEST(RunAllocate) { PretenureFlag flag[] = {NOT_TENURED, TENURED}; @@ -684,15 +650,13 @@ TEST(RunAllocate) { t.LowerAllNodes(); t.GenerateCode(); - if (Pipeline::SupportedTarget()) { HeapObject* result = t.CallWithPotentialGC<HeapObject>(); CHECK(t.heap()->new_space()->Contains(result) || flag[i] == TENURED); CHECK(t.heap()->old_space()->Contains(result) || flag[i] == NOT_TENURED); CHECK(result->IsHeapNumber()); - } } } -#endif + // Fills in most of the nodes of the graph in order to make tests shorter. class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { @@ -1264,7 +1228,6 @@ TEST(LowerReferenceEqual_to_wordeq) { TEST(LowerStringOps_to_call_and_compare) { - if (Pipeline::SupportedTarget()) { // These tests need linkage for the calls. TestingGraph t(Type::String(), Type::String()); IrOpcode::Value compare_eq = @@ -1277,7 +1240,6 @@ TEST(LowerStringOps_to_call_and_compare) { t.CheckLoweringBinop(compare_lt, t.simplified()->StringLessThan()); t.CheckLoweringBinop(compare_le, t.simplified()->StringLessThanOrEqual()); } -} void CheckChangeInsertion(IrOpcode::Value expected, MachineType from, @@ -1708,7 +1670,6 @@ TEST(RunNumberDivide_minus_1_TruncatingToInt32) { Node* trunc = t.NumberToInt32(div); t.Return(trunc); - if (Pipeline::SupportedTarget()) { t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); @@ -1716,7 +1677,6 @@ TEST(RunNumberDivide_minus_1_TruncatingToInt32) { int32_t x = 0 - *i; t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); } - } } @@ -1747,7 +1707,6 @@ TEST(RunNumberMultiply_TruncatingToInt32) { Node* trunc = t.NumberToInt32(mul); t.Return(trunc); - if (Pipeline::SupportedTarget()) { t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); @@ -1756,7 +1715,6 @@ TEST(RunNumberMultiply_TruncatingToInt32) { t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); } } - } } @@ -1771,14 +1729,12 @@ TEST(RunNumberMultiply_TruncatingToUint32) { Node* trunc = t.NumberToUint32(mul); t.Return(trunc); - if (Pipeline::SupportedTarget()) { t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); FOR_UINT32_INPUTS(i) { uint32_t x = DoubleToUint32(static_cast<double>(*i) * k); t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); - } } } } @@ -1791,7 +1747,6 @@ TEST(RunNumberDivide_2_TruncatingToUint32) { Node* trunc = t.NumberToUint32(div); t.Return(trunc); - if (Pipeline::SupportedTarget()) { t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); @@ -1799,7 +1754,6 @@ TEST(RunNumberDivide_2_TruncatingToUint32) { uint32_t x = DoubleToUint32(static_cast<double>(*i / 2.0)); t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); } - } } @@ -1853,7 +1807,6 @@ TEST(RunNumberDivide_TruncatingToInt32) { Node* trunc = t.NumberToInt32(div); t.Return(trunc); - if (Pipeline::SupportedTarget()) { t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); @@ -1861,7 +1814,6 @@ TEST(RunNumberDivide_TruncatingToInt32) { if (*i == INT_MAX) continue; // exclude max int. int32_t x = DoubleToInt32(static_cast<double>(*i) / k); t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); - } } } } @@ -1894,14 +1846,12 @@ TEST(RunNumberDivide_TruncatingToUint32) { Node* trunc = t.NumberToUint32(div); t.Return(trunc); - if (Pipeline::SupportedTarget()) { t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); FOR_UINT32_INPUTS(i) { uint32_t x = *i / k; t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); - } } } } @@ -1972,7 +1922,6 @@ TEST(RunNumberModulus_TruncatingToInt32) { Node* trunc = t.NumberToInt32(mod); t.Return(trunc); - if (Pipeline::SupportedTarget()) { t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); @@ -1980,7 +1929,6 @@ TEST(RunNumberModulus_TruncatingToInt32) { if (*i == INT_MAX) continue; // exclude max int. int32_t x = DoubleToInt32(std::fmod(static_cast<double>(*i), k)); t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); - } } } } @@ -2014,14 +1962,12 @@ TEST(RunNumberModulus_TruncatingToUint32) { Node* trunc = t.NumberToUint32(mod); t.Return(trunc); - if (Pipeline::SupportedTarget()) { t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); FOR_UINT32_INPUTS(i) { uint32_t x = *i % k; t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); - } } } } diff --git a/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc b/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc new file mode 100644 index 0000000000..deb6c971a1 --- /dev/null +++ b/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc @@ -0,0 +1,129 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/v8.h" + +#include "src/compiler.h" +#include "src/interpreter/bytecode-generator.h" +#include "src/interpreter/interpreter.h" +#include "test/cctest/cctest.h" + +namespace v8 { +namespace internal { +namespace interpreter { + +class BytecodeGeneratorHelper { + public: + const char* kFunctionName = "my_function"; + + BytecodeGeneratorHelper() { + i::FLAG_ignition = true; + i::FLAG_ignition_filter = kFunctionName; + CcTest::i_isolate()->interpreter()->Initialize(); + } + + + Handle<BytecodeArray> MakeBytecode(const char* script, + const char* function_name) { + CompileRun(script); + Local<Function> function = + Local<Function>::Cast(CcTest::global()->Get(v8_str(function_name))); + i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*function); + return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); + } + + + Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) { + ScopedVector<char> program(1024); + SNPrintF(program, "function %s() { %s }\n%s();", kFunctionName, body, + kFunctionName); + return MakeBytecode(program.start(), kFunctionName); + } +}; + + +// Structure for containing expected bytecode snippets. +struct ExpectedSnippet { + const char* body; + int frame_size; + int bytecode_length; + const uint8_t bytecode[16]; +}; + + +// Helper macros for handcrafting bytecode sequences. +#define B(x) static_cast<uint8_t>(Bytecode::k##x) +#define U8(x) static_cast<uint8_t>(x & 0xff) +#define R(x) static_cast<uint8_t>(-x & 0xff) + + +TEST(PrimitiveReturnStatements) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + + ExpectedSnippet snippets[] = { + {"return;", 0, 2, {B(LdaUndefined), B(Return)}}, + {"return null;", 0, 2, {B(LdaNull), B(Return)}}, + {"return true;", 0, 2, {B(LdaTrue), B(Return)}}, + {"return false;", 0, 2, {B(LdaFalse), B(Return)}}, + {"return 0;", 0, 2, {B(LdaZero), B(Return)}}, + {"return +1;", 0, 3, {B(LdaSmi8), U8(1), B(Return)}}, + {"return -1;", 0, 3, {B(LdaSmi8), U8(-1), B(Return)}}, + {"return +127;", 0, 3, {B(LdaSmi8), U8(127), B(Return)}}, + {"return -128;", 0, 3, {B(LdaSmi8), U8(-128), B(Return)}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + Handle<BytecodeArray> ba = + helper.MakeBytecodeForFunctionBody(snippets[i].body); + CHECK_EQ(ba->frame_size(), snippets[i].frame_size); + CHECK_EQ(ba->length(), snippets[i].bytecode_length); + CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode, + ba->length())); + } +} + + +TEST(PrimitiveExpressions) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + + ExpectedSnippet snippets[] = { + {"var x = 0; return x;", + kPointerSize, + 6, + { + B(LdaZero), // + B(Star), R(0), // + B(Ldar), R(0), // + B(Return) // + }}, + {"var x = 0; return x + 3;", + 2 * kPointerSize, + 12, + { + B(LdaZero), // + B(Star), R(0), // + B(Ldar), R(0), // Easy to spot r1 not really needed here. + B(Star), R(1), // Dead store. + B(LdaSmi8), U8(3), // + B(Add), R(1), // + B(Return) // + }}}; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + Handle<BytecodeArray> ba = + helper.MakeBytecodeForFunctionBody(snippets[i].body); + CHECK_EQ(ba->frame_size(), snippets[i].frame_size); + CHECK_EQ(ba->length(), snippets[i].bytecode_length); + CHECK(!memcmp(ba->GetFirstBytecodeAddress(), snippets[i].bytecode, + ba->length())); + } +} + +} // namespace interpreter +} // namespace internal +} // namespance v8 diff --git a/deps/v8/test/cctest/interpreter/test-interpreter.cc b/deps/v8/test/cctest/interpreter/test-interpreter.cc new file mode 100644 index 0000000000..2302fdc9ac --- /dev/null +++ b/deps/v8/test/cctest/interpreter/test-interpreter.cc @@ -0,0 +1,208 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/v8.h" + +#include "src/execution.h" +#include "src/handles.h" +#include "src/interpreter/bytecode-array-builder.h" +#include "src/interpreter/interpreter.h" +#include "test/cctest/cctest.h" + +namespace v8 { +namespace internal { +namespace interpreter { + +class InterpreterCallable { + public: + InterpreterCallable(Isolate* isolate, Handle<JSFunction> function) + : isolate_(isolate), function_(function) {} + virtual ~InterpreterCallable() {} + + MaybeHandle<Object> operator()() { + return Execution::Call(isolate_, function_, + isolate_->factory()->undefined_value(), 0, nullptr, + false); + } + + private: + Isolate* isolate_; + Handle<JSFunction> function_; +}; + +class InterpreterTester { + public: + InterpreterTester(Isolate* isolate, Handle<BytecodeArray> bytecode) + : isolate_(isolate), function_(GetBytecodeFunction(isolate, bytecode)) { + i::FLAG_ignition = true; + // Ensure handler table is generated. + isolate->interpreter()->Initialize(); + } + virtual ~InterpreterTester() {} + + InterpreterCallable GetCallable() { + return InterpreterCallable(isolate_, function_); + } + + private: + Isolate* isolate_; + Handle<JSFunction> function_; + + static Handle<JSFunction> GetBytecodeFunction( + Isolate* isolate, Handle<BytecodeArray> bytecode_array) { + Handle<JSFunction> function = v8::Utils::OpenHandle( + *v8::Handle<v8::Function>::Cast(CompileRun("(function(){})"))); + function->ReplaceCode(*isolate->builtins()->InterpreterEntryTrampoline()); + function->shared()->set_function_data(*bytecode_array); + return function; + } + + DISALLOW_COPY_AND_ASSIGN(InterpreterTester); +}; + +} // namespace interpreter +} // namespace internal +} // namespace v8 + +using v8::internal::BytecodeArray; +using v8::internal::Handle; +using v8::internal::Object; +using v8::internal::Smi; +using namespace v8::internal::interpreter; + +TEST(TestInterpreterReturn) { + InitializedHandleScope handles; + Handle<Object> undefined_value = + handles.main_isolate()->factory()->undefined_value(); + + BytecodeArrayBuilder builder(handles.main_isolate()); + builder.set_locals_count(0); + builder.Return(); + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); + + InterpreterTester tester(handles.main_isolate(), bytecode_array); + InterpreterCallable callable(tester.GetCallable()); + Handle<Object> return_val = callable().ToHandleChecked(); + CHECK(return_val.is_identical_to(undefined_value)); +} + + +TEST(TestInterpreterLoadUndefined) { + InitializedHandleScope handles; + Handle<Object> undefined_value = + handles.main_isolate()->factory()->undefined_value(); + + BytecodeArrayBuilder builder(handles.main_isolate()); + builder.set_locals_count(0); + builder.LoadUndefined().Return(); + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); + + InterpreterTester tester(handles.main_isolate(), bytecode_array); + InterpreterCallable callable(tester.GetCallable()); + Handle<Object> return_val = callable().ToHandleChecked(); + CHECK(return_val.is_identical_to(undefined_value)); +} + + +TEST(TestInterpreterLoadNull) { + InitializedHandleScope handles; + Handle<Object> null_value = handles.main_isolate()->factory()->null_value(); + + BytecodeArrayBuilder builder(handles.main_isolate()); + builder.set_locals_count(0); + builder.LoadNull().Return(); + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); + + InterpreterTester tester(handles.main_isolate(), bytecode_array); + InterpreterCallable callable(tester.GetCallable()); + Handle<Object> return_val = callable().ToHandleChecked(); + CHECK(return_val.is_identical_to(null_value)); +} + + +TEST(TestInterpreterLoadTheHole) { + InitializedHandleScope handles; + Handle<Object> the_hole_value = + handles.main_isolate()->factory()->the_hole_value(); + + BytecodeArrayBuilder builder(handles.main_isolate()); + builder.set_locals_count(0); + builder.LoadTheHole().Return(); + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); + + InterpreterTester tester(handles.main_isolate(), bytecode_array); + InterpreterCallable callable(tester.GetCallable()); + Handle<Object> return_val = callable().ToHandleChecked(); + CHECK(return_val.is_identical_to(the_hole_value)); +} + + +TEST(TestInterpreterLoadTrue) { + InitializedHandleScope handles; + Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); + + BytecodeArrayBuilder builder(handles.main_isolate()); + builder.set_locals_count(0); + builder.LoadTrue().Return(); + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); + + InterpreterTester tester(handles.main_isolate(), bytecode_array); + InterpreterCallable callable(tester.GetCallable()); + Handle<Object> return_val = callable().ToHandleChecked(); + CHECK(return_val.is_identical_to(true_value)); +} + + +TEST(TestInterpreterLoadFalse) { + InitializedHandleScope handles; + Handle<Object> false_value = handles.main_isolate()->factory()->false_value(); + + BytecodeArrayBuilder builder(handles.main_isolate()); + builder.set_locals_count(0); + builder.LoadFalse().Return(); + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); + + InterpreterTester tester(handles.main_isolate(), bytecode_array); + InterpreterCallable callable(tester.GetCallable()); + Handle<Object> return_val = callable().ToHandleChecked(); + CHECK(return_val.is_identical_to(false_value)); +} + + +TEST(TestInterpreterLoadLiteral) { + InitializedHandleScope handles; + for (int i = -128; i < 128; i++) { + BytecodeArrayBuilder builder(handles.main_isolate()); + builder.set_locals_count(0); + builder.LoadLiteral(Smi::FromInt(i)).Return(); + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); + + InterpreterTester tester(handles.main_isolate(), bytecode_array); + InterpreterCallable callable(tester.GetCallable()); + Handle<Object> return_val = callable().ToHandleChecked(); + CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(i)); + } +} + + +TEST(TestInterpreterLoadStoreRegisters) { + InitializedHandleScope handles; + Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); + for (int i = 0; i <= Register::kMaxRegisterIndex; i++) { + BytecodeArrayBuilder builder(handles.main_isolate()); + builder.set_locals_count(i + 1); + Register reg(i); + builder.LoadTrue() + .StoreAccumulatorInRegister(reg) + .LoadFalse() + .LoadAccumulatorWithRegister(reg) + .Return(); + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); + + InterpreterTester tester(handles.main_isolate(), bytecode_array); + InterpreterCallable callable(tester.GetCallable()); + Handle<Object> return_val = callable().ToHandleChecked(); + CHECK(return_val.is_identical_to(true_value)); + } +} diff --git a/deps/v8/test/cctest/test-api-interceptors.cc b/deps/v8/test/cctest/test-api-interceptors.cc index 2e9bc74a92..c0a8a287ae 100644 --- a/deps/v8/test/cctest/test-api-interceptors.cc +++ b/deps/v8/test/cctest/test-api-interceptors.cc @@ -14,7 +14,6 @@ #include "src/execution.h" #include "src/objects.h" #include "src/parser.h" -#include "src/smart-pointers.h" #include "src/unicode-inl.h" #include "src/utils.h" #include "src/vm-state.h" diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index 88d4aef25e..dad5d6caf5 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -40,12 +40,13 @@ #include "src/api.h" #include "src/arguments.h" #include "src/base/platform/platform.h" +#include "src/base/smart-pointers.h" #include "src/compilation-cache.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/execution.h" +#include "src/futex-emulation.h" #include "src/objects.h" #include "src/parser.h" -#include "src/smart-pointers.h" #include "src/unicode-inl.h" #include "src/utils.h" #include "src/vm-state.h" @@ -522,7 +523,7 @@ TEST(MakingExternalStringConditions) { String::NewFromTwoByte(env->GetIsolate(), two_byte_string); i::DeleteArray(two_byte_string); - // We should refuse to externalize newly created small string. + // We should refuse to externalize small strings. CHECK(!small_string->CanMakeExternal()); // Trigger GCs so that the newly allocated string moves to old gen. CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now @@ -534,14 +535,6 @@ TEST(MakingExternalStringConditions) { small_string = String::NewFromTwoByte(env->GetIsolate(), two_byte_string); i::DeleteArray(two_byte_string); - // We should refuse externalizing newly created small string. - CHECK(!small_string->CanMakeExternal()); - for (int i = 0; i < 100; i++) { - String::Value value(small_string); - } - // Frequently used strings should be accepted. - CHECK(small_string->CanMakeExternal()); - const int buf_size = 10 * 1024; char* buf = i::NewArray<char>(buf_size); memset(buf, 'a', buf_size); @@ -566,7 +559,7 @@ TEST(MakingExternalOneByteStringConditions) { CcTest::heap()->CollectGarbage(i::NEW_SPACE); Local<String> small_string = String::NewFromUtf8(env->GetIsolate(), "s1"); - // We should refuse to externalize newly created small string. + // We should refuse to externalize small strings. CHECK(!small_string->CanMakeExternal()); // Trigger GCs so that the newly allocated string moves to old gen. CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now @@ -574,15 +567,6 @@ TEST(MakingExternalOneByteStringConditions) { // Old space strings should be accepted. CHECK(small_string->CanMakeExternal()); - small_string = String::NewFromUtf8(env->GetIsolate(), "small string 2"); - // We should refuse externalizing newly created small string. - CHECK(!small_string->CanMakeExternal()); - for (int i = 0; i < 100; i++) { - String::Value value(small_string); - } - // Frequently used strings should be accepted. - CHECK(small_string->CanMakeExternal()); - const int buf_size = 10 * 1024; char* buf = i::NewArray<char>(buf_size); memset(buf, 'a', buf_size); @@ -1965,7 +1949,7 @@ THREADED_TEST(UndefinedIsNotEnumerable) { v8::Handle<Script> call_recursively_script; -static const int kTargetRecursionDepth = 200; // near maximum +static const int kTargetRecursionDepth = 150; // near maximum static void CallScriptRecursivelyCall( @@ -3275,6 +3259,7 @@ TEST(TwoPassPhantomCallbacks) { } CHECK_EQ(static_cast<int>(kLength), instance_counter); CcTest::heap()->CollectAllGarbage(); + EmptyMessageQueues(isolate); CHECK_EQ(0, instance_counter); } @@ -3293,6 +3278,7 @@ TEST(TwoPassPhantomCallbacksNestedGc) { array[15]->MarkTriggerGc(); CHECK_EQ(static_cast<int>(kLength), instance_counter); CcTest::heap()->CollectAllGarbage(); + EmptyMessageQueues(isolate); CHECK_EQ(0, instance_counter); } @@ -3342,6 +3328,8 @@ class PhantomStdMapTraits : public v8::StdMapTraits<K, V> { CHECK_EQ(IntKeyToVoidPointer(key), v8::Object::GetAlignedPointerFromInternalField(value, 0)); } + static void OnWeakCallback( + const v8::WeakCallbackInfo<WeakCallbackDataType>&) {} static void DisposeWeak( const v8::WeakCallbackInfo<WeakCallbackDataType>& info) { K key = KeyFromWeakCallbackInfo(info); @@ -6782,6 +6770,7 @@ static void ForceMarkSweep1( THREADED_TEST(GCFromWeakCallbacks) { v8::Isolate* isolate = CcTest::isolate(); + v8::Locker locker(CcTest::isolate()); v8::HandleScope scope(isolate); v8::Handle<Context> context = Context::New(isolate); Context::Scope context_scope(context); @@ -6806,6 +6795,7 @@ THREADED_TEST(GCFromWeakCallbacks) { v8::WeakCallbackType::kParameter); object.handle.MarkIndependent(); invoke_gc[outer_gc](); + EmptyMessageQueues(isolate); CHECK(object.flag); } } @@ -8135,7 +8125,45 @@ THREADED_TEST(CrossDomainIsPropertyEnumerable) { } -THREADED_TEST(CrossDomainForIn) { +THREADED_TEST(CrossDomainFor) { + LocalContext env1; + v8::HandleScope handle_scope(env1->GetIsolate()); + v8::Handle<Context> env2 = Context::New(env1->GetIsolate()); + + Local<Value> foo = v8_str("foo"); + Local<Value> bar = v8_str("bar"); + + // Set to the same domain. + env1->SetSecurityToken(foo); + env2->SetSecurityToken(foo); + + env1->Global()->Set(v8_str("prop"), v8_num(3)); + env2->Global()->Set(v8_str("env1"), env1->Global()); + + // Change env2 to a different domain and set env1's global object + // as the __proto__ of an object in env2 and enumerate properties + // in for-in. It shouldn't enumerate properties on env1's global + // object. + env2->SetSecurityToken(bar); + { + Context::Scope scope_env2(env2); + Local<Value> result = CompileRun( + "(function() {" + " try {" + " for (var p in env1) {" + " if (p == 'prop') return false;" + " }" + " return true;" + " } catch (e) {" + " return false;" + " }" + "})()"); + CHECK(result->IsTrue()); + } +} + + +THREADED_TEST(CrossDomainForInOnPrototype) { LocalContext env1; v8::HandleScope handle_scope(env1->GetIsolate()); v8::Handle<Context> env2 = Context::New(env1->GetIsolate()); @@ -8668,7 +8696,7 @@ TEST(AccessControlES5) { global1->Set(v8_str("other"), global0); // Regression test for issue 1154. - CHECK(CompileRun("Object.keys(other)").IsEmpty()); + CHECK(CompileRun("Object.keys(other).length == 0")->BooleanValue()); CHECK(CompileRun("other.blocked_prop").IsEmpty()); // Regression test for issue 1027. @@ -8719,6 +8747,11 @@ THREADED_TEST(AccessControlGetOwnPropertyNames) { obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42)); obj_template->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL); + // Add an accessor accessible by cross-domain JS code. + obj_template->SetAccessor( + v8_str("accessible_prop"), EchoGetter, EchoSetter, v8::Handle<Value>(), + v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE)); + // Create an environment v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template); context0->Enter(); @@ -8741,11 +8774,15 @@ THREADED_TEST(AccessControlGetOwnPropertyNames) { // global object should be blocked by access checks on the global // proxy object. Accessing the object that requires access checks // is blocked by the access checks on the object itself. - value = CompileRun("Object.getOwnPropertyNames(other).length == 0"); - CHECK(value.IsEmpty()); + value = CompileRun( + "var names = Object.getOwnPropertyNames(other);" + "names.length == 1 && names[0] == 'accessible_prop';"); + CHECK(value->BooleanValue()); - value = CompileRun("Object.getOwnPropertyNames(object).length == 0"); - CHECK(value.IsEmpty()); + value = CompileRun( + "var names = Object.getOwnPropertyNames(object);" + "names.length == 1 && names[0] == 'accessible_prop';"); + CHECK(value->BooleanValue()); context1->Exit(); context0->Exit(); @@ -11660,7 +11697,8 @@ static int GetGlobalObjectsCount() { i::HeapIterator it(CcTest::heap()); for (i::HeapObject* object = it.next(); object != NULL; object = it.next()) if (object->IsJSGlobalObject()) count++; - return count; + // Subtract one to compensate for the code stub context that is always present + return count - 1; } @@ -11869,6 +11907,7 @@ void HandleCreatingCallback1( THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { + v8::Locker locker(CcTest::isolate()); LocalContext context; v8::Isolate* isolate = context->GetIsolate(); @@ -11884,6 +11923,7 @@ THREADED_TEST(NoGlobalHandlesOrphaningDueToWeakCallback) { handle3.SetWeak(&handle3, HandleCreatingCallback1, v8::WeakCallbackType::kParameter); CcTest::heap()->CollectAllGarbage(); + EmptyMessageQueues(isolate); } @@ -12534,6 +12574,17 @@ THREADED_TEST(ExternalAllocatedMemory) { } +TEST(Regress51719) { + i::FLAG_incremental_marking = false; + CcTest::InitializeVM(); + + const int64_t kTriggerGCSize = + v8::internal::Internals::kExternalAllocationLimit + 1; + v8::Isolate* isolate = CcTest::isolate(); + isolate->AdjustAmountOfExternalAllocatedMemory(kTriggerGCSize); +} + + // Regression test for issue 54, object templates with internal fields // but no accessors or interceptors did not get their internal field // count set on instances. @@ -14094,58 +14145,58 @@ void TypedArrayTestHelper(i::ExternalArrayType array_type, int64_t low, THREADED_TEST(Uint8Array) { - TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUint8Array, + TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::FixedUint8Array, v8::ArrayBuffer>(i::kExternalUint8Array, 0, 0xFF); } THREADED_TEST(Int8Array) { - TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalInt8Array, + TypedArrayTestHelper<int8_t, v8::Int8Array, i::FixedInt8Array, v8::ArrayBuffer>(i::kExternalInt8Array, -0x80, 0x7F); } THREADED_TEST(Uint16Array) { - TypedArrayTestHelper<uint16_t, v8::Uint16Array, i::ExternalUint16Array, + TypedArrayTestHelper<uint16_t, v8::Uint16Array, i::FixedUint16Array, v8::ArrayBuffer>(i::kExternalUint16Array, 0, 0xFFFF); } THREADED_TEST(Int16Array) { - TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalInt16Array, + TypedArrayTestHelper<int16_t, v8::Int16Array, i::FixedInt16Array, v8::ArrayBuffer>(i::kExternalInt16Array, -0x8000, 0x7FFF); } THREADED_TEST(Uint32Array) { - TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUint32Array, + TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::FixedUint32Array, v8::ArrayBuffer>(i::kExternalUint32Array, 0, UINT_MAX); } THREADED_TEST(Int32Array) { - TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalInt32Array, + TypedArrayTestHelper<int32_t, v8::Int32Array, i::FixedInt32Array, v8::ArrayBuffer>(i::kExternalInt32Array, INT_MIN, INT_MAX); } THREADED_TEST(Float32Array) { - TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloat32Array, + TypedArrayTestHelper<float, v8::Float32Array, i::FixedFloat32Array, v8::ArrayBuffer>(i::kExternalFloat32Array, -500, 500); } THREADED_TEST(Float64Array) { - TypedArrayTestHelper<double, v8::Float64Array, i::ExternalFloat64Array, + TypedArrayTestHelper<double, v8::Float64Array, i::FixedFloat64Array, v8::ArrayBuffer>(i::kExternalFloat64Array, -500, 500); } THREADED_TEST(Uint8ClampedArray) { TypedArrayTestHelper<uint8_t, v8::Uint8ClampedArray, - i::ExternalUint8ClampedArray, v8::ArrayBuffer>( + i::FixedUint8ClampedArray, v8::ArrayBuffer>( i::kExternalUint8ClampedArray, 0, 0xFF); } @@ -14169,38 +14220,16 @@ THREADED_TEST(DataView) { } -THREADED_TEST(SkipArrayBufferBackingStoreDuringGC) { - LocalContext env; - v8::Isolate* isolate = env->GetIsolate(); - v8::HandleScope handle_scope(isolate); - - // Make sure the pointer looks like a heap object - uint8_t* store_ptr = reinterpret_cast<uint8_t*>(i::kHeapObjectTag); - - // Create ArrayBuffer with pointer-that-cannot-be-visited in the backing store - Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, store_ptr, 8); - - // Should not crash - CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now - CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now - CcTest::heap()->CollectAllGarbage(); - CcTest::heap()->CollectAllGarbage(); - - // Should not move the pointer - CHECK_EQ(ab->GetContents().Data(), store_ptr); -} - - THREADED_TEST(SharedUint8Array) { i::FLAG_harmony_sharedarraybuffer = true; - TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUint8Array, + TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::FixedUint8Array, v8::SharedArrayBuffer>(i::kExternalUint8Array, 0, 0xFF); } THREADED_TEST(SharedInt8Array) { i::FLAG_harmony_sharedarraybuffer = true; - TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalInt8Array, + TypedArrayTestHelper<int8_t, v8::Int8Array, i::FixedInt8Array, v8::SharedArrayBuffer>(i::kExternalInt8Array, -0x80, 0x7F); } @@ -14208,7 +14237,7 @@ THREADED_TEST(SharedInt8Array) { THREADED_TEST(SharedUint16Array) { i::FLAG_harmony_sharedarraybuffer = true; - TypedArrayTestHelper<uint16_t, v8::Uint16Array, i::ExternalUint16Array, + TypedArrayTestHelper<uint16_t, v8::Uint16Array, i::FixedUint16Array, v8::SharedArrayBuffer>(i::kExternalUint16Array, 0, 0xFFFF); } @@ -14216,7 +14245,7 @@ THREADED_TEST(SharedUint16Array) { THREADED_TEST(SharedInt16Array) { i::FLAG_harmony_sharedarraybuffer = true; - TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalInt16Array, + TypedArrayTestHelper<int16_t, v8::Int16Array, i::FixedInt16Array, v8::SharedArrayBuffer>(i::kExternalInt16Array, -0x8000, 0x7FFF); } @@ -14224,7 +14253,7 @@ THREADED_TEST(SharedInt16Array) { THREADED_TEST(SharedUint32Array) { i::FLAG_harmony_sharedarraybuffer = true; - TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUint32Array, + TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::FixedUint32Array, v8::SharedArrayBuffer>(i::kExternalUint32Array, 0, UINT_MAX); } @@ -14232,7 +14261,7 @@ THREADED_TEST(SharedUint32Array) { THREADED_TEST(SharedInt32Array) { i::FLAG_harmony_sharedarraybuffer = true; - TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalInt32Array, + TypedArrayTestHelper<int32_t, v8::Int32Array, i::FixedInt32Array, v8::SharedArrayBuffer>(i::kExternalInt32Array, INT_MIN, INT_MAX); } @@ -14240,7 +14269,7 @@ THREADED_TEST(SharedInt32Array) { THREADED_TEST(SharedFloat32Array) { i::FLAG_harmony_sharedarraybuffer = true; - TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloat32Array, + TypedArrayTestHelper<float, v8::Float32Array, i::FixedFloat32Array, v8::SharedArrayBuffer>(i::kExternalFloat32Array, -500, 500); } @@ -14248,7 +14277,7 @@ THREADED_TEST(SharedFloat32Array) { THREADED_TEST(SharedFloat64Array) { i::FLAG_harmony_sharedarraybuffer = true; - TypedArrayTestHelper<double, v8::Float64Array, i::ExternalFloat64Array, + TypedArrayTestHelper<double, v8::Float64Array, i::FixedFloat64Array, v8::SharedArrayBuffer>(i::kExternalFloat64Array, -500, 500); } @@ -14257,7 +14286,7 @@ THREADED_TEST(SharedFloat64Array) { THREADED_TEST(SharedUint8ClampedArray) { i::FLAG_harmony_sharedarraybuffer = true; TypedArrayTestHelper<uint8_t, v8::Uint8ClampedArray, - i::ExternalUint8ClampedArray, v8::SharedArrayBuffer>( + i::FixedUint8ClampedArray, v8::SharedArrayBuffer>( i::kExternalUint8ClampedArray, 0, 0xFF); } @@ -16532,118 +16561,6 @@ TEST(GCCallbacks) { } -THREADED_TEST(AddToJSFunctionResultCache) { - i::FLAG_stress_compaction = false; - i::FLAG_allow_natives_syntax = true; - v8::HandleScope scope(CcTest::isolate()); - - LocalContext context; - - const char* code = - "(function() {" - " var key0 = 'a';" - " var key1 = 'b';" - " var r0 = %_GetFromCache(0, key0);" - " var r1 = %_GetFromCache(0, key1);" - " var r0_ = %_GetFromCache(0, key0);" - " if (r0 !== r0_)" - " return 'Different results for ' + key0 + ': ' + r0 + ' vs. ' + r0_;" - " var r1_ = %_GetFromCache(0, key1);" - " if (r1 !== r1_)" - " return 'Different results for ' + key1 + ': ' + r1 + ' vs. ' + r1_;" - " return 'PASSED';" - "})()"; - CcTest::heap()->ClearJSFunctionResultCaches(); - ExpectString(code, "PASSED"); -} - - -THREADED_TEST(FillJSFunctionResultCache) { - i::FLAG_allow_natives_syntax = true; - LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - - const char* code = - "(function() {" - " var k = 'a';" - " var r = %_GetFromCache(0, k);" - " for (var i = 0; i < 16; i++) {" - " %_GetFromCache(0, 'a' + i);" - " };" - " if (r === %_GetFromCache(0, k))" - " return 'FAILED: k0CacheSize is too small';" - " return 'PASSED';" - "})()"; - CcTest::heap()->ClearJSFunctionResultCaches(); - ExpectString(code, "PASSED"); -} - - -THREADED_TEST(RoundRobinGetFromCache) { - i::FLAG_allow_natives_syntax = true; - LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - - const char* code = - "(function() {" - " var keys = [];" - " for (var i = 0; i < 16; i++) keys.push(i);" - " var values = [];" - " 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.toString() !== values[i].toString())" - " return 'Wrong value for ' + " - " keys[i] + ': ' + v + ' vs. ' + values[i];" - " };" - " return 'PASSED';" - "})()"; - CcTest::heap()->ClearJSFunctionResultCaches(); - ExpectString(code, "PASSED"); -} - - -THREADED_TEST(ReverseGetFromCache) { - i::FLAG_allow_natives_syntax = true; - LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - - const char* code = - "(function() {" - " var keys = [];" - " for (var i = 0; i < 16; i++) keys.push(i);" - " var values = [];" - " for (var i = 0; i < 16; i++) values[i] = %_GetFromCache(0, keys[i]);" - " for (var i = 15; i >= 16; i--) {" - " var v = %_GetFromCache(0, keys[i]);" - " if (v !== values[i])" - " return 'Wrong value for ' + " - " keys[i] + ': ' + v + ' vs. ' + values[i];" - " };" - " return 'PASSED';" - "})()"; - CcTest::heap()->ClearJSFunctionResultCaches(); - ExpectString(code, "PASSED"); -} - - -THREADED_TEST(TestEviction) { - i::FLAG_allow_natives_syntax = true; - LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - - const char* code = - "(function() {" - " for (var i = 0; i < 2*16; i++) {" - " %_GetFromCache(0, 'a' + i);" - " };" - " return 'PASSED';" - "})()"; - CcTest::heap()->ClearJSFunctionResultCaches(); - ExpectString(code, "PASSED"); -} - - THREADED_TEST(TwoByteStringInOneByteCons) { // See Chromium issue 47824. LocalContext context; @@ -16741,8 +16658,8 @@ TEST(ContainsOnlyOneByte) { const int length = 512; // Ensure word aligned assignment. const int aligned_length = length*sizeof(uintptr_t)/sizeof(uint16_t); - i::SmartArrayPointer<uintptr_t> - aligned_contents(new uintptr_t[aligned_length]); + v8::base::SmartArrayPointer<uintptr_t> aligned_contents( + new uintptr_t[aligned_length]); uint16_t* string_contents = reinterpret_cast<uint16_t*>(aligned_contents.get()); // Set to contain only one byte. @@ -16994,8 +16911,6 @@ TEST(VerifyArrayPrototypeGuarantees) { // Break fast array hole handling by prototype structure changes. BreakArrayGuarantees("[].__proto__.__proto__ = { funny: true };"); // By sending elements to dictionary mode. - BreakArrayGuarantees("Object.freeze(Array.prototype);"); - BreakArrayGuarantees("Object.freeze(Object.prototype);"); BreakArrayGuarantees( "Object.defineProperty(Array.prototype, 0, {" " get: function() { return 3; }});"); @@ -17235,10 +17150,12 @@ class InitDefaultIsolateThread : public v8::base::Thread { void Run() { v8::Isolate::CreateParams create_params; create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); + const intptr_t pageSizeMult = + v8::internal::Page::kPageSize / v8::internal::MB; switch (testCase_) { case SetResourceConstraints: { - create_params.constraints.set_max_semi_space_size(1); - create_params.constraints.set_max_old_space_size(4); + create_params.constraints.set_max_semi_space_size(1 * pageSizeMult); + create_params.constraints.set_max_old_space_size(4 * pageSizeMult); break; } default: @@ -18124,20 +18041,20 @@ THREADED_TEST(Regress93759) { CHECK(result1->Equals(simple_object->GetPrototype())); Local<Value> result2 = CompileRun("Object.getPrototypeOf(protected)"); - CHECK(result2.IsEmpty()); + CHECK(result2->IsNull()); Local<Value> result3 = CompileRun("Object.getPrototypeOf(global)"); CHECK(result3->Equals(global_object->GetPrototype())); Local<Value> result4 = CompileRun("Object.getPrototypeOf(proxy)"); - CHECK(result4.IsEmpty()); + CHECK(result4->IsNull()); Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)"); CHECK(result5->Equals( object_with_hidden->GetPrototype()->ToObject(isolate)->GetPrototype())); Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)"); - CHECK(result6.IsEmpty()); + CHECK(result6->IsNull()); } @@ -19376,15 +19293,15 @@ TEST(AccessCheckThrows) { CheckCorrectThrow("%GetProperty(other, 'x')"); CheckCorrectThrow("%SetProperty(other, 'x', 'foo', 0)"); CheckCorrectThrow("%AddNamedProperty(other, 'x', 'foo', 1)"); - CheckCorrectThrow("%DeleteProperty(other, 'x', 0)"); - CheckCorrectThrow("%DeleteProperty(other, '1', 0)"); + CheckCorrectThrow("%DeleteProperty_Sloppy(other, 'x')"); + CheckCorrectThrow("%DeleteProperty_Strict(other, 'x')"); + CheckCorrectThrow("%DeleteProperty_Sloppy(other, '1')"); + CheckCorrectThrow("%DeleteProperty_Strict(other, '1')"); CheckCorrectThrow("%HasOwnProperty(other, 'x')"); CheckCorrectThrow("%HasProperty(other, 'x')"); CheckCorrectThrow("%HasElement(other, 1)"); CheckCorrectThrow("%IsPropertyEnumerable(other, 'x')"); - CheckCorrectThrow("%GetPropertyNames(other)"); // PROPERTY_ATTRIBUTES_NONE = 0 - CheckCorrectThrow("%GetOwnPropertyNames(other, 0)"); CheckCorrectThrow("%DefineAccessorPropertyUnchecked(" "other, 'x', null, null, 1)"); @@ -20961,43 +20878,50 @@ TEST(StreamingProducesParserCache) { } -TEST(StreamingWithDebuggingDoesNotProduceParserCache) { - // If the debugger is active, we should just not produce parser cache at - // all. This is a regeression test: We used to produce a parser cache without - // any data in it (just headers). +TEST(StreamingWithDebuggingEnabledLate) { + // The streaming parser can only parse lazily, i.e. inner functions are not + // fully parsed. However, we may compile inner functions eagerly when + // debugging. Make sure that we can deal with this when turning on debugging + // after streaming parser has already finished parsing. i::FLAG_min_preparse_length = 0; - const char* chunks[] = {"function foo() { ret", "urn 13; } f", "oo(); ", + const char* chunks[] = {"with({x:1}) {", + " var foo = function foo(y) {", + " return x + y;", + " };", + " foo(2);", + "}", NULL}; LocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - - // Make the debugger active by setting a breakpoint. - CompileRun("function break_here() { }"); - i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast( - v8::Utils::OpenHandle(*env->Global()->Get(v8_str("break_here")))); - EnableDebugger(); - v8::internal::Debug* debug = CcTest::i_isolate()->debug(); - int position = 0; - debug->SetBreakPoint(func, i::Handle<i::Object>(v8::internal::Smi::FromInt(1), - CcTest::i_isolate()), - &position); + v8::TryCatch try_catch(isolate); v8::ScriptCompiler::StreamedSource source( new TestSourceStream(chunks), v8::ScriptCompiler::StreamedSource::ONE_BYTE); v8::ScriptCompiler::ScriptStreamingTask* task = - v8::ScriptCompiler::StartStreamingScript( - isolate, &source, v8::ScriptCompiler::kProduceParserCache); + v8::ScriptCompiler::StartStreamingScript(isolate, &source); - // TestSourceStream::GetMoreData won't block, so it's OK to just run the - // task here in the main thread. task->Run(); delete task; - // Check that we got no cached data. - CHECK(source.GetCachedData() == NULL); + CHECK(!try_catch.HasCaught()); + + v8::ScriptOrigin origin(v8_str("http://foo.com")); + char* full_source = TestSourceStream::FullSourceString(chunks); + + EnableDebugger(); + + v8::Handle<Script> script = v8::ScriptCompiler::Compile( + isolate, &source, v8_str(full_source), origin); + + Maybe<uint32_t> result = + script->Run(env.local()).ToLocalChecked()->Uint32Value(env.local()); + CHECK_EQ(3U, result.FromMaybe(0)); + + delete[] full_source; + DisableDebugger(); } @@ -21256,11 +21180,7 @@ TEST(TurboAsmDisablesNeuter) { v8::V8::Initialize(); v8::HandleScope scope(CcTest::isolate()); LocalContext context; -#if V8_TURBOFAN_TARGET bool should_be_neuterable = !i::FLAG_turbo_asm; -#else - bool should_be_neuterable = true; -#endif const char* load = "function Module(stdlib, foreign, heap) {" " 'use asm';" @@ -21305,14 +21225,10 @@ TEST(GetPrototypeAccessControl) { env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance()); - { - v8::TryCatch try_catch(isolate); - CompileRun( - "function f() { %_GetPrototype(prohibited); }" - "%OptimizeFunctionOnNextCall(f);" - "f();"); - CHECK(try_catch.HasCaught()); - } + CHECK(CompileRun( + "function f() { return %_GetPrototype(prohibited); }" + "%OptimizeFunctionOnNextCall(f);" + "f();")->IsNull()); } @@ -21714,19 +21630,19 @@ TEST(ExtrasExportsObject) { // standalone.gypi ensures we include the test-extra.js file, which should // export the tested functions. - v8::Local<v8::Object> exports = env->GetExtrasExportsObject(); + v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); auto func = - exports->Get(v8_str("testExtraShouldReturnFive")).As<v8::Function>(); + binding->Get(v8_str("testExtraShouldReturnFive")).As<v8::Function>(); auto undefined = v8::Undefined(isolate); auto result = func->Call(undefined, 0, {}).As<v8::Number>(); CHECK_EQ(5, result->Int32Value()); v8::Handle<v8::FunctionTemplate> runtimeFunction = v8::FunctionTemplate::New(isolate, ExtrasExportsTestRuntimeFunction); - exports->Set(v8_str("runtime"), runtimeFunction->GetFunction()); + binding->Set(v8_str("runtime"), runtimeFunction->GetFunction()); func = - exports->Get(v8_str("testExtraShouldCallToRuntime")).As<v8::Function>(); + binding->Get(v8_str("testExtraShouldCallToRuntime")).As<v8::Function>(); result = func->Call(undefined, 0, {}).As<v8::Number>(); CHECK_EQ(7, result->Int32Value()); } @@ -21755,7 +21671,6 @@ TEST(Map) { CHECK_EQ(3, contents->Get(2).As<v8::Int32>()->Value()); CHECK_EQ(4, contents->Get(3).As<v8::Int32>()->Value()); - map = v8::Map::FromArray(env.local(), contents).ToLocalChecked(); CHECK_EQ(2U, map->Size()); CHECK(map->Has(env.local(), v8::Integer::New(isolate, 1)).FromJust()); @@ -21789,16 +21704,6 @@ TEST(Map) { } -TEST(MapFromArrayOddLength) { - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope handle_scope(isolate); - LocalContext env; - // Odd lengths result in a null MaybeLocal. - Local<v8::Array> contents = v8::Array::New(isolate, 41); - CHECK(v8::Map::FromArray(env.local(), contents).IsEmpty()); -} - - TEST(Set) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); @@ -21820,7 +21725,6 @@ TEST(Set) { CHECK_EQ(1, keys->Get(0).As<v8::Int32>()->Value()); CHECK_EQ(2, keys->Get(1).As<v8::Int32>()->Value()); - set = v8::Set::FromArray(env.local(), keys).ToLocalChecked(); CHECK_EQ(2U, set->Size()); CHECK(set->Has(env.local(), v8::Integer::New(isolate, 1)).FromJust()); @@ -21881,33 +21785,45 @@ TEST(CompatibleReceiverCheckOnCachedICHandler) { 0); } +class FutexInterruptionThread : public v8::base::Thread { + public: + explicit FutexInterruptionThread(v8::Isolate* isolate) + : Thread(Options("FutexInterruptionThread")), isolate_(isolate) {} -static int nb_uncaught_exception_callback_calls = 0; - + virtual void Run() { + // Wait a bit before terminating. + v8::base::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(100)); + v8::V8::TerminateExecution(isolate_); + } -bool NoAbortOnUncaughtException(v8::Isolate* isolate) { - ++nb_uncaught_exception_callback_calls; - return false; -} + private: + v8::Isolate* isolate_; +}; -TEST(AbortOnUncaughtExceptionNoAbort) { +TEST(FutexInterruption) { + i::FLAG_harmony_sharedarraybuffer = true; + i::FLAG_harmony_atomics = true; v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> global_template = - v8::ObjectTemplate::New(isolate); - LocalContext env(NULL, global_template); + v8::HandleScope scope(isolate); + LocalContext env; - i::FLAG_abort_on_uncaught_exception = true; - isolate->SetAbortOnUncaughtExceptionCallback(NoAbortOnUncaughtException); + FutexInterruptionThread timeout_thread(isolate); - CompileRun("function boom() { throw new Error(\"boom\") }"); + v8::TryCatch try_catch(CcTest::isolate()); + timeout_thread.Start(); - v8::Local<v8::Object> global_object = env->Global(); - v8::Local<v8::Function> foo = - v8::Local<v8::Function>::Cast(global_object->Get(v8_str("boom"))); + CompileRun( + "var ab = new SharedArrayBuffer(4);" + "var i32a = new Int32Array(ab);" + "Atomics.futexWait(i32a, 0, 0);"); + CHECK(try_catch.HasTerminated()); +} - foo->Call(global_object, 0, NULL); - CHECK_EQ(1, nb_uncaught_exception_callback_calls); +TEST(EstimatedContextSize) { + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + LocalContext env; + CHECK(50000 < env->EstimatedSize()); } diff --git a/deps/v8/test/cctest/test-assembler-arm64.cc b/deps/v8/test/cctest/test-assembler-arm64.cc index 0500bb3c1a..3c2f840058 100644 --- a/deps/v8/test/cctest/test-assembler-arm64.cc +++ b/deps/v8/test/cctest/test-assembler-arm64.cc @@ -2970,61 +2970,6 @@ TEST(ldp_stp_offset_wide) { } -TEST(ldnp_stnp_offset) { - INIT_V8(); - SETUP(); - - uint64_t src[3] = {0x0011223344556677UL, 0x8899aabbccddeeffUL, - 0xffeeddccbbaa9988UL}; - uint64_t dst[7] = {0, 0, 0, 0, 0, 0, 0}; - uintptr_t src_base = reinterpret_cast<uintptr_t>(src); - uintptr_t dst_base = reinterpret_cast<uintptr_t>(dst); - - START(); - __ Mov(x16, src_base); - __ Mov(x17, dst_base); - __ Mov(x18, src_base + 24); - __ Mov(x19, dst_base + 56); - __ Ldnp(w0, w1, MemOperand(x16)); - __ Ldnp(w2, w3, MemOperand(x16, 4)); - __ Ldnp(x4, x5, MemOperand(x16, 8)); - __ Ldnp(w6, w7, MemOperand(x18, -12)); - __ Ldnp(x8, x9, MemOperand(x18, -16)); - __ Stnp(w0, w1, MemOperand(x17)); - __ Stnp(w2, w3, MemOperand(x17, 8)); - __ Stnp(x4, x5, MemOperand(x17, 16)); - __ Stnp(w6, w7, MemOperand(x19, -24)); - __ Stnp(x8, x9, MemOperand(x19, -16)); - END(); - - RUN(); - - CHECK_EQUAL_64(0x44556677, x0); - CHECK_EQUAL_64(0x00112233, x1); - CHECK_EQUAL_64(0x0011223344556677UL, dst[0]); - CHECK_EQUAL_64(0x00112233, x2); - CHECK_EQUAL_64(0xccddeeff, x3); - CHECK_EQUAL_64(0xccddeeff00112233UL, dst[1]); - CHECK_EQUAL_64(0x8899aabbccddeeffUL, x4); - CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[2]); - CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x5); - CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[3]); - CHECK_EQUAL_64(0x8899aabb, x6); - CHECK_EQUAL_64(0xbbaa9988, x7); - CHECK_EQUAL_64(0xbbaa99888899aabbUL, dst[4]); - CHECK_EQUAL_64(0x8899aabbccddeeffUL, x8); - CHECK_EQUAL_64(0x8899aabbccddeeffUL, dst[5]); - CHECK_EQUAL_64(0xffeeddccbbaa9988UL, x9); - CHECK_EQUAL_64(0xffeeddccbbaa9988UL, dst[6]); - CHECK_EQUAL_64(src_base, x16); - CHECK_EQUAL_64(dst_base, x17); - CHECK_EQUAL_64(src_base + 24, x18); - CHECK_EQUAL_64(dst_base + 56, x19); - - TEARDOWN(); -} - - TEST(ldp_stp_preindex) { INIT_V8(); SETUP(); diff --git a/deps/v8/test/cctest/test-assembler-mips.cc b/deps/v8/test/cctest/test-assembler-mips.cc index 13abbbb447..63c9172f56 100644 --- a/deps/v8/test/cctest/test-assembler-mips.cc +++ b/deps/v8/test/cctest/test-assembler-mips.cc @@ -1458,18 +1458,18 @@ TEST(min_max) { } TestFloat; TestFloat test; - const double dblNaN = std::numeric_limits<double>::quiet_NaN(); - const float fltNaN = std::numeric_limits<float>::quiet_NaN(); - const int tableLength = 5; - double inputsa[tableLength] = {2.0, 3.0, dblNaN, 3.0, dblNaN}; - double inputsb[tableLength] = {3.0, 2.0, 3.0, dblNaN, dblNaN}; - double outputsdmin[tableLength] = {2.0, 2.0, 3.0, 3.0, dblNaN}; - double outputsdmax[tableLength] = {3.0, 3.0, 3.0, 3.0, dblNaN}; - - float inputse[tableLength] = {2.0, 3.0, fltNaN, 3.0, fltNaN}; - float inputsf[tableLength] = {3.0, 2.0, 3.0, fltNaN, fltNaN}; - float outputsfmin[tableLength] = {2.0, 2.0, 3.0, 3.0, fltNaN}; - float outputsfmax[tableLength] = {3.0, 3.0, 3.0, 3.0, fltNaN}; + const double double_nan = std::numeric_limits<double>::quiet_NaN(); + const float float_nan = std::numeric_limits<float>::quiet_NaN(); + const int kTableLength = 5; + double inputsa[kTableLength] = {2.0, 3.0, double_nan, 3.0, double_nan}; + double inputsb[kTableLength] = {3.0, 2.0, 3.0, double_nan, double_nan}; + double outputsdmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, double_nan}; + double outputsdmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, double_nan}; + + float inputse[kTableLength] = {2.0, 3.0, float_nan, 3.0, float_nan}; + float inputsf[kTableLength] = {3.0, 2.0, 3.0, float_nan, float_nan}; + float outputsfmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, float_nan}; + float outputsfmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, float_nan}; __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a))); __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b))); @@ -1491,7 +1491,7 @@ TEST(min_max) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputsa[i]; test.b = inputsb[i]; test.e = inputse[i]; @@ -1499,7 +1499,7 @@ TEST(min_max) { (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); - if (i < tableLength - 1) { + if (i < kTableLength - 1) { CHECK_EQ(test.c, outputsdmin[i]); CHECK_EQ(test.d, outputsdmax[i]); CHECK_EQ(test.g, outputsfmin[i]); @@ -1517,7 +1517,7 @@ TEST(min_max) { TEST(rint_d) { if (IsMipsArchVariant(kMips32r6)) { - const int tableLength = 30; + const int kTableLength = 30; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -1530,7 +1530,7 @@ TEST(rint_d) { }TestFloat; TestFloat test; - double inputs[tableLength] = {18446744073709551617.0, + double inputs[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147, 1.7976931348623157E+308, 6.27463370218383111104242366943E-307, @@ -1542,7 +1542,7 @@ TEST(rint_d) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - double outputs_RN[tableLength] = {18446744073709551617.0, + double outputs_RN[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147, 1.7976931348623157E308, 0, @@ -1554,7 +1554,7 @@ TEST(rint_d) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - double outputs_RZ[tableLength] = {18446744073709551617.0, + double outputs_RZ[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147, 1.7976931348623157E308, 0, @@ -1566,7 +1566,7 @@ TEST(rint_d) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - double outputs_RP[tableLength] = {18446744073709551617.0, + double outputs_RP[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147, 1.7976931348623157E308, 1, @@ -1578,7 +1578,7 @@ TEST(rint_d) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - double outputs_RM[tableLength] = {18446744073709551617.0, + double outputs_RM[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147, 1.7976931348623157E308, 0, @@ -1611,7 +1611,7 @@ TEST(rint_d) { for (int j = 0; j < 4; j++) { test.fcsr = fcsr_inputs[j]; - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs[j][i]); @@ -1696,7 +1696,7 @@ TEST(sel) { TEST(rint_s) { if (IsMipsArchVariant(kMips32r6)) { - const int tableLength = 30; + const int kTableLength = 30; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -1709,7 +1709,7 @@ TEST(rint_s) { }TestFloat; TestFloat test; - float inputs[tableLength] = {18446744073709551617.0, + float inputs[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, 1.7976931348623157E+38, 6.27463370218383111104242366943E-37, @@ -1721,7 +1721,7 @@ TEST(rint_s) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - float outputs_RN[tableLength] = {18446744073709551617.0, + float outputs_RN[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, 1.7976931348623157E38, 0, @@ -1733,7 +1733,7 @@ TEST(rint_s) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - float outputs_RZ[tableLength] = {18446744073709551617.0, + float outputs_RZ[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, 1.7976931348623157E38, 0, @@ -1745,7 +1745,7 @@ TEST(rint_s) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - float outputs_RP[tableLength] = {18446744073709551617.0, + float outputs_RP[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, 1.7976931348623157E38, 1, @@ -1757,7 +1757,7 @@ TEST(rint_s) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - float outputs_RM[tableLength] = {18446744073709551617.0, + float outputs_RM[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, 1.7976931348623157E38, 0, @@ -1790,7 +1790,7 @@ TEST(rint_s) { for (int j = 0; j < 4; j++) { test.fcsr = fcsr_inputs[j]; - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs[j][i]); @@ -1802,11 +1802,13 @@ TEST(rint_s) { TEST(mina_maxa) { if (IsMipsArchVariant(kMips32r6)) { - const int tableLength = 12; + const int kTableLength = 15; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); MacroAssembler assm(isolate, NULL, 0); + const double double_nan = std::numeric_limits<double>::quiet_NaN(); + const float float_nan = std::numeric_limits<float>::quiet_NaN(); typedef struct test_float { double a; @@ -1820,53 +1822,37 @@ TEST(mina_maxa) { }TestFloat; TestFloat test; - double inputsa[tableLength] = { - 5.3, 4.8, 6.1, - 9.8, 9.8, 9.8, - -10.0, -8.9, -9.8, - -10.0, -8.9, -9.8 + double inputsa[kTableLength] = { + 5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9, + -9.8, -10.0, -8.9, -9.8, double_nan, 3.0, double_nan }; - double inputsb[tableLength] = { - 4.8, 5.3, 6.1, - -10.0, -8.9, -9.8, - 9.8, 9.8, 9.8, - -9.8, -11.2, -9.8 + double inputsb[kTableLength] = { + 4.8, 5.3, 6.1, -10.0, -8.9, -9.8, 9.8, 9.8, + 9.8, -9.8, -11.2, -9.8, 3.0, double_nan, double_nan }; - double resd[tableLength] = { - 4.8, 4.8, 6.1, - 9.8, -8.9, 9.8, - 9.8, -8.9, 9.8, - -9.8, -8.9, -9.8 + double resd[kTableLength] = { + 4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9, + -9.8, -9.8, -8.9, -9.8, 3.0, 3.0, double_nan }; - double resd1[tableLength] = { - 5.3, 5.3, 6.1, - -10.0, 9.8, 9.8, - -10.0, 9.8, 9.8, - -10.0, -11.2, -9.8 + double resd1[kTableLength] = { + 5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8, + 9.8, -10.0, -11.2, -9.8, 3.0, 3.0, double_nan }; - float inputsc[tableLength] = { - 5.3, 4.8, 6.1, - 9.8, 9.8, 9.8, - -10.0, -8.9, -9.8, - -10.0, -8.9, -9.8 + float inputsc[kTableLength] = { + 5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9, + -9.8, -10.0, -8.9, -9.8, float_nan, 3.0, float_nan }; - float inputsd[tableLength] = { - 4.8, 5.3, 6.1, - -10.0, -8.9, -9.8, - 9.8, 9.8, 9.8, - -9.8, -11.2, -9.8 + float inputsd[kTableLength] = { + 4.8, 5.3, 6.1, -10.0, -8.9, -9.8, 9.8, 9.8, + 9.8, -9.8, -11.2, -9.8, 3.0, float_nan, float_nan }; - float resf[tableLength] = { - 4.8, 4.8, 6.1, - 9.8, -8.9, 9.8, - 9.8, -8.9, 9.8, - -9.8, -8.9, -9.8 + float resf[kTableLength] = { + 4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9, + -9.8, -9.8, -8.9, -9.8, 3.0, 3.0, float_nan }; - float resf1[tableLength] = { - 5.3, 5.3, 6.1, - -10.0, 9.8, 9.8, - -10.0, 9.8, 9.8, - -10.0, -11.2, -9.8 + float resf1[kTableLength] = { + 5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8, + 9.8, -10.0, -11.2, -9.8, 3.0, 3.0, float_nan }; __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) ); @@ -1889,16 +1875,23 @@ TEST(mina_maxa) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputsa[i]; test.b = inputsb[i]; test.c = inputsc[i]; test.d = inputsd[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); - CHECK_EQ(test.resd, resd[i]); - CHECK_EQ(test.resf, resf[i]); - CHECK_EQ(test.resd1, resd1[i]); - CHECK_EQ(test.resf1, resf1[i]); + if (i < kTableLength - 1) { + CHECK_EQ(test.resd, resd[i]); + CHECK_EQ(test.resf, resf[i]); + CHECK_EQ(test.resd1, resd1[i]); + CHECK_EQ(test.resf1, resf1[i]); + } else { + DCHECK(std::isnan(test.resd)); + DCHECK(std::isnan(test.resf)); + DCHECK(std::isnan(test.resd1)); + DCHECK(std::isnan(test.resf1)); + } } } } @@ -1918,22 +1911,22 @@ TEST(trunc_l) { int64_t c; // a trunc result int64_t d; // b trunc result }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, 2147483648.0, dFPU64InvalidResult, @@ -1953,7 +1946,7 @@ TEST(trunc_l) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -1966,7 +1959,7 @@ TEST(trunc_l) { TEST(movz_movn) { if (IsMipsArchVariant(kMips32r2)) { - const int tableLength = 4; + const int kTableLength = 4; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -1987,17 +1980,17 @@ TEST(movz_movn) { }TestFloat; TestFloat test; - double inputs_D[tableLength] = { + double inputs_D[kTableLength] = { 5.3, -5.3, 5.3, -2.9 }; - double inputs_S[tableLength] = { + double inputs_S[kTableLength] = { 4.8, 4.8, -4.8, -0.29 }; - float outputs_S[tableLength] = { + float outputs_S[kTableLength] = { 4.8, 4.8, -4.8, -0.29 }; - double outputs_D[tableLength] = { + double outputs_D[kTableLength] = { 5.3, -5.3, 5.3, -2.9 }; @@ -2029,7 +2022,7 @@ TEST(movz_movn) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.c = inputs_S[i]; @@ -2053,7 +2046,7 @@ TEST(movz_movn) { TEST(movt_movd) { if (IsMipsArchVariant(kMips32r2)) { - const int tableLength = 4; + const int kTableLength = 4; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); @@ -2073,22 +2066,22 @@ TEST(movt_movd) { }TestFloat; TestFloat test; - double inputs_D[tableLength] = { + double inputs_D[kTableLength] = { 5.3, -5.3, 20.8, -2.9 }; - double inputs_S[tableLength] = { + double inputs_S[kTableLength] = { 4.88, 4.8, -4.8, -0.29 }; - float outputs_S[tableLength] = { + float outputs_S[kTableLength] = { 4.88, 4.8, -4.8, -0.29 }; - double outputs_D[tableLength] = { + double outputs_D[kTableLength] = { 5.3, -5.3, 20.8, -2.9 }; int condition_flags[8] = {0, 1, 2, 3, 4, 5, 6, 7}; - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.srcd = inputs_D[i]; test.srcf = inputs_S[i]; @@ -2160,8 +2153,8 @@ TEST(cvt_w_d) { int32_t b; int32_t fcsr; }Test; - const int tableLength = 24; - double inputs[tableLength] = { + const int kTableLength = 24; + double inputs[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483637.0, 2147483638.0, 2147483639.0, @@ -2169,28 +2162,28 @@ TEST(cvt_w_d) { 2147483643.0, 2147483644.0, 2147483645.0, 2147483646.0, 2147483647.0, 2147483653.0 }; - double outputs_RN[tableLength] = { + double outputs_RN[kTableLength] = { 2.0, 3.0, 2.0, 3.0, 4.0, 4.0, -2.0, -3.0, -2.0, -3.0, -4.0, -4.0, 2147483637.0, 2147483638.0, 2147483639.0, 2147483640.0, 2147483641.0, 2147483642.0, 2147483643.0, 2147483644.0, 2147483645.0, 2147483646.0, 2147483647.0, kFPUInvalidResult}; - double outputs_RZ[tableLength] = { + double outputs_RZ[kTableLength] = { 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, 2147483637.0, 2147483638.0, 2147483639.0, 2147483640.0, 2147483641.0, 2147483642.0, 2147483643.0, 2147483644.0, 2147483645.0, 2147483646.0, 2147483647.0, kFPUInvalidResult}; - double outputs_RP[tableLength] = { + double outputs_RP[kTableLength] = { 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, 2147483637.0, 2147483638.0, 2147483639.0, 2147483640.0, 2147483641.0, 2147483642.0, 2147483643.0, 2147483644.0, 2147483645.0, 2147483646.0, 2147483647.0, kFPUInvalidResult}; - double outputs_RM[tableLength] = { + double outputs_RM[kTableLength] = { 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, -3.0, -3.0, -3.0, -4.0, -4.0, -4.0, 2147483637.0, 2147483638.0, 2147483639.0, @@ -2217,7 +2210,7 @@ TEST(cvt_w_d) { F3 f = FUNCTION_CAST<F3>(code->entry()); for (int j = 0; j < 4; j++) { test.fcsr = fcsr_inputs[j]; - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs[j][i]); @@ -2238,22 +2231,22 @@ TEST(trunc_w) { int32_t c; // a trunc result int32_t d; // b trunc result }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, kFPUInvalidResult, kFPUInvalidResult, @@ -2273,7 +2266,7 @@ TEST(trunc_w) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -2295,22 +2288,22 @@ TEST(round_w) { int32_t c; // a trunc result int32_t d; // b trunc result }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 2.0, 3.0, 2.0, 3.0, 4.0, 4.0, -2.0, -3.0, -2.0, -3.0, -4.0, -4.0, kFPUInvalidResult, kFPUInvalidResult, @@ -2330,7 +2323,7 @@ TEST(round_w) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -2353,22 +2346,22 @@ TEST(round_l) { int64_t c; int64_t d; }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 2.0, 3.0, 2.0, 3.0, 4.0, 4.0, -2.0, -3.0, -2.0, -3.0, -4.0, -4.0, 2147483648.0, dFPU64InvalidResult, @@ -2388,7 +2381,7 @@ TEST(round_l) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -2400,7 +2393,7 @@ TEST(round_l) { TEST(sub) { - const int tableLength = 12; + const int kTableLength = 12; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -2416,27 +2409,27 @@ TEST(sub) { }TestFloat; TestFloat test; - double inputfs_D[tableLength] = { + double inputfs_D[kTableLength] = { 5.3, 4.8, 2.9, -5.3, -4.8, -2.9, 5.3, 4.8, 2.9, -5.3, -4.8, -2.9 }; - double inputft_D[tableLength] = { + double inputft_D[kTableLength] = { 4.8, 5.3, 2.9, 4.8, 5.3, 2.9, -4.8, -5.3, -2.9, -4.8, -5.3, -2.9 }; - double outputs_D[tableLength] = { + double outputs_D[kTableLength] = { 0.5, -0.5, 0.0, -10.1, -10.1, -5.8, 10.1, 10.1, 5.8, -0.5, 0.5, 0.0 }; - float inputfs_S[tableLength] = { + float inputfs_S[kTableLength] = { 5.3, 4.8, 2.9, -5.3, -4.8, -2.9, 5.3, 4.8, 2.9, -5.3, -4.8, -2.9 }; - float inputft_S[tableLength] = { + float inputft_S[kTableLength] = { 4.8, 5.3, 2.9, 4.8, 5.3, 2.9, -4.8, -5.3, -2.9, -4.8, -5.3, -2.9 }; - float outputs_S[tableLength] = { + float outputs_S[kTableLength] = { 0.5, -0.5, 0.0, -10.1, -10.1, -5.8, 10.1, 10.1, 5.8, -0.5, 0.5, 0.0 }; @@ -2456,7 +2449,7 @@ TEST(sub) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputfs_S[i]; test.b = inputft_S[i]; test.c = inputfs_D[i]; @@ -2469,7 +2462,7 @@ TEST(sub) { TEST(sqrt_rsqrt_recip) { - const int tableLength = 4; + const int kTableLength = 4; const double deltaDouble = 2E-15; const float deltaFloat = 2E-7; const float sqrt2_s = sqrt(2); @@ -2491,18 +2484,18 @@ TEST(sqrt_rsqrt_recip) { }TestFloat; TestFloat test; - double inputs_D[tableLength] = { + double inputs_D[kTableLength] = { 0.0L, 4.0L, 2.0L, 4e-28L }; - double outputs_D[tableLength] = { + double outputs_D[kTableLength] = { 0.0L, 2.0L, sqrt2_d, 2e-14L }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 0.0, 4.0, 2.0, 4e-28 }; - float outputs_S[tableLength] = { + float outputs_S[kTableLength] = { 0.0, 2.0, sqrt2_s, 2e-14 }; @@ -2536,7 +2529,7 @@ TEST(sqrt_rsqrt_recip) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { float f1; double d1; test.a = inputs_S[i]; @@ -2573,7 +2566,7 @@ TEST(sqrt_rsqrt_recip) { TEST(neg) { - const int tableLength = 3; + const int kTableLength = 3; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -2587,18 +2580,18 @@ TEST(neg) { }TestFloat; TestFloat test; - double inputs_D[tableLength] = { + double inputs_D[kTableLength] = { 0.0, 4.0, -2.0 }; - double outputs_D[tableLength] = { + double outputs_D[kTableLength] = { 0.0, -4.0, 2.0 }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 0.0, 4.0, -2.0 }; - float outputs_S[tableLength] = { + float outputs_S[kTableLength] = { 0.0, -4.0, 2.0 }; __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) ); @@ -2615,7 +2608,7 @@ TEST(neg) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_S[i]; test.c = inputs_D[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -2626,7 +2619,7 @@ TEST(neg) { TEST(mul) { - const int tableLength = 4; + const int kTableLength = 4; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -2642,17 +2635,17 @@ TEST(mul) { }TestFloat; TestFloat test; - double inputfs_D[tableLength] = { + double inputfs_D[kTableLength] = { 5.3, -5.3, 5.3, -2.9 }; - double inputft_D[tableLength] = { + double inputft_D[kTableLength] = { 4.8, 4.8, -4.8, -0.29 }; - float inputfs_S[tableLength] = { + float inputfs_S[kTableLength] = { 5.3, -5.3, 5.3, -2.9 }; - float inputft_S[tableLength] = { + float inputft_S[kTableLength] = { 4.8, 4.8, -4.8, -0.29 }; @@ -2672,7 +2665,7 @@ TEST(mul) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputfs_S[i]; test.b = inputft_S[i]; test.c = inputfs_D[i]; @@ -2685,7 +2678,7 @@ TEST(mul) { TEST(mov) { - const int tableLength = 4; + const int kTableLength = 4; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -2699,17 +2692,17 @@ TEST(mov) { }TestFloat; TestFloat test; - double inputs_D[tableLength] = { + double inputs_D[kTableLength] = { 5.3, -5.3, 5.3, -2.9 }; - double inputs_S[tableLength] = { + double inputs_S[kTableLength] = { 4.8, 4.8, -4.8, -0.29 }; - float outputs_S[tableLength] = { + float outputs_S[kTableLength] = { 4.8, 4.8, -4.8, -0.29 }; - double outputs_D[tableLength] = { + double outputs_D[kTableLength] = { 5.3, -5.3, 5.3, -2.9 }; @@ -2727,7 +2720,7 @@ TEST(mov) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.c = inputs_S[i]; @@ -2750,22 +2743,22 @@ TEST(floor_w) { int32_t c; // a floor result int32_t d; // b floor result }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, -3.0, -3.0, -3.0, -4.0, -4.0, -4.0, kFPUInvalidResult, kFPUInvalidResult, @@ -2785,7 +2778,7 @@ TEST(floor_w) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -2808,22 +2801,22 @@ TEST(floor_l) { int64_t c; int64_t d; }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, -3.0, -3.0, -3.0, -4.0, -4.0, -4.0, 2147483648.0, dFPU64InvalidResult, @@ -2843,7 +2836,7 @@ TEST(floor_l) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -2866,22 +2859,22 @@ TEST(ceil_w) { int32_t c; // a floor result int32_t d; // b floor result }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, kFPUInvalidResult, kFPUInvalidResult, @@ -2901,7 +2894,7 @@ TEST(ceil_w) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -2924,22 +2917,22 @@ TEST(ceil_l) { int64_t c; int64_t d; }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, 2147483648.0, dFPU64InvalidResult, @@ -2959,7 +2952,7 @@ TEST(ceil_l) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -5059,4 +5052,56 @@ TEST(r6_balc) { } +uint32_t run_bal(int16_t offset) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + + MacroAssembler assm(isolate, NULL, 0); + + __ mov(t0, ra); + __ bal(offset); // Equivalent for "BGEZAL zero_reg, offset". + __ nop(); + + __ mov(ra, t0); + __ jr(ra); + __ nop(); + + __ li(v0, 1); + __ jr(ra); + __ nop(); + + CodeDesc desc; + assm.GetCode(&desc); + Handle<Code> code = isolate->factory()->NewCode( + desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); + + F2 f = FUNCTION_CAST<F2>(code->entry()); + + uint32_t res = + reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + + return res; +} + + +TEST(bal) { + CcTest::InitializeVM(); + + struct TestCaseBal { + int16_t offset; + uint32_t expected_res; + }; + + struct TestCaseBal tc[] = { + // offset, expected_res + { 4, 1 }, + }; + + size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBal); + for (size_t i = 0; i < nr_test_cases; ++i) { + CHECK_EQ(tc[i].expected_res, run_bal(tc[i].offset)); + } +} + + #undef __ diff --git a/deps/v8/test/cctest/test-assembler-mips64.cc b/deps/v8/test/cctest/test-assembler-mips64.cc index bb7b05ca76..00e364cfce 100644 --- a/deps/v8/test/cctest/test-assembler-mips64.cc +++ b/deps/v8/test/cctest/test-assembler-mips64.cc @@ -1440,7 +1440,7 @@ TEST(MIPS16) { } -// ----------------------mips32r6 specific tests---------------------- +// ----------------------mips64r6 specific tests---------------------- TEST(seleqz_selnez) { if (kArchVariant == kMips64r6) { CcTest::InitializeVM(); @@ -1562,18 +1562,18 @@ TEST(min_max) { } TestFloat; TestFloat test; - const double dblNaN = std::numeric_limits<double>::quiet_NaN(); - const float fltNaN = std::numeric_limits<float>::quiet_NaN(); - const int tableLength = 5; - double inputsa[tableLength] = {2.0, 3.0, dblNaN, 3.0, dblNaN}; - double inputsb[tableLength] = {3.0, 2.0, 3.0, dblNaN, dblNaN}; - double outputsdmin[tableLength] = {2.0, 2.0, 3.0, 3.0, dblNaN}; - double outputsdmax[tableLength] = {3.0, 3.0, 3.0, 3.0, dblNaN}; - - float inputse[tableLength] = {2.0, 3.0, fltNaN, 3.0, fltNaN}; - float inputsf[tableLength] = {3.0, 2.0, 3.0, fltNaN, fltNaN}; - float outputsfmin[tableLength] = {2.0, 2.0, 3.0, 3.0, fltNaN}; - float outputsfmax[tableLength] = {3.0, 3.0, 3.0, 3.0, fltNaN}; + const double double_nan = std::numeric_limits<double>::quiet_NaN(); + const float float_nan = std::numeric_limits<float>::quiet_NaN(); + const int kTableLength = 5; + double inputsa[kTableLength] = {2.0, 3.0, double_nan, 3.0, double_nan}; + double inputsb[kTableLength] = {3.0, 2.0, 3.0, double_nan, double_nan}; + double outputsdmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, double_nan}; + double outputsdmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, double_nan}; + + float inputse[kTableLength] = {2.0, 3.0, float_nan, 3.0, float_nan}; + float inputsf[kTableLength] = {3.0, 2.0, 3.0, float_nan, float_nan}; + float outputsfmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, float_nan}; + float outputsfmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, float_nan}; __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a))); __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b))); @@ -1595,7 +1595,7 @@ TEST(min_max) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputsa[i]; test.b = inputsb[i]; test.e = inputse[i]; @@ -1603,7 +1603,7 @@ TEST(min_max) { (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); - if (i < tableLength - 1) { + if (i < kTableLength - 1) { CHECK_EQ(test.c, outputsdmin[i]); CHECK_EQ(test.d, outputsdmax[i]); CHECK_EQ(test.g, outputsfmin[i]); @@ -1621,7 +1621,7 @@ TEST(min_max) { TEST(rint_d) { if (kArchVariant == kMips64r6) { - const int tableLength = 30; + const int kTableLength = 30; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -1634,7 +1634,7 @@ TEST(rint_d) { }TestFloat; TestFloat test; - double inputs[tableLength] = {18446744073709551617.0, + double inputs[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147, 1.7976931348623157E+308, 6.27463370218383111104242366943E-307, @@ -1646,7 +1646,7 @@ TEST(rint_d) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - double outputs_RN[tableLength] = {18446744073709551617.0, + double outputs_RN[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147, 1.7976931348623157E308, 0, @@ -1658,7 +1658,7 @@ TEST(rint_d) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - double outputs_RZ[tableLength] = {18446744073709551617.0, + double outputs_RZ[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147, 1.7976931348623157E308, 0, @@ -1670,7 +1670,7 @@ TEST(rint_d) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - double outputs_RP[tableLength] = {18446744073709551617.0, + double outputs_RP[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147, 1.7976931348623157E308, 1, @@ -1682,7 +1682,7 @@ TEST(rint_d) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - double outputs_RM[tableLength] = {18446744073709551617.0, + double outputs_RM[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147, 1.7976931348623157E308, 0, @@ -1713,7 +1713,7 @@ TEST(rint_d) { for (int j = 0; j < 4; j++) { test.fcsr = fcsr_inputs[j]; - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs[j][i]); @@ -1798,7 +1798,7 @@ TEST(sel) { TEST(rint_s) { if (kArchVariant == kMips64r6) { - const int tableLength = 30; + const int kTableLength = 30; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -1811,7 +1811,7 @@ TEST(rint_s) { }TestFloat; TestFloat test; - float inputs[tableLength] = {18446744073709551617.0, + float inputs[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, 1.7976931348623157E+38, 6.27463370218383111104242366943E-37, @@ -1823,7 +1823,7 @@ TEST(rint_s) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - float outputs_RN[tableLength] = {18446744073709551617.0, + float outputs_RN[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, 1.7976931348623157E38, 0, @@ -1835,7 +1835,7 @@ TEST(rint_s) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - float outputs_RZ[tableLength] = {18446744073709551617.0, + float outputs_RZ[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, 1.7976931348623157E38, 0, @@ -1847,7 +1847,7 @@ TEST(rint_s) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - float outputs_RP[tableLength] = {18446744073709551617.0, + float outputs_RP[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, 1.7976931348623157E38, 1, @@ -1859,7 +1859,7 @@ TEST(rint_s) { 37778931862957161709582.0, 37778931862957161709583.0, 37778931862957161709584.0, 37778931862957161709585.0, 37778931862957161709586.0, 37778931862957161709587.0}; - float outputs_RM[tableLength] = {18446744073709551617.0, + float outputs_RM[kTableLength] = {18446744073709551617.0, 4503599627370496.0, -4503599627370496.0, 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37, 1.7976931348623157E38, 0, @@ -1892,7 +1892,7 @@ TEST(rint_s) { for (int j = 0; j < 4; j++) { test.fcsr = fcsr_inputs[j]; - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs[j][i]); @@ -1904,11 +1904,13 @@ TEST(rint_s) { TEST(mina_maxa) { if (kArchVariant == kMips64r6) { - const int tableLength = 12; + const int kTableLength = 15; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); MacroAssembler assm(isolate, NULL, 0); + const double double_nan = std::numeric_limits<double>::quiet_NaN(); + const float float_nan = std::numeric_limits<float>::quiet_NaN(); typedef struct test_float { double a; @@ -1922,53 +1924,37 @@ TEST(mina_maxa) { }TestFloat; TestFloat test; - double inputsa[tableLength] = { - 5.3, 4.8, 6.1, - 9.8, 9.8, 9.8, - -10.0, -8.9, -9.8, - -10.0, -8.9, -9.8 + double inputsa[kTableLength] = { + 5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9, + -9.8, -10.0, -8.9, -9.8, double_nan, 3.0, double_nan }; - double inputsb[tableLength] = { - 4.8, 5.3, 6.1, - -10.0, -8.9, -9.8, - 9.8, 9.8, 9.8, - -9.8, -11.2, -9.8 + double inputsb[kTableLength] = { + 4.8, 5.3, 6.1, -10.0, -8.9, -9.8, 9.8, 9.8, + 9.8, -9.8, -11.2, -9.8, 3.0, double_nan, double_nan }; - double resd[tableLength] = { - 4.8, 4.8, 6.1, - 9.8, -8.9, 9.8, - 9.8, -8.9, 9.8, - -9.8, -8.9, -9.8 + double resd[kTableLength] = { + 4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9, + -9.8, -9.8, -8.9, -9.8, 3.0, 3.0, double_nan }; - double resd1[tableLength] = { - 5.3, 5.3, 6.1, - -10.0, 9.8, 9.8, - -10.0, 9.8, 9.8, - -10.0, -11.2, -9.8 + double resd1[kTableLength] = { + 5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8, + 9.8, -10.0, -11.2, -9.8, 3.0, 3.0, double_nan }; - float inputsc[tableLength] = { - 5.3, 4.8, 6.1, - 9.8, 9.8, 9.8, - -10.0, -8.9, -9.8, - -10.0, -8.9, -9.8 + float inputsc[kTableLength] = { + 5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9, + -9.8, -10.0, -8.9, -9.8, float_nan, 3.0, float_nan }; - float inputsd[tableLength] = { - 4.8, 5.3, 6.1, - -10.0, -8.9, -9.8, - 9.8, 9.8, 9.8, - -9.8, -11.2, -9.8 + float inputsd[kTableLength] = { + 4.8, 5.3, 6.1, -10.0, -8.9, -9.8, 9.8, 9.8, + 9.8, -9.8, -11.2, -9.8, 3.0, float_nan, float_nan }; - float resf[tableLength] = { - 4.8, 4.8, 6.1, - 9.8, -8.9, 9.8, - 9.8, -8.9, 9.8, - -9.8, -8.9, -9.8 + float resf[kTableLength] = { + 4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9, + -9.8, -9.8, -8.9, -9.8, 3.0, 3.0, float_nan }; - float resf1[tableLength] = { - 5.3, 5.3, 6.1, - -10.0, 9.8, 9.8, - -10.0, 9.8, 9.8, - -10.0, -11.2, -9.8 + float resf1[kTableLength] = { + 5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8, + 9.8, -10.0, -11.2, -9.8, 3.0, 3.0, float_nan }; __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) ); @@ -1991,24 +1977,31 @@ TEST(mina_maxa) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputsa[i]; test.b = inputsb[i]; test.c = inputsc[i]; test.d = inputsd[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); - CHECK_EQ(test.resd, resd[i]); - CHECK_EQ(test.resf, resf[i]); - CHECK_EQ(test.resd1, resd1[i]); - CHECK_EQ(test.resf1, resf1[i]); + if (i < kTableLength - 1) { + CHECK_EQ(test.resd, resd[i]); + CHECK_EQ(test.resf, resf[i]); + CHECK_EQ(test.resd1, resd1[i]); + CHECK_EQ(test.resf1, resf1[i]); + } else { + DCHECK(std::isnan(test.resd)); + DCHECK(std::isnan(test.resf)); + DCHECK(std::isnan(test.resd1)); + DCHECK(std::isnan(test.resf1)); + } } } } -// ----------------------mips32r2 specific tests---------------------- +// ----------------------mips64r2 specific tests---------------------- TEST(trunc_l) { if (kArchVariant == kMips64r2) { CcTest::InitializeVM(); @@ -2022,22 +2015,22 @@ TEST(trunc_l) { int64_t c; // a trunc result int64_t d; // b trunc result }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, 2147483648.0, dFPU64InvalidResult, @@ -2057,7 +2050,7 @@ TEST(trunc_l) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -2070,7 +2063,7 @@ TEST(trunc_l) { TEST(movz_movn) { if (kArchVariant == kMips64r2) { - const int tableLength = 4; + const int kTableLength = 4; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -2091,17 +2084,17 @@ TEST(movz_movn) { }TestFloat; TestFloat test; - double inputs_D[tableLength] = { + double inputs_D[kTableLength] = { 5.3, -5.3, 5.3, -2.9 }; - double inputs_S[tableLength] = { + double inputs_S[kTableLength] = { 4.8, 4.8, -4.8, -0.29 }; - float outputs_S[tableLength] = { + float outputs_S[kTableLength] = { 4.8, 4.8, -4.8, -0.29 }; - double outputs_D[tableLength] = { + double outputs_D[kTableLength] = { 5.3, -5.3, 5.3, -2.9 }; @@ -2133,7 +2126,7 @@ TEST(movz_movn) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.c = inputs_S[i]; @@ -2157,7 +2150,7 @@ TEST(movz_movn) { TEST(movt_movd) { if (kArchVariant == kMips64r2) { - const int tableLength = 4; + const int kTableLength = 4; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); typedef struct test_float { @@ -2176,22 +2169,22 @@ TEST(movt_movd) { }TestFloat; TestFloat test; - double inputs_D[tableLength] = { + double inputs_D[kTableLength] = { 5.3, -5.3, 20.8, -2.9 }; - double inputs_S[tableLength] = { + double inputs_S[kTableLength] = { 4.88, 4.8, -4.8, -0.29 }; - float outputs_S[tableLength] = { + float outputs_S[kTableLength] = { 4.88, 4.8, -4.8, -0.29 }; - double outputs_D[tableLength] = { + double outputs_D[kTableLength] = { 5.3, -5.3, 20.8, -2.9 }; int condition_flags[8] = {0, 1, 2, 3, 4, 5, 6, 7}; - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.srcd = inputs_D[i]; test.srcf = inputs_S[i]; @@ -2264,8 +2257,8 @@ TEST(cvt_w_d) { int32_t b; int fcsr; }Test; - const int tableLength = 24; - double inputs[tableLength] = { + const int kTableLength = 24; + double inputs[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483637.0, 2147483638.0, 2147483639.0, @@ -2273,28 +2266,28 @@ TEST(cvt_w_d) { 2147483643.0, 2147483644.0, 2147483645.0, 2147483646.0, 2147483647.0, 2147483653.0 }; - double outputs_RN[tableLength] = { + double outputs_RN[kTableLength] = { 2.0, 3.0, 2.0, 3.0, 4.0, 4.0, -2.0, -3.0, -2.0, -3.0, -4.0, -4.0, 2147483637.0, 2147483638.0, 2147483639.0, 2147483640.0, 2147483641.0, 2147483642.0, 2147483643.0, 2147483644.0, 2147483645.0, 2147483646.0, 2147483647.0, kFPUInvalidResult}; - double outputs_RZ[tableLength] = { + double outputs_RZ[kTableLength] = { 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, 2147483637.0, 2147483638.0, 2147483639.0, 2147483640.0, 2147483641.0, 2147483642.0, 2147483643.0, 2147483644.0, 2147483645.0, 2147483646.0, 2147483647.0, kFPUInvalidResult}; - double outputs_RP[tableLength] = { + double outputs_RP[kTableLength] = { 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, 2147483637.0, 2147483638.0, 2147483639.0, 2147483640.0, 2147483641.0, 2147483642.0, 2147483643.0, 2147483644.0, 2147483645.0, 2147483646.0, 2147483647.0, kFPUInvalidResult}; - double outputs_RM[tableLength] = { + double outputs_RM[kTableLength] = { 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, -3.0, -3.0, -3.0, -4.0, -4.0, -4.0, 2147483637.0, 2147483638.0, 2147483639.0, @@ -2321,7 +2314,7 @@ TEST(cvt_w_d) { F3 f = FUNCTION_CAST<F3>(code->entry()); for (int j = 0; j < 4; j++) { test.fcsr = fcsr_inputs[j]; - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs[j][i]); @@ -2342,22 +2335,22 @@ TEST(trunc_w) { int32_t c; // a trunc result int32_t d; // b trunc result }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, kFPUInvalidResult, kFPUInvalidResult, @@ -2377,7 +2370,7 @@ TEST(trunc_w) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -2399,22 +2392,22 @@ TEST(round_w) { int32_t c; // a trunc result int32_t d; // b trunc result }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 2.0, 3.0, 2.0, 3.0, 4.0, 4.0, -2.0, -3.0, -2.0, -3.0, -4.0, -4.0, kFPUInvalidResult, kFPUInvalidResult, @@ -2434,7 +2427,7 @@ TEST(round_w) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -2456,22 +2449,22 @@ TEST(round_l) { int64_t c; int64_t d; }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 2.0, 3.0, 2.0, 3.0, 4.0, 4.0, -2.0, -3.0, -2.0, -3.0, -4.0, -4.0, 2147483648.0, dFPU64InvalidResult, @@ -2491,7 +2484,7 @@ TEST(round_l) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; std::cout<< i<< "\n"; @@ -2503,7 +2496,7 @@ TEST(round_l) { TEST(sub) { - const int tableLength = 12; + const int kTableLength = 12; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -2519,27 +2512,27 @@ TEST(sub) { }TestFloat; TestFloat test; - double inputfs_D[tableLength] = { + double inputfs_D[kTableLength] = { 5.3, 4.8, 2.9, -5.3, -4.8, -2.9, 5.3, 4.8, 2.9, -5.3, -4.8, -2.9 }; - double inputft_D[tableLength] = { + double inputft_D[kTableLength] = { 4.8, 5.3, 2.9, 4.8, 5.3, 2.9, -4.8, -5.3, -2.9, -4.8, -5.3, -2.9 }; - double outputs_D[tableLength] = { + double outputs_D[kTableLength] = { 0.5, -0.5, 0.0, -10.1, -10.1, -5.8, 10.1, 10.1, 5.8, -0.5, 0.5, 0.0 }; - float inputfs_S[tableLength] = { + float inputfs_S[kTableLength] = { 5.3, 4.8, 2.9, -5.3, -4.8, -2.9, 5.3, 4.8, 2.9, -5.3, -4.8, -2.9 }; - float inputft_S[tableLength] = { + float inputft_S[kTableLength] = { 4.8, 5.3, 2.9, 4.8, 5.3, 2.9, -4.8, -5.3, -2.9, -4.8, -5.3, -2.9 }; - float outputs_S[tableLength] = { + float outputs_S[kTableLength] = { 0.5, -0.5, 0.0, -10.1, -10.1, -5.8, 10.1, 10.1, 5.8, -0.5, 0.5, 0.0 }; @@ -2559,7 +2552,7 @@ TEST(sub) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputfs_S[i]; test.b = inputft_S[i]; test.c = inputfs_D[i]; @@ -2572,7 +2565,7 @@ TEST(sub) { TEST(sqrt_rsqrt_recip) { - const int tableLength = 4; + const int kTableLength = 4; const double deltaDouble = 2E-15; const float deltaFloat = 2E-7; const float sqrt2_s = sqrt(2); @@ -2594,18 +2587,18 @@ TEST(sqrt_rsqrt_recip) { }TestFloat; TestFloat test; - double inputs_D[tableLength] = { + double inputs_D[kTableLength] = { 0.0L, 4.0L, 2.0L, 4e-28L }; - double outputs_D[tableLength] = { + double outputs_D[kTableLength] = { 0.0L, 2.0L, sqrt2_d, 2e-14L }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 0.0, 4.0, 2.0, 4e-28 }; - float outputs_S[tableLength] = { + float outputs_S[kTableLength] = { 0.0, 2.0, sqrt2_s, 2e-14 }; @@ -2633,7 +2626,7 @@ TEST(sqrt_rsqrt_recip) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { float f1; double d1; test.a = inputs_S[i]; @@ -2668,7 +2661,7 @@ TEST(sqrt_rsqrt_recip) { TEST(neg) { - const int tableLength = 2; + const int kTableLength = 2; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -2682,18 +2675,18 @@ TEST(neg) { }TestFloat; TestFloat test; - double inputs_D[tableLength] = { + double inputs_D[kTableLength] = { 4.0, -2.0 }; - double outputs_D[tableLength] = { + double outputs_D[kTableLength] = { -4.0, 2.0 }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 4.0, -2.0 }; - float outputs_S[tableLength] = { + float outputs_S[kTableLength] = { -4.0, 2.0 }; __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) ); @@ -2710,7 +2703,7 @@ TEST(neg) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_S[i]; test.c = inputs_D[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -2722,7 +2715,7 @@ TEST(neg) { TEST(mul) { - const int tableLength = 4; + const int kTableLength = 4; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -2738,17 +2731,17 @@ TEST(mul) { }TestFloat; TestFloat test; - double inputfs_D[tableLength] = { + double inputfs_D[kTableLength] = { 5.3, -5.3, 5.3, -2.9 }; - double inputft_D[tableLength] = { + double inputft_D[kTableLength] = { 4.8, 4.8, -4.8, -0.29 }; - float inputfs_S[tableLength] = { + float inputfs_S[kTableLength] = { 5.3, -5.3, 5.3, -2.9 }; - float inputft_S[tableLength] = { + float inputft_S[kTableLength] = { 4.8, 4.8, -4.8, -0.29 }; @@ -2768,7 +2761,7 @@ TEST(mul) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputfs_S[i]; test.b = inputft_S[i]; test.c = inputfs_D[i]; @@ -2781,7 +2774,7 @@ TEST(mul) { TEST(mov) { - const int tableLength = 4; + const int kTableLength = 4; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); @@ -2795,17 +2788,17 @@ TEST(mov) { }TestFloat; TestFloat test; - double inputs_D[tableLength] = { + double inputs_D[kTableLength] = { 5.3, -5.3, 5.3, -2.9 }; - double inputs_S[tableLength] = { + double inputs_S[kTableLength] = { 4.8, 4.8, -4.8, -0.29 }; - float outputs_S[tableLength] = { + float outputs_S[kTableLength] = { 4.8, 4.8, -4.8, -0.29 }; - double outputs_D[tableLength] = { + double outputs_D[kTableLength] = { 5.3, -5.3, 5.3, -2.9 }; @@ -2823,7 +2816,7 @@ TEST(mov) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.c = inputs_S[i]; @@ -2846,22 +2839,22 @@ TEST(floor_w) { int32_t c; // a floor result int32_t d; // b floor result }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, -3.0, -3.0, -3.0, -4.0, -4.0, -4.0, kFPUInvalidResult, kFPUInvalidResult, @@ -2881,7 +2874,7 @@ TEST(floor_w) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -2903,22 +2896,22 @@ TEST(floor_l) { int64_t c; int64_t d; }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 2.0, 2.0, 2.0, 3.0, 3.0, 3.0, -3.0, -3.0, -3.0, -4.0, -4.0, -4.0, 2147483648.0, dFPU64InvalidResult, @@ -2938,7 +2931,7 @@ TEST(floor_l) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -2960,22 +2953,22 @@ TEST(ceil_w) { int32_t c; // a floor result int32_t d; // b floor result }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, kFPUInvalidResult, kFPUInvalidResult, @@ -2995,7 +2988,7 @@ TEST(ceil_w) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -3017,22 +3010,22 @@ TEST(ceil_l) { int64_t c; int64_t d; }Test; - const int tableLength = 15; - double inputs_D[tableLength] = { + const int kTableLength = 15; + double inputs_D[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::infinity() }; - float inputs_S[tableLength] = { + float inputs_S[kTableLength] = { 2.1, 2.6, 2.5, 3.1, 3.6, 3.5, -2.1, -2.6, -2.5, -3.1, -3.6, -3.5, 2147483648.0, std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::infinity() }; - double outputs[tableLength] = { + double outputs[kTableLength] = { 3.0, 3.0, 3.0, 4.0, 4.0, 4.0, -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, 2147483648.0, dFPU64InvalidResult, @@ -3052,7 +3045,7 @@ TEST(ceil_l) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - for (int i = 0; i < tableLength; i++) { + for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); @@ -3517,6 +3510,8 @@ TEST(class_fmt) { Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); USE(dummy); // Expected double results. + CHECK_EQ(bit_cast<int64_t>(t.dSignalingNan), 0x001); + CHECK_EQ(bit_cast<int64_t>(t.dQuietNan), 0x002); CHECK_EQ(bit_cast<int64_t>(t.dNegInf), 0x004); CHECK_EQ(bit_cast<int64_t>(t.dNegNorm), 0x008); CHECK_EQ(bit_cast<int64_t>(t.dNegSubnorm), 0x010); @@ -3527,6 +3522,8 @@ TEST(class_fmt) { CHECK_EQ(bit_cast<int64_t>(t.dPosZero), 0x200); // Expected float results. + CHECK_EQ(bit_cast<int32_t>(t.fSignalingNan), 0x001); + CHECK_EQ(bit_cast<int32_t>(t.fQuietNan), 0x002); CHECK_EQ(bit_cast<int32_t>(t.fNegInf), 0x004); CHECK_EQ(bit_cast<int32_t>(t.fNegNorm), 0x008); CHECK_EQ(bit_cast<int32_t>(t.fNegSubnorm), 0x010); @@ -5366,4 +5363,104 @@ TEST(r6_balc) { } +uint64_t run_dsll(uint64_t rt_value, uint16_t sa_value) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + + MacroAssembler assm(isolate, NULL, 0); + + __ dsll(v0, a0, sa_value); + __ jr(ra); + __ nop(); + + CodeDesc desc; + assm.GetCode(&desc); + Handle<Code> code = isolate->factory()->NewCode( + desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); + + F2 f = FUNCTION_CAST<F2>(code->entry()); + + uint64_t res = + reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rt_value, 0, 0, 0, 0)); + + return res; +} + + +TEST(dsll) { + CcTest::InitializeVM(); + + struct TestCaseDsll { + uint64_t rt_value; + uint16_t sa_value; + uint64_t expected_res; + }; + + struct TestCaseDsll tc[] = { + // rt_value, sa_value, expected_res + { 0xffffffffffffffff, 0, 0xffffffffffffffff }, + { 0xffffffffffffffff, 16, 0xffffffffffff0000 }, + { 0xffffffffffffffff, 31, 0xffffffff80000000 }, + }; + + size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDsll); + for (size_t i = 0; i < nr_test_cases; ++i) { + CHECK_EQ(tc[i].expected_res, + run_dsll(tc[i].rt_value, tc[i].sa_value)); + } +} + + +uint64_t run_bal(int16_t offset) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + + MacroAssembler assm(isolate, NULL, 0); + + __ mov(t0, ra); + __ bal(offset); // Equivalent for "BGEZAL zero_reg, offset". + __ nop(); + + __ mov(ra, t0); + __ jr(ra); + __ nop(); + + __ li(v0, 1); + __ jr(ra); + __ nop(); + + CodeDesc desc; + assm.GetCode(&desc); + Handle<Code> code = isolate->factory()->NewCode( + desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); + + F2 f = FUNCTION_CAST<F2>(code->entry()); + + uint64_t res = + reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + + return res; +} + + +TEST(bal) { + CcTest::InitializeVM(); + + struct TestCaseBal { + int16_t offset; + uint64_t expected_res; + }; + + struct TestCaseBal tc[] = { + // offset, expected_res + { 4, 1 }, + }; + + size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBal); + for (size_t i = 0; i < nr_test_cases; ++i) { + CHECK_EQ(tc[i].expected_res, run_bal(tc[i].offset)); + } +} + + #undef __ diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc index 3b25480a4a..e35b430555 100644 --- a/deps/v8/test/cctest/test-compiler.cc +++ b/deps/v8/test/cctest/test-compiler.cc @@ -376,7 +376,7 @@ TEST(OptimizedCodeSharing1) { FLAG_cache_optimized_code = true; CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 3; i++) { LocalContext env; env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), v8::Integer::New(CcTest::isolate(), i)); @@ -432,7 +432,65 @@ TEST(OptimizedCodeSharing2) { CHECK(fun0->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); reference_code = handle(fun0->code()); } - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 3; i++) { + LocalContext env; + env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), + v8::Integer::New(CcTest::isolate(), i)); + script->GetUnboundScript()->BindToCurrentContext()->Run(); + CompileRun( + "var closure0 = MakeClosure();" + "%DebugPrint(closure0());" + "%OptimizeFunctionOnNextCall(closure0);" + "%DebugPrint(closure0());" + "var closure1 = MakeClosure();" + "var closure2 = MakeClosure();"); + Handle<JSFunction> fun1 = v8::Utils::OpenHandle( + *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure1")))); + Handle<JSFunction> fun2 = v8::Utils::OpenHandle( + *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure2")))); + CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); + CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); + CHECK_EQ(*reference_code, fun1->code()); + CHECK_EQ(*reference_code, fun2->code()); + } +} + + +// Test that optimized code for different closures is actually shared +// immediately by the FastNewClosureStub without context-dependent entries. +TEST(OptimizedCodeSharing3) { + if (FLAG_stress_compaction) return; + FLAG_allow_natives_syntax = true; + FLAG_cache_optimized_code = true; + FLAG_turbo_cache_shared_code = true; + const char* flag = "--turbo-filter=*"; + FlagList::SetFlagsFromString(flag, StrLength(flag)); + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Script> script = v8_compile( + "function MakeClosure() {" + " return function() { return x; };" + "}"); + Handle<Code> reference_code; + { + LocalContext env; + env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), + v8::Integer::New(CcTest::isolate(), 23)); + script->GetUnboundScript()->BindToCurrentContext()->Run(); + CompileRun( + "var closure0 = MakeClosure();" + "%DebugPrint(closure0());" + "%OptimizeFunctionOnNextCall(closure0);" + "%DebugPrint(closure0());"); + Handle<JSFunction> fun0 = v8::Utils::OpenHandle( + *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure0")))); + CHECK(fun0->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); + reference_code = handle(fun0->code()); + // Evict only the context-dependent entry from the optimized code map. This + // leaves it in a state where only the context-independent entry exists. + fun0->shared()->TrimOptimizedCodeMap(SharedFunctionInfo::kEntryLength); + } + for (int i = 0; i < 3; i++) { LocalContext env; env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), v8::Integer::New(CcTest::isolate(), i)); @@ -566,6 +624,32 @@ TEST(CompileFunctionInContextNonIdentifierArgs) { } +TEST(CompileFunctionInContextScriptOrigin) { + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + LocalContext env; + v8::ScriptOrigin origin(v8_str("test"), + v8::Integer::New(CcTest::isolate(), 22), + v8::Integer::New(CcTest::isolate(), 41)); + v8::ScriptCompiler::Source script_source(v8_str("throw new Error()"), origin); + v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext( + CcTest::isolate(), &script_source, env.local(), 0, NULL, 0, NULL); + CHECK(!fun.IsEmpty()); + v8::TryCatch try_catch; + CcTest::isolate()->SetCaptureStackTraceForUncaughtExceptions(true); + fun->Call(env->Global(), 0, NULL); + CHECK(try_catch.HasCaught()); + CHECK(!try_catch.Exception().IsEmpty()); + v8::Local<v8::StackTrace> stack = + v8::Exception::GetStackTrace(try_catch.Exception()); + CHECK(!stack.IsEmpty()); + CHECK(stack->GetFrameCount() > 0); + v8::Local<v8::StackFrame> frame = stack->GetFrame(0); + CHECK_EQ(23, frame->GetLineNumber()); + CHECK_EQ(42 + strlen("throw "), static_cast<unsigned>(frame->GetColumn())); +} + + #ifdef ENABLE_DISASSEMBLER static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj, const char* property_name) { diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc index e24f6f9050..17eec07376 100644 --- a/deps/v8/test/cctest/test-cpu-profiler.cc +++ b/deps/v8/test/cctest/test-cpu-profiler.cc @@ -31,9 +31,9 @@ #include "include/v8-profiler.h" #include "src/base/platform/platform.h" +#include "src/base/smart-pointers.h" #include "src/cpu-profiler-inl.h" #include "src/deoptimizer.h" -#include "src/smart-pointers.h" #include "src/utils.h" #include "test/cctest/cctest.h" #include "test/cctest/profiler-extension.h" @@ -46,8 +46,8 @@ using i::ProfileGenerator; using i::ProfileNode; using i::ProfilerEventsProcessor; using i::ScopedVector; -using i::SmartPointer; using i::Vector; +using v8::base::SmartPointer; // Helper methods diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc index a6ffdca179..8f569ae6fe 100644 --- a/deps/v8/test/cctest/test-debug.cc +++ b/deps/v8/test/cctest/test-debug.cc @@ -33,7 +33,7 @@ #include "src/base/platform/condition-variable.h" #include "src/base/platform/platform.h" #include "src/compilation-cache.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/deoptimizer.h" #include "src/frames.h" #include "src/utils.h" @@ -52,7 +52,6 @@ using ::v8::internal::Heap; using ::v8::internal::JSGlobalProxy; using ::v8::internal::Code; using ::v8::internal::Debug; -using ::v8::internal::Debugger; using ::v8::internal::CommandMessage; using ::v8::internal::CommandMessageQueue; using ::v8::internal::StackFrame; @@ -155,7 +154,7 @@ static v8::Local<v8::Function> CompileFunction(v8::Isolate* isolate, static bool HasDebugInfo(v8::Handle<v8::Function> fun) { Handle<v8::internal::JSFunction> f = v8::Utils::OpenHandle(*fun); Handle<v8::internal::SharedFunctionInfo> shared(f->shared()); - return Debug::HasDebugInfo(shared); + return shared->HasDebugInfo(); } @@ -412,13 +411,10 @@ void CheckDebuggerUnloaded(bool check_functions) { if (check_functions) { if (obj->IsJSFunction()) { JSFunction* fun = JSFunction::cast(obj); - for (RelocIterator it(fun->shared()->code()); !it.done(); it.next()) { - RelocInfo::Mode rmode = it.rinfo()->rmode(); - if (RelocInfo::IsCodeTarget(rmode)) { - CHECK(!Debug::IsDebugBreak(it.rinfo()->target_address())); - } else if (RelocInfo::IsJSReturn(rmode)) { - CHECK(!it.rinfo()->IsPatchedReturnSequence()); - } + for (RelocIterator it(fun->shared()->code(), + RelocInfo::kDebugBreakSlotMask); + !it.done(); it.next()) { + CHECK(!it.rinfo()->IsPatchedDebugBreakSlotSequence()); } } } @@ -439,61 +435,6 @@ static void CheckDebuggerUnloaded(bool check_functions = false) { } -// Compile a function, set a break point and check that the call at the break -// location in the code is the expected debug_break function. -void CheckDebugBreakFunction(DebugLocalContext* env, - const char* source, const char* name, - int position, v8::internal::RelocInfo::Mode mode, - Code* debug_break) { - EnableDebugger(); - i::Debug* debug = CcTest::i_isolate()->debug(); - - // Create function and set the break point. - Handle<i::JSFunction> fun = - v8::Utils::OpenHandle(*CompileFunction(env, source, name)); - int bp = SetBreakPoint(fun, position); - - // Check that the debug break function is as expected. - Handle<i::SharedFunctionInfo> shared(fun->shared()); - CHECK(Debug::HasDebugInfo(shared)); - i::BreakLocation location = i::BreakLocation::FromPosition( - Debug::GetDebugInfo(shared), i::SOURCE_BREAK_LOCATIONS, position, - i::STATEMENT_ALIGNED); - i::RelocInfo::Mode actual_mode = location.rmode(); - if (actual_mode == i::RelocInfo::CODE_TARGET_WITH_ID) { - actual_mode = i::RelocInfo::CODE_TARGET; - } - CHECK_EQ(mode, actual_mode); - if (mode != i::RelocInfo::JS_RETURN) { - CHECK_EQ(debug_break, *location.CodeTarget()); - } else { - i::RelocInfo rinfo = location.rinfo(); - CHECK(i::RelocInfo::IsJSReturn(rinfo.rmode())); - CHECK(rinfo.IsPatchedReturnSequence()); - } - - // Clear the break point and check that the debug break function is no longer - // there - ClearBreakPoint(bp); - CHECK(!debug->HasDebugInfo(shared)); - CHECK(debug->EnsureDebugInfo(shared, fun)); - location = i::BreakLocation::FromPosition(Debug::GetDebugInfo(shared), - i::SOURCE_BREAK_LOCATIONS, position, - i::STATEMENT_ALIGNED); - actual_mode = location.rmode(); - if (actual_mode == i::RelocInfo::CODE_TARGET_WITH_ID) { - actual_mode = i::RelocInfo::CODE_TARGET; - } - CHECK_EQ(mode, actual_mode); - if (mode == i::RelocInfo::JS_RETURN) { - i::RelocInfo rinfo = location.rinfo(); - CHECK(!rinfo.IsPatchedReturnSequence()); - } - - DisableDebugger(); -} - - // --- D e b u g E v e n t H a n d l e r s // --- // --- The different tests uses a number of debug event handlers. @@ -911,7 +852,6 @@ bool terminate_after_max_break_point_hit = false; static void DebugEventBreakMax( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); - v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); v8::Isolate* v8_isolate = CcTest::isolate(); v8::internal::Isolate* isolate = CcTest::i_isolate(); v8::internal::Debug* debug = isolate->debug(); @@ -923,17 +863,6 @@ static void DebugEventBreakMax( // Count the number of breaks. break_point_hit_count++; - // Collect the JavsScript stack height if the function frame_count is - // compiled. - if (!frame_count.IsEmpty()) { - static const int kArgc = 1; - v8::Handle<v8::Value> argv[kArgc] = { exec_state }; - // Using exec_state as receiver is just to have a receiver. - v8::Handle<v8::Value> result = - frame_count->Call(exec_state, kArgc, argv); - last_js_stack_height = result->Int32Value(); - } - // Set the break flag again to come back here as soon as possible. v8::Debug::DebugBreak(v8_isolate); @@ -7145,15 +7074,22 @@ TEST(DebugBreakStackInspection) { static void TestDebugBreakInLoop(const char* loop_head, const char** loop_bodies, const char* loop_tail) { - // Receive 100 breaks for each test and then terminate JavaScript execution. - static const int kBreaksPerTest = 100; + // Receive 10 breaks for each test and then terminate JavaScript execution. + static const int kBreaksPerTest = 10; 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 < 7; j++) { + + EmbeddedVector<char, 1024> buffer; + SNPrintF(buffer, "function f() {%s%s%s}", loop_head, loop_bodies[i], + loop_tail); + + i::PrintF("%s\n", buffer.start()); + + for (int j = 0; j < 3; j++) { break_point_hit_count_deoptimize = j; - if (j == 6) { + if (j == 2) { break_point_hit_count_deoptimize = kBreaksPerTest; } @@ -7161,11 +7097,6 @@ static void TestDebugBreakInLoop(const char* loop_head, max_break_point_hit_count = kBreaksPerTest; terminate_after_max_break_point_hit = true; - EmbeddedVector<char, 1024> buffer; - SNPrintF(buffer, - "function f() {%s%s%s}", - loop_head, loop_bodies[i], loop_tail); - // Function with infinite loop. CompileRun(buffer.start()); @@ -7182,43 +7113,38 @@ static void TestDebugBreakInLoop(const char* loop_head, } -TEST(DebugBreakLoop) { +static const char* loop_bodies_1[] = {"", + "g()", + "if (a == 0) { g() }", + "if (a == 1) { g() }", + "if (a == 0) { g() } else { h() }", + "if (a == 0) { continue }", + NULL}; + + +static const char* loop_bodies_2[] = { + "if (a == 1) { continue }", + "switch (a) { case 1: g(); }", + "switch (a) { case 1: continue; }", + "switch (a) { case 1: g(); break; default: h() }", + "switch (a) { case 1: continue; break; default: h() }", + NULL}; + + +void DebugBreakLoop(const char* loop_header, const char** loop_bodies, + const char* loop_footer) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); // Register a debug event listener which sets the break flag and counts. v8::Debug::SetDebugEventListener(DebugEventBreakMax); - // Create a function for getting the frame count when hitting the break. - frame_count = CompileFunction(&env, frame_count_source, "frame_count"); - - CompileRun("var a = 1;"); - CompileRun("function g() { }"); - CompileRun("function h() { }"); - - const char* loop_bodies[] = { - "", - "g()", - "if (a == 0) { g() }", - "if (a == 1) { g() }", - "if (a == 0) { g() } else { h() }", - "if (a == 0) { continue }", - "if (a == 1) { continue }", - "switch (a) { case 1: g(); }", - "switch (a) { case 1: continue; }", - "switch (a) { case 1: g(); break; default: h() }", - "switch (a) { case 1: continue; break; default: h() }", - NULL - }; - - TestDebugBreakInLoop("while (true) {", loop_bodies, "}"); - TestDebugBreakInLoop("while (a == 1) {", loop_bodies, "}"); - - TestDebugBreakInLoop("do {", loop_bodies, "} while (true)"); - TestDebugBreakInLoop("do {", loop_bodies, "} while (a == 1)"); + CompileRun( + "var a = 1;\n" + "function g() { }\n" + "function h() { }"); - TestDebugBreakInLoop("for (;;) {", loop_bodies, "}"); - TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}"); + TestDebugBreakInLoop(loop_header, loop_bodies, loop_footer); // Get rid of the debug event listener. v8::Debug::SetDebugEventListener(NULL); @@ -7226,6 +7152,62 @@ TEST(DebugBreakLoop) { } +TEST(DebugBreakInWhileTrue1) { + DebugBreakLoop("while (true) {", loop_bodies_1, "}"); +} + + +TEST(DebugBreakInWhileTrue2) { + DebugBreakLoop("while (true) {", loop_bodies_2, "}"); +} + + +TEST(DebugBreakInWhileCondition1) { + DebugBreakLoop("while (a == 1) {", loop_bodies_1, "}"); +} + + +TEST(DebugBreakInWhileCondition2) { + DebugBreakLoop("while (a == 1) {", loop_bodies_2, "}"); +} + + +TEST(DebugBreakInDoWhileTrue1) { + DebugBreakLoop("do {", loop_bodies_1, "} while (true)"); +} + + +TEST(DebugBreakInDoWhileTrue2) { + DebugBreakLoop("do {", loop_bodies_2, "} while (true)"); +} + + +TEST(DebugBreakInDoWhileCondition1) { + DebugBreakLoop("do {", loop_bodies_1, "} while (a == 1)"); +} + + +TEST(DebugBreakInDoWhileCondition2) { + DebugBreakLoop("do {", loop_bodies_2, "} while (a == 1)"); +} + + +TEST(DebugBreakInFor1) { DebugBreakLoop("for (;;) {", loop_bodies_1, "}"); } + + +TEST(DebugBreakInFor2) { DebugBreakLoop("for (;;) {", loop_bodies_2, "}"); } + + +TEST(DebugBreakInForCondition1) { + DebugBreakLoop("for (;a == 1;) {", loop_bodies_1, "}"); +} + + +TEST(DebugBreakInForCondition2) { + DebugBreakLoop("for (;a == 1;) {", loop_bodies_2, "}"); +} + + v8::Local<v8::Script> inline_script; static void DebugBreakInlineListener( @@ -7331,7 +7313,12 @@ TEST(Regress131642) { // Import from test-heap.cc +namespace v8 { +namespace internal { + int CountNativeContexts(); +} +} static void NopListener(const v8::Debug::EventDetails& event_details) { @@ -7341,15 +7328,15 @@ static void NopListener(const v8::Debug::EventDetails& event_details) { TEST(DebuggerCreatesContextIffActive) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - CHECK_EQ(1, CountNativeContexts()); + CHECK_EQ(1, v8::internal::CountNativeContexts()); v8::Debug::SetDebugEventListener(NULL); CompileRun("debugger;"); - CHECK_EQ(1, CountNativeContexts()); + CHECK_EQ(1, v8::internal::CountNativeContexts()); v8::Debug::SetDebugEventListener(NopListener); CompileRun("debugger;"); - CHECK_EQ(2, CountNativeContexts()); + CHECK_EQ(2, v8::internal::CountNativeContexts()); v8::Debug::SetDebugEventListener(NULL); } @@ -7637,3 +7624,27 @@ TEST(DebugBreakInLexicalScopes) { "x * y", 30); } + +static int after_compile_handler_depth = 0; +static void HandleInterrupt(v8::Isolate* isolate, void* data) { + CHECK_EQ(0, after_compile_handler_depth); +} + +static void NoInterruptsOnDebugEvent( + const v8::Debug::EventDetails& event_details) { + if (event_details.GetEvent() != v8::AfterCompile) return; + ++after_compile_handler_depth; + // Do not allow nested AfterCompile events. + CHECK(after_compile_handler_depth <= 1); + v8::Isolate* isolate = event_details.GetEventContext()->GetIsolate(); + isolate->RequestInterrupt(&HandleInterrupt, nullptr); + CompileRun("function foo() {}; foo();"); + --after_compile_handler_depth; +} + + +TEST(NoInterruptsInDebugListener) { + DebugLocalContext env; + v8::Debug::SetDebugEventListener(NoInterruptsOnDebugEvent); + CompileRun("void(0);"); +} diff --git a/deps/v8/test/cctest/test-deoptimization.cc b/deps/v8/test/cctest/test-deoptimization.cc index 1d512e0a75..20c1913923 100644 --- a/deps/v8/test/cctest/test-deoptimization.cc +++ b/deps/v8/test/cctest/test-deoptimization.cc @@ -32,7 +32,7 @@ #include "src/api.h" #include "src/base/platform/platform.h" #include "src/compilation-cache.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/deoptimizer.h" #include "src/isolate.h" #include "test/cctest/cctest.h" diff --git a/deps/v8/test/cctest/test-dictionary.cc b/deps/v8/test/cctest/test-dictionary.cc index 03f3c27d51..dc8a8b5bed 100644 --- a/deps/v8/test/cctest/test-dictionary.cc +++ b/deps/v8/test/cctest/test-dictionary.cc @@ -29,7 +29,7 @@ #include "test/cctest/cctest.h" #include "src/api.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/execution.h" #include "src/factory.h" #include "src/global-handles.h" diff --git a/deps/v8/test/cctest/test-disasm-arm.cc b/deps/v8/test/cctest/test-disasm-arm.cc index cc5e89f1fd..b3b8a0358e 100644 --- a/deps/v8/test/cctest/test-disasm-arm.cc +++ b/deps/v8/test/cctest/test-disasm-arm.cc @@ -30,7 +30,7 @@ #include "src/v8.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/disasm.h" #include "src/disassembler.h" #include "src/macro-assembler.h" diff --git a/deps/v8/test/cctest/test-disasm-arm64.cc b/deps/v8/test/cctest/test-disasm-arm64.cc index b3b50acf9d..643a3c1bdb 100644 --- a/deps/v8/test/cctest/test-disasm-arm64.cc +++ b/deps/v8/test/cctest/test-disasm-arm64.cc @@ -1249,25 +1249,6 @@ TEST_(load_store_pair) { } -TEST_(load_store_pair_nontemp) { - SET_UP(); - - COMPARE(ldnp(w0, w1, MemOperand(x2)), "ldnp w0, w1, [x2]"); - COMPARE(stnp(w3, w4, MemOperand(x5, 252)), "stnp w3, w4, [x5, #252]"); - COMPARE(ldnp(w6, w7, MemOperand(x8, -256)), "ldnp w6, w7, [x8, #-256]"); - COMPARE(stnp(x9, x10, MemOperand(x11)), "stnp x9, x10, [x11]"); - COMPARE(ldnp(x12, x13, MemOperand(x14, 504)), "ldnp x12, x13, [x14, #504]"); - COMPARE(stnp(x15, x16, MemOperand(x17, -512)), "stnp x15, x16, [x17, #-512]"); - COMPARE(ldnp(s18, s19, MemOperand(x20)), "ldnp s18, s19, [x20]"); - COMPARE(stnp(s21, s22, MemOperand(x23, 252)), "stnp s21, s22, [x23, #252]"); - COMPARE(ldnp(s24, s25, MemOperand(x26, -256)), "ldnp s24, s25, [x26, #-256]"); - COMPARE(stnp(d27, d28, MemOperand(fp)), "stnp d27, d28, [fp]"); - COMPARE(ldnp(d30, d31, MemOperand(x0, 504)), "ldnp d30, d31, [x0, #504]"); - COMPARE(stnp(d1, d2, MemOperand(x3, -512)), "stnp d1, d2, [x3, #-512]"); - - CLEANUP(); -} - #if 0 // TODO(all): enable. TEST_(load_literal) { SET_UP(); diff --git a/deps/v8/test/cctest/test-disasm-ia32.cc b/deps/v8/test/cctest/test-disasm-ia32.cc index aeaa99538b..669e37ac69 100644 --- a/deps/v8/test/cctest/test-disasm-ia32.cc +++ b/deps/v8/test/cctest/test-disasm-ia32.cc @@ -29,9 +29,10 @@ #include "src/v8.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/disasm.h" #include "src/disassembler.h" +#include "src/ia32/frames-ia32.h" #include "src/ic/ic.h" #include "src/macro-assembler.h" #include "test/cctest/cctest.h" @@ -287,7 +288,7 @@ TEST(DisasmIa320) { __ bind(&L2); __ call(Operand(ebx, ecx, times_4, 10000)); __ nop(); - Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL)); + Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_INSIDE_TYPEOF)); __ call(ic, RelocInfo::CODE_TARGET); __ nop(); __ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY); diff --git a/deps/v8/test/cctest/test-disasm-mips.cc b/deps/v8/test/cctest/test-disasm-mips.cc index c04cd23bf5..6895ebf5d4 100644 --- a/deps/v8/test/cctest/test-disasm-mips.cc +++ b/deps/v8/test/cctest/test-disasm-mips.cc @@ -30,7 +30,7 @@ #include "src/v8.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/disasm.h" #include "src/disassembler.h" #include "src/macro-assembler.h" @@ -98,7 +98,7 @@ if (failure) { \ byte *progcounter = &buffer[pc_offset]; \ char str_with_address[100]; \ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \ - compare_string, progcounter + 4 + (offset << 2)); \ + compare_string, progcounter + 4 + (offset * 4)); \ assm.asm_; \ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \ } @@ -110,7 +110,7 @@ if (failure) { \ byte *progcounter = &buffer[pc_offset]; \ char str_with_address[100]; \ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \ - compare_string, progcounter + (offset << 2)); \ + compare_string, progcounter + (offset * 4)); \ assm.asm_; \ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \ } @@ -121,16 +121,25 @@ if (failure) { \ int pc_offset = assm.pc_offset(); \ byte *progcounter = &buffer[pc_offset]; \ char str_with_address[100]; \ - int instr_index = target >> 2; \ - snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \ - compare_string, reinterpret_cast<byte *>( \ - ((uint32_t)(progcounter + 1) & ~0xfffffff) | \ + int instr_index = (target >> 2) & kImm26Mask; \ + snprintf( \ + str_with_address, sizeof(str_with_address), "%s %p -> %p", \ + compare_string, reinterpret_cast<byte *>(target), \ + reinterpret_cast<byte *>(((uint32_t)(progcounter + 4) & ~0xfffffff) | \ (instr_index << 2))); \ assm.asm_; \ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \ } +#define GET_PC_REGION(pc_region) \ + { \ + int pc_offset = assm.pc_offset(); \ + byte *progcounter = &buffer[pc_offset]; \ + pc_region = reinterpret_cast<int32_t>(progcounter + 4) & ~0xfffffff; \ + } + + TEST(Type0) { SET_UP(); @@ -466,12 +475,18 @@ TEST(Type0) { COMPARE_PC_REL_COMPACT(bgtz(a0, 32767), "1c807fff bgtz a0, 32767", 32767); - COMPARE_PC_JUMP(j(0x4), "08000001 j 0x4", 0x4); - COMPARE_PC_JUMP(j(0xffffffc), "0bffffff j 0xffffffc", 0xffffffc); + int32_t pc_region; + GET_PC_REGION(pc_region); + + int32_t target = pc_region | 0x4; + COMPARE_PC_JUMP(j(target), "08000001 j ", target); + target = pc_region | 0xffffffc; + COMPARE_PC_JUMP(j(target), "0bffffff j ", target); - COMPARE_PC_JUMP(jal(0x4), "0c000001 jal 0x4", 0x4); - COMPARE_PC_JUMP(jal(0xffffffc), "0fffffff jal 0xffffffc", - 0xffffffc); + target = pc_region | 0x4; + COMPARE_PC_JUMP(jal(target), "0c000001 jal ", target); + target = pc_region | 0xffffffc; + COMPARE_PC_JUMP(jal(target), "0fffffff jal ", target); COMPARE(addiu(a0, a1, 0x0), "24a40000 addiu a0, a1, 0"); diff --git a/deps/v8/test/cctest/test-disasm-mips64.cc b/deps/v8/test/cctest/test-disasm-mips64.cc index 225a1e7f0b..7cf6397886 100644 --- a/deps/v8/test/cctest/test-disasm-mips64.cc +++ b/deps/v8/test/cctest/test-disasm-mips64.cc @@ -30,7 +30,7 @@ #include "src/v8.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/disasm.h" #include "src/disassembler.h" #include "src/macro-assembler.h" @@ -98,7 +98,7 @@ if (failure) { \ byte *progcounter = &buffer[pc_offset]; \ char str_with_address[100]; \ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \ - compare_string, progcounter + 4 + (offset << 2)); \ + compare_string, progcounter + 4 + (offset * 4)); \ assm.asm_; \ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \ } @@ -110,7 +110,7 @@ if (failure) { \ byte *progcounter = &buffer[pc_offset]; \ char str_with_address[100]; \ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \ - compare_string, progcounter + (offset << 2)); \ + compare_string, progcounter + (offset * 4)); \ assm.asm_; \ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \ } @@ -121,16 +121,25 @@ if (failure) { \ int pc_offset = assm.pc_offset(); \ byte *progcounter = &buffer[pc_offset]; \ char str_with_address[100]; \ - int instr_index = target >> 2; \ - snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \ - compare_string, reinterpret_cast<byte *>( \ - ((uint64_t)(progcounter + 1) & ~0xfffffff) | \ + int instr_index = (target >> 2) & kImm26Mask; \ + snprintf( \ + str_with_address, sizeof(str_with_address), "%s %p -> %p", \ + compare_string, reinterpret_cast<byte *>(target), \ + reinterpret_cast<byte *>(((uint64_t)(progcounter + 1) & ~0xfffffff) | \ (instr_index << 2))); \ assm.asm_; \ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \ } +#define GET_PC_REGION(pc_region) \ + { \ + int pc_offset = assm.pc_offset(); \ + byte *progcounter = &buffer[pc_offset]; \ + pc_region = reinterpret_cast<int64_t>(progcounter + 4) & ~0xfffffff; \ + } + + TEST(Type0) { SET_UP(); @@ -1114,12 +1123,18 @@ TEST(Type3) { COMPARE_PC_REL_COMPACT(bgtz(a0, 32767), "1c807fff bgtz a0, 32767", 32767); - COMPARE_PC_JUMP(j(0x4), "08000001 j 0x4", 0x4); - COMPARE_PC_JUMP(j(0xffffffc), "0bffffff j 0xffffffc", 0xffffffc); + int64_t pc_region; + GET_PC_REGION(pc_region); + + int64_t target = pc_region | 0x4; + COMPARE_PC_JUMP(j(target), "08000001 j ", target); + target = pc_region | 0xffffffc; + COMPARE_PC_JUMP(j(target), "0bffffff j ", target); - COMPARE_PC_JUMP(jal(0x4), "0c000001 jal 0x4", 0x4); - COMPARE_PC_JUMP(jal(0xffffffc), "0fffffff jal 0xffffffc", - 0xffffffc); + target = pc_region | 0x4; + COMPARE_PC_JUMP(jal(target), "0c000001 jal ", target); + target = pc_region | 0xffffffc; + COMPARE_PC_JUMP(jal(target), "0fffffff jal ", target); VERIFY_RUN(); } diff --git a/deps/v8/test/cctest/test-disasm-ppc.cc b/deps/v8/test/cctest/test-disasm-ppc.cc index ed409f2f9d..e4b434ffb1 100644 --- a/deps/v8/test/cctest/test-disasm-ppc.cc +++ b/deps/v8/test/cctest/test-disasm-ppc.cc @@ -30,7 +30,7 @@ #include "src/v8.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/disasm.h" #include "src/disassembler.h" #include "src/macro-assembler.h" @@ -107,8 +107,8 @@ TEST(DisasmPPC) { COMPARE(and_(r6, r0, r6, SetRC), "7c063039 and. r6, r0, r6"); // skipping branches (for now?) COMPARE(bctr(), "4e800420 bctr"); + COMPARE(bctrl(), "4e800421 bctrl"); COMPARE(blr(), "4e800020 blr"); - COMPARE(bclr(BA, SetLK), "4e800021 blrl"); // skipping call - only used in simulator #if V8_TARGET_ARCH_PPC64 COMPARE(cmpi(r0, Operand(5)), "2fa00005 cmpi r0, 5"); diff --git a/deps/v8/test/cctest/test-disasm-x64.cc b/deps/v8/test/cctest/test-disasm-x64.cc index bcfe507b25..980f5d5b0f 100644 --- a/deps/v8/test/cctest/test-disasm-x64.cc +++ b/deps/v8/test/cctest/test-disasm-x64.cc @@ -29,7 +29,7 @@ #include "src/v8.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/disasm.h" #include "src/disassembler.h" #include "src/ic/ic.h" @@ -282,7 +282,7 @@ TEST(DisasmX64) { // TODO(mstarzinger): The following is protected. // __ call(Operand(rbx, rcx, times_4, 10000)); __ nop(); - Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL)); + Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_INSIDE_TYPEOF)); __ call(ic, RelocInfo::CODE_TARGET); __ nop(); __ nop(); diff --git a/deps/v8/test/cctest/test-disasm-x87.cc b/deps/v8/test/cctest/test-disasm-x87.cc index a3433b290b..17609cfc3c 100644 --- a/deps/v8/test/cctest/test-disasm-x87.cc +++ b/deps/v8/test/cctest/test-disasm-x87.cc @@ -29,11 +29,12 @@ #include "src/v8.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/disasm.h" #include "src/disassembler.h" #include "src/ic/ic.h" #include "src/macro-assembler.h" +#include "src/x87/frames-x87.h" #include "test/cctest/cctest.h" using namespace v8::internal; @@ -287,7 +288,7 @@ TEST(DisasmIa320) { __ bind(&L2); __ call(Operand(ebx, ecx, times_4, 10000)); __ nop(); - Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_CONTEXTUAL)); + Handle<Code> ic(LoadIC::initialize_stub(isolate, NOT_INSIDE_TYPEOF)); __ call(ic, RelocInfo::CODE_TARGET); __ nop(); __ call(FUNCTION_ADDR(DummyStaticFunction), RelocInfo::RUNTIME_ENTRY); diff --git a/deps/v8/test/cctest/test-extra.js b/deps/v8/test/cctest/test-extra.js index 829ddee01a..f943ea6c4e 100644 --- a/deps/v8/test/cctest/test-extra.js +++ b/deps/v8/test/cctest/test-extra.js @@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -(function (global, exports) { +(function (global, binding) { 'use strict'; - exports.testExtraShouldReturnFive = function () { + binding.testExtraShouldReturnFive = function () { return 5; }; - exports.testExtraShouldCallToRuntime = function() { - return exports.runtime(3); + binding.testExtraShouldCallToRuntime = function() { + return binding.runtime(3); }; }) diff --git a/deps/v8/test/cctest/test-feedback-vector.cc b/deps/v8/test/cctest/test-feedback-vector.cc index cf8a730fb7..b982c0f02b 100644 --- a/deps/v8/test/cctest/test-feedback-vector.cc +++ b/deps/v8/test/cctest/test-feedback-vector.cc @@ -6,7 +6,7 @@ #include "test/cctest/cctest.h" #include "src/api.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/execution.h" #include "src/factory.h" #include "src/global-handles.h" @@ -40,7 +40,8 @@ TEST(VectorStructure) { CHECK_EQ(1, vector->Slots()); CHECK_EQ(0, vector->ICSlots()); - FeedbackVectorSpec one_icslot(0, Code::CALL_IC); + ZoneFeedbackVectorSpec one_icslot(zone, 0, 1); + one_icslot.SetKind(0, Code::CALL_IC); vector = factory->NewTypeFeedbackVector(&one_icslot); CHECK_EQ(0, vector->Slots()); CHECK_EQ(1, vector->ICSlots()); @@ -385,4 +386,101 @@ TEST(VectorLoadICOnSmi) { nexus.FindAllMaps(&maps2); CHECK_EQ(2, maps2.length()); } + + +static Handle<JSFunction> GetFunction(const char* name) { + Handle<JSFunction> f = v8::Utils::OpenHandle( + *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str(name)))); + return f; +} + + +TEST(ReferenceContextAllocatesNoSlots) { + if (i::FLAG_always_opt) return; + CcTest::InitializeVM(); + LocalContext context; + v8::HandleScope scope(context->GetIsolate()); + Isolate* isolate = CcTest::i_isolate(); + + CompileRun( + "function testvar(x) {" + " y = x;" + " y = a;" + " return y;" + "}" + "a = 3;" + "testvar({});"); + + Handle<JSFunction> f = GetFunction("testvar"); + + // There should be two LOAD_ICs, one for a and one for y at the end. + Handle<TypeFeedbackVector> feedback_vector = + handle(f->shared()->feedback_vector(), isolate); + CHECK_EQ(2, feedback_vector->ICSlots()); + CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::LOAD_IC); + CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::LOAD_IC); + + CompileRun( + "function testprop(x) {" + " x.blue = a;" + "}" + "testprop({ blue: 3 });"); + + f = GetFunction("testprop"); + + // There should be one LOAD_IC, for the load of a. + feedback_vector = handle(f->shared()->feedback_vector(), isolate); + CHECK_EQ(1, feedback_vector->ICSlots()); + + CompileRun( + "function testpropfunc(x) {" + " x().blue = a;" + " return x().blue;" + "}" + "function makeresult() { return { blue: 3 }; }" + "testpropfunc(makeresult);"); + + f = GetFunction("testpropfunc"); + + // There should be 2 LOAD_ICs and 2 CALL_ICs. + feedback_vector = handle(f->shared()->feedback_vector(), isolate); + CHECK_EQ(4, feedback_vector->ICSlots()); + CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::CALL_IC); + CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::LOAD_IC); + CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) == Code::CALL_IC); + CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(3)) == Code::LOAD_IC); + + CompileRun( + "function testkeyedprop(x) {" + " x[0] = a;" + " return x[0];" + "}" + "testkeyedprop([0, 1, 2]);"); + + f = GetFunction("testkeyedprop"); + + // There should be 1 LOAD_ICs for the load of a, and one KEYED_LOAD_IC for the + // load of x[0] in the return statement. + feedback_vector = handle(f->shared()->feedback_vector(), isolate); + CHECK_EQ(2, feedback_vector->ICSlots()); + CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::LOAD_IC); + CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == + Code::KEYED_LOAD_IC); + + CompileRun( + "function testcompound(x) {" + " x.old = x.young = x.in_between = a;" + " return x.old + x.young;" + "}" + "testcompound({ old: 3, young: 3, in_between: 3 });"); + + f = GetFunction("testcompound"); + + // There should be 3 LOAD_ICs, for load of a and load of x.old and x.young. + feedback_vector = handle(f->shared()->feedback_vector(), isolate); + CHECK_EQ(3, feedback_vector->ICSlots()); + CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(0)) == Code::LOAD_IC); + CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(1)) == Code::LOAD_IC); + CHECK(feedback_vector->GetKind(FeedbackVectorICSlot(2)) == Code::LOAD_IC); +} } diff --git a/deps/v8/test/cctest/test-func-name-inference.cc b/deps/v8/test/cctest/test-func-name-inference.cc index ae8e77d745..6c7aa030bc 100644 --- a/deps/v8/test/cctest/test-func-name-inference.cc +++ b/deps/v8/test/cctest/test-func-name-inference.cc @@ -29,11 +29,12 @@ #include "src/v8.h" #include "src/api.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/string-search.h" #include "test/cctest/cctest.h" +using ::v8::base::SmartArrayPointer; using ::v8::internal::CStrVector; using ::v8::internal::Factory; using ::v8::internal::Handle; @@ -43,7 +44,6 @@ using ::v8::internal::JSFunction; using ::v8::internal::Object; using ::v8::internal::Runtime; using ::v8::internal::Script; -using ::v8::internal::SmartArrayPointer; using ::v8::internal::SharedFunctionInfo; using ::v8::internal::String; using ::v8::internal::Vector; @@ -80,7 +80,6 @@ static void CheckFunctionName(v8::Handle<v8::Script> script, CHECK_NE(0, func_pos); // Obtain SharedFunctionInfo for the function. - isolate->debug()->PrepareForBreakPoints(); Handle<SharedFunctionInfo> shared_func_info = Handle<SharedFunctionInfo>::cast( isolate->debug()->FindSharedFunctionInfoInScript(i_script, func_pos)); @@ -88,6 +87,8 @@ static void CheckFunctionName(v8::Handle<v8::Script> script, // Verify inferred function name. SmartArrayPointer<char> inferred_name = shared_func_info->inferred_name()->ToCString(); + i::PrintF("expected: %s, found: %s\n", ref_inferred_name, + inferred_name.get()); CHECK_EQ(0, strcmp(ref_inferred_name, inferred_name.get())); } @@ -223,6 +224,44 @@ TEST(ObjectLiteral) { } +TEST(UpperCaseClass) { + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + v8::Handle<v8::Script> script = Compile(CcTest::isolate(), + "'use strict';\n" + "class MyClass {\n" + " constructor() {\n" + " this.value = 1;\n" + " }\n" + " method() {\n" + " this.value = 2;\n" + " }\n" + "}"); + CheckFunctionName(script, "this.value = 1", "MyClass"); + CheckFunctionName(script, "this.value = 2", "MyClass.method"); +} + + +TEST(LowerCaseClass) { + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + v8::Handle<v8::Script> script = Compile(CcTest::isolate(), + "'use strict';\n" + "class myclass {\n" + " constructor() {\n" + " this.value = 1;\n" + " }\n" + " method() {\n" + " this.value = 2;\n" + " }\n" + "}"); + CheckFunctionName(script, "this.value = 1", "myclass"); + CheckFunctionName(script, "this.value = 2", "myclass.method"); +} + + TEST(AsParameter) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); diff --git a/deps/v8/test/cctest/test-global-handles.cc b/deps/v8/test/cctest/test-global-handles.cc index ee295d6991..20aaeac73e 100644 --- a/deps/v8/test/cctest/test-global-handles.cc +++ b/deps/v8/test/cctest/test-global-handles.cc @@ -380,3 +380,20 @@ TEST(EternalHandles) { CHECK_EQ(2*kArrayLength + 1, eternal_handles->NumberOfHandles()); } + + +TEST(PersistentBaseGetLocal) { + CcTest::InitializeVM(); + v8::Isolate* isolate = CcTest::isolate(); + + v8::HandleScope scope(isolate); + v8::Local<v8::Object> o = v8::Object::New(isolate); + CHECK(!o.IsEmpty()); + v8::Persistent<v8::Object> p(isolate, o); + CHECK(o == p.Get(isolate)); + CHECK(v8::Local<v8::Object>::New(isolate, p) == p.Get(isolate)); + + v8::Global<v8::Object> g(isolate, o); + CHECK(o == g.Get(isolate)); + CHECK(v8::Local<v8::Object>::New(isolate, g) == g.Get(isolate)); +} diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc index 4416f38973..f4c8c1a486 100644 --- a/deps/v8/test/cctest/test-heap-profiler.cc +++ b/deps/v8/test/cctest/test-heap-profiler.cc @@ -33,9 +33,10 @@ #include "include/v8-profiler.h" #include "src/allocation-tracker.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/hashmap.h" #include "src/heap-profiler.h" +#include "src/heap-snapshot-generator-inl.h" #include "test/cctest/cctest.h" using i::AllocationTraceNode; @@ -95,10 +96,11 @@ class NamedEntriesDetector { static const v8::HeapGraphNode* GetGlobalObject( const v8::HeapSnapshot* snapshot) { - CHECK_EQ(2, snapshot->GetRoot()->GetChildrenCount()); - // The 0th-child is (GC Roots), 1st is the user root. + CHECK_EQ(3, snapshot->GetRoot()->GetChildrenCount()); + // The 0th-child is (GC Roots), 1st is code stubs context, 2nd is the user + // root. const v8::HeapGraphNode* global_obj = - snapshot->GetRoot()->GetChild(1)->GetToNode(); + snapshot->GetRoot()->GetChild(2)->GetToNode(); CHECK_EQ(0, strncmp("Object", const_cast<i::HeapEntry*>( reinterpret_cast<const i::HeapEntry*>(global_obj))->name(), 6)); return global_obj; @@ -481,6 +483,34 @@ TEST(HeapSnapshotSymbol) { } +void CheckSimdSnapshot(const char* program, const char* var_name) { + i::FLAG_harmony_simd = true; + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); + + CompileRun(program); + const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot(); + CHECK(ValidateSnapshot(snapshot)); + const v8::HeapGraphNode* global = GetGlobalObject(snapshot); + const v8::HeapGraphNode* var = + GetProperty(global, v8::HeapGraphEdge::kProperty, var_name); + CHECK(var); + CHECK_EQ(var->GetType(), v8::HeapGraphNode::kSimdValue); +} + + +TEST(HeapSnapshotSimd) { + CheckSimdSnapshot("a = SIMD.Float32x4();\n", "a"); + CheckSimdSnapshot("a = SIMD.Int32x4();\n", "a"); + CheckSimdSnapshot("a = SIMD.Bool32x4();\n", "a"); + CheckSimdSnapshot("a = SIMD.Int16x8();\n", "a"); + CheckSimdSnapshot("a = SIMD.Bool16x8();\n", "a"); + CheckSimdSnapshot("a = SIMD.Int8x16();\n", "a"); + CheckSimdSnapshot("a = SIMD.Bool8x16();\n", "a"); +} + + TEST(HeapSnapshotWeakCollection) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -960,7 +990,7 @@ TEST(HeapSnapshotJSONSerialization) { v8::Local<v8::String> ref_string = CompileRun(STRING_LITERAL_FOR_TEST)->ToString(isolate); #undef STRING_LITERAL_FOR_TEST - CHECK_EQ(0, strcmp(*v8::String::Utf8Value(ref_string), + CHECK_LT(0, strcmp(*v8::String::Utf8Value(ref_string), *v8::String::Utf8Value(string))); } @@ -1768,7 +1798,7 @@ TEST(GetHeapValueForDeletedObject) { static int StringCmp(const char* ref, i::String* act) { - i::SmartArrayPointer<char> s_act = act->ToCString(); + v8::base::SmartArrayPointer<char> s_act = act->ToCString(); int result = strcmp(ref, s_act.get()); if (result != 0) fprintf(stderr, "Expected: \"%s\", Actual: \"%s\"\n", ref, s_act.get()); @@ -2082,6 +2112,7 @@ TEST(NoDebugObjectInSnapshot) { CHECK(ValidateSnapshot(snapshot)); const v8::HeapGraphNode* root = snapshot->GetRoot(); int globals_count = 0; + bool found = false; for (int i = 0; i < root->GetChildrenCount(); ++i) { const v8::HeapGraphEdge* edge = root->GetChild(i); if (edge->GetType() == v8::HeapGraphEdge::kShortcut) { @@ -2089,10 +2120,13 @@ TEST(NoDebugObjectInSnapshot) { const v8::HeapGraphNode* global = edge->GetToNode(); const v8::HeapGraphNode* foo = GetProperty(global, v8::HeapGraphEdge::kProperty, "foo"); - CHECK(foo); + if (foo != nullptr) { + found = true; + } } } - CHECK_EQ(1, globals_count); + CHECK_EQ(2, globals_count); + CHECK(found); } diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc index 848c768860..5d568e25c1 100644 --- a/deps/v8/test/cctest/test-heap.cc +++ b/deps/v8/test/cctest/test-heap.cc @@ -31,6 +31,7 @@ #include "src/v8.h" #include "src/compilation-cache.h" +#include "src/context-measure.h" #include "src/deoptimizer.h" #include "src/execution.h" #include "src/factory.h" @@ -40,9 +41,32 @@ #include "src/snapshot/snapshot.h" #include "test/cctest/cctest.h" -using namespace v8::internal; using v8::Just; +namespace v8 { +namespace internal { + +// Tests that should have access to private methods of {v8::internal::Heap}. +// Those tests need to be defined using HEAP_TEST(Name) { ... }. +#define HEAP_TEST_METHODS(V) \ + V(GCFlags) + + +#define HEAP_TEST(Name) \ + CcTest register_test_##Name(HeapTester::Test##Name, __FILE__, #Name, NULL, \ + true, true); \ + void HeapTester::Test##Name() + + +class HeapTester { + public: +#define DECLARE_STATIC(Name) static void Test##Name(); + + HEAP_TEST_METHODS(DECLARE_STATIC) +#undef HEAP_TEST_METHODS +}; + + static void CheckMap(Map* map, int type, int instance_size) { CHECK(map->IsHeapObject()); #ifdef DEBUG @@ -59,7 +83,10 @@ TEST(HeapMaps) { Heap* heap = CcTest::heap(); CheckMap(heap->meta_map(), MAP_TYPE, Map::kSize); CheckMap(heap->heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize); - CheckMap(heap->float32x4_map(), FLOAT32X4_TYPE, Float32x4::kSize); +#define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ + CheckMap(heap->type##_map(), SIMD128_VALUE_TYPE, Type::kSize); + SIMD128_TYPES(SIMD128_TYPE) +#undef SIMD128_TYPE CheckMap(heap->fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel); CheckMap(heap->string_map(), STRING_TYPE, kVariableSizeSentinel); } @@ -215,20 +242,24 @@ TEST(HeapObjects) { template <typename T, typename LANE_TYPE, int LANES> -static void CheckSimdLanes(T* value) { - // Get the original values, and check that all lanes can be set to new values - // without disturbing the other lanes. - LANE_TYPE lane_values[LANES]; +static void CheckSimdValue(T* value, LANE_TYPE lane_values[LANES], + LANE_TYPE other_value) { + // Check against lane_values, and check that all lanes can be set to + // other_value without disturbing the other lanes. for (int i = 0; i < LANES; i++) { - lane_values[i] = value->get_lane(i); + CHECK_EQ(lane_values[i], value->get_lane(i)); } for (int i = 0; i < LANES; i++) { - lane_values[i] += 1; - value->set_lane(i, lane_values[i]); + value->set_lane(i, other_value); // change the value for (int j = 0; j < LANES; j++) { - CHECK_EQ(lane_values[j], value->get_lane(j)); + if (i != j) + CHECK_EQ(lane_values[j], value->get_lane(j)); + else + CHECK_EQ(other_value, value->get_lane(j)); } + value->set_lane(i, lane_values[i]); // restore the lane } + CHECK(value->BooleanValue()); // SIMD values are 'true'. } @@ -239,32 +270,132 @@ TEST(SimdObjects) { HandleScope sc(isolate); - Handle<Object> value = factory->NewFloat32x4(1, 2, 3, 4); - CHECK(value->IsFloat32x4()); - CHECK(value->BooleanValue()); // SIMD values map to true. + // Float32x4 + { + float lanes[4] = {1, 2, 3, 4}; + float quiet_NaN = std::numeric_limits<float>::quiet_NaN(); + float signaling_NaN = std::numeric_limits<float>::signaling_NaN(); + + Handle<Float32x4> value = factory->NewFloat32x4(lanes); + CHECK(value->IsFloat32x4()); + CheckSimdValue<Float32x4, float, 4>(*value, lanes, 3.14f); + + // Check special lane values. + value->set_lane(1, -0.0); + CHECK_EQ(-0.0, value->get_lane(1)); + CHECK(std::signbit(value->get_lane(1))); // Sign bit should be preserved. + value->set_lane(2, quiet_NaN); + CHECK(std::isnan(value->get_lane(2))); + value->set_lane(3, signaling_NaN); + CHECK(std::isnan(value->get_lane(3))); + +#ifdef OBJECT_PRINT + // Check value printing. + { + value = factory->NewFloat32x4(lanes); + std::ostringstream os; + value->Float32x4Print(os); + CHECK_EQ("1, 2, 3, 4", os.str()); + } + { + float special_lanes[4] = {0, -0.0, quiet_NaN, signaling_NaN}; + value = factory->NewFloat32x4(special_lanes); + std::ostringstream os; + value->Float32x4Print(os); + // Value printing doesn't preserve signed zeroes. + CHECK_EQ("0, 0, NaN, NaN", os.str()); + } +#endif // OBJECT_PRINT + } + // Int32x4 + { + int32_t lanes[4] = {-1, 0, 1, 2}; + + Handle<Int32x4> value = factory->NewInt32x4(lanes); + CHECK(value->IsInt32x4()); + CheckSimdValue<Int32x4, int32_t, 4>(*value, lanes, 3); + +#ifdef OBJECT_PRINT + std::ostringstream os; + value->Int32x4Print(os); + CHECK_EQ("-1, 0, 1, 2", os.str()); +#endif // OBJECT_PRINT + } + // Bool32x4 + { + bool lanes[4] = {true, true, true, false}; + + Handle<Bool32x4> value = factory->NewBool32x4(lanes); + CHECK(value->IsBool32x4()); + CheckSimdValue<Bool32x4, bool, 4>(*value, lanes, false); + +#ifdef OBJECT_PRINT + std::ostringstream os; + value->Bool32x4Print(os); + CHECK_EQ("true, true, true, false", os.str()); +#endif // OBJECT_PRINT + } + // Int16x8 + { + int16_t lanes[8] = {-1, 0, 1, 2, 3, 4, 5, -32768}; + + Handle<Int16x8> value = factory->NewInt16x8(lanes); + CHECK(value->IsInt16x8()); + CheckSimdValue<Int16x8, int16_t, 8>(*value, lanes, 32767); + +#ifdef OBJECT_PRINT + std::ostringstream os; + value->Int16x8Print(os); + CHECK_EQ("-1, 0, 1, 2, 3, 4, 5, -32768", os.str()); +#endif // OBJECT_PRINT + } + // Bool16x8 + { + bool lanes[8] = {true, true, true, true, true, true, true, false}; + + Handle<Bool16x8> value = factory->NewBool16x8(lanes); + CHECK(value->IsBool16x8()); + CheckSimdValue<Bool16x8, bool, 8>(*value, lanes, false); + +#ifdef OBJECT_PRINT + std::ostringstream os; + value->Bool16x8Print(os); + CHECK_EQ("true, true, true, true, true, true, true, false", os.str()); +#endif // OBJECT_PRINT + } + // Int8x16 + { + int8_t lanes[16] = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -128}; - Float32x4* float32x4 = *Handle<Float32x4>::cast(value); - CheckSimdLanes<Float32x4, float, 4>(float32x4); + Handle<Int8x16> value = factory->NewInt8x16(lanes); + CHECK(value->IsInt8x16()); + CheckSimdValue<Int8x16, int8_t, 16>(*value, lanes, 127); + +#ifdef OBJECT_PRINT + std::ostringstream os; + value->Int8x16Print(os); + CHECK_EQ("-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -128", + os.str()); +#endif // OBJECT_PRINT + } + // Bool8x16 + { + bool lanes[16] = {true, true, true, true, true, true, true, false, + true, true, true, true, true, true, true, false}; - // Check ToString for SIMD values. - // TODO(bbudge): Switch to Check* style function to test ToString(). - value = factory->NewFloat32x4(1, 2, 3, 4); - float32x4 = *Handle<Float32x4>::cast(value); - std::ostringstream os; - float32x4->Float32x4Print(os); - CHECK_EQ("1, 2, 3, 4", os.str()); + Handle<Bool8x16> value = factory->NewBool8x16(lanes); + CHECK(value->IsBool8x16()); + CheckSimdValue<Bool8x16, bool, 16>(*value, lanes, false); - // Check unusual lane values. - float32x4->set_lane(0, 0); - CHECK_EQ(0, float32x4->get_lane(0)); - float32x4->set_lane(1, -0.0); - CHECK_EQ(-0.0, float32x4->get_lane(1)); - float quiet_NaN = std::numeric_limits<float>::quiet_NaN(); - float signaling_NaN = std::numeric_limits<float>::signaling_NaN(); - float32x4->set_lane(2, quiet_NaN); - CHECK(std::isnan(float32x4->get_lane(2))); - float32x4->set_lane(3, signaling_NaN); - CHECK(std::isnan(float32x4->get_lane(3))); +#ifdef OBJECT_PRINT + std::ostringstream os; + value->Bool8x16Print(os); + CHECK_EQ( + "true, true, true, true, true, true, true, false, true, true, true, " + "true, true, true, true, false", + os.str()); +#endif // OBJECT_PRINT + } } @@ -556,6 +687,46 @@ TEST(DeleteWeakGlobalHandle) { } +TEST(BytecodeArray) { + static const uint8_t kRawBytes[] = {0xc3, 0x7e, 0xa5, 0x5a}; + static const int kRawBytesSize = sizeof(kRawBytes); + static const int kFrameSize = 32; + + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + Factory* factory = isolate->factory(); + HandleScope scope(isolate); + + // Allocate and initialize BytecodeArray + Handle<BytecodeArray> array = + factory->NewBytecodeArray(kRawBytesSize, kRawBytes, kFrameSize); + + CHECK(array->IsBytecodeArray()); + CHECK_EQ(array->length(), (int)sizeof(kRawBytes)); + CHECK_EQ(array->frame_size(), kFrameSize); + CHECK_LE(array->address(), array->GetFirstBytecodeAddress()); + CHECK_GE(array->address() + array->BytecodeArraySize(), + array->GetFirstBytecodeAddress() + array->length()); + for (int i = 0; i < kRawBytesSize; i++) { + CHECK_EQ(array->GetFirstBytecodeAddress()[i], kRawBytes[i]); + CHECK_EQ(array->get(i), kRawBytes[i]); + } + + // Full garbage collection + heap->CollectAllGarbage(); + + // BytecodeArray should survive + CHECK_EQ(array->length(), kRawBytesSize); + CHECK_EQ(array->frame_size(), kFrameSize); + + for (int i = 0; i < kRawBytesSize; i++) { + CHECK_EQ(array->get(i), kRawBytes[i]); + CHECK_EQ(array->GetFirstBytecodeAddress()[i], kRawBytes[i]); + } +} + + static const char* not_so_random_string_table[] = { "abstract", "boolean", @@ -791,7 +962,7 @@ TEST(JSArray) { CHECK(array->HasFastSmiOrObjectElements()); // array[length] = name. - JSReceiver::SetElement(array, 0, name, SLOPPY).Check(); + JSReceiver::SetElement(isolate, array, 0, name, SLOPPY).Check(); CHECK_EQ(Smi::FromInt(1), array->length()); element = i::Object::GetElement(isolate, array, 0).ToHandleChecked(); CHECK_EQ(*element, *name); @@ -805,7 +976,7 @@ TEST(JSArray) { CHECK(array->HasDictionaryElements()); // Must be in slow mode. // array[length] = name. - JSReceiver::SetElement(array, int_length, name, SLOPPY).Check(); + JSReceiver::SetElement(isolate, array, int_length, name, SLOPPY).Check(); uint32_t new_int_length = 0; CHECK(array->length()->ToArrayIndex(&new_int_length)); CHECK_EQ(static_cast<double>(int_length), new_int_length - 1); @@ -836,8 +1007,8 @@ TEST(JSObjectCopy) { JSReceiver::SetProperty(obj, first, one, SLOPPY).Check(); JSReceiver::SetProperty(obj, second, two, SLOPPY).Check(); - JSReceiver::SetElement(obj, 0, first, SLOPPY).Check(); - JSReceiver::SetElement(obj, 1, second, SLOPPY).Check(); + JSReceiver::SetElement(isolate, obj, 0, first, SLOPPY).Check(); + JSReceiver::SetElement(isolate, obj, 1, second, SLOPPY).Check(); // Make the clone. Handle<Object> value1, value2; @@ -862,8 +1033,8 @@ TEST(JSObjectCopy) { JSReceiver::SetProperty(clone, first, two, SLOPPY).Check(); JSReceiver::SetProperty(clone, second, one, SLOPPY).Check(); - JSReceiver::SetElement(clone, 0, second, SLOPPY).Check(); - JSReceiver::SetElement(clone, 1, first, SLOPPY).Check(); + JSReceiver::SetElement(isolate, clone, 0, second, SLOPPY).Check(); + JSReceiver::SetElement(isolate, clone, 1, first, SLOPPY).Check(); value1 = Object::GetElement(isolate, obj, 1).ToHandleChecked(); value2 = Object::GetElement(isolate, clone, 0).ToHandleChecked(); @@ -973,22 +1144,6 @@ TEST(Iteration) { } -TEST(EmptyHandleEscapeFrom) { - CcTest::InitializeVM(); - - v8::HandleScope scope(CcTest::isolate()); - Handle<JSObject> runaway; - - { - v8::EscapableHandleScope nested(CcTest::isolate()); - Handle<JSObject> empty; - runaway = empty.EscapeFrom(&nested); - } - - CHECK(runaway.is_null()); -} - - static int LenFromSize(int size) { return (size - FixedArray::kHeaderSize) / kPointerSize; } @@ -1012,7 +1167,7 @@ TEST(Regression39128) { // Step 1: prepare a map for the object. We add 1 inobject property to it. // Create a map with single inobject property. Handle<Map> my_map = Map::Create(CcTest::i_isolate(), 1); - int n_properties = my_map->inobject_properties(); + int n_properties = my_map->GetInObjectProperties(); CHECK_GT(n_properties, 0); int object_size = my_map->instance_size(); @@ -1523,7 +1678,8 @@ int CountNativeContexts() { count++; object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); } - return count; + // Subtract one to compensate for the code stub context that is always present + return count - 1; } @@ -1661,7 +1817,8 @@ static int CountNativeContextsWithGC(Isolate* isolate, int n) { Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK), isolate); } - return count; + // Subtract one to compensate for the code stub context that is always present + return count - 1; } @@ -2238,7 +2395,10 @@ static int NumberOfGlobalObjects() { for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { if (obj->IsGlobalObject()) count++; } - return count; + // Subtract two to compensate for the two global objects (not global + // JSObjects, of which there would only be one) that are part of the code stub + // context, which is always present. + return count - 2; } @@ -2450,7 +2610,7 @@ TEST(InstanceOfStubWriteBarrier) { } IncrementalMarking* marking = CcTest::heap()->incremental_marking(); - marking->Abort(); + marking->Stop(); marking->Start(Heap::kNoGCFlags); Handle<JSFunction> f = @@ -2578,7 +2738,7 @@ TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { CHECK(f->IsOptimized()); IncrementalMarking* marking = CcTest::heap()->incremental_marking(); - marking->Abort(); + marking->Stop(); marking->Start(Heap::kNoGCFlags); // The following calls will increment CcTest::heap()->global_ic_age(). CcTest::isolate()->ContextDisposedNotification(); @@ -2619,7 +2779,7 @@ TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { CcTest::global()->Get(v8_str("f")))); CHECK(f->IsOptimized()); - CcTest::heap()->incremental_marking()->Abort(); + CcTest::heap()->incremental_marking()->Stop(); // The following two calls will increment CcTest::heap()->global_ic_age(). CcTest::isolate()->ContextDisposedNotification(); @@ -2631,12 +2791,43 @@ TEST(ResetSharedFunctionInfoCountersDuringMarkSweep) { } +HEAP_TEST(GCFlags) { + CcTest::InitializeVM(); + Heap* heap = CcTest::heap(); + + heap->set_current_gc_flags(Heap::kNoGCFlags); + CHECK_EQ(Heap::kNoGCFlags, heap->current_gc_flags()); + + // Set the flags to check whether we appropriately resets them after the GC. + heap->set_current_gc_flags(Heap::kAbortIncrementalMarkingMask); + heap->CollectAllGarbage(Heap::kReduceMemoryFootprintMask); + CHECK_EQ(Heap::kNoGCFlags, heap->current_gc_flags()); + + MarkCompactCollector* collector = heap->mark_compact_collector(); + if (collector->sweeping_in_progress()) { + collector->EnsureSweepingCompleted(); + } + + IncrementalMarking* marking = heap->incremental_marking(); + marking->Stop(); + marking->Start(Heap::kReduceMemoryFootprintMask); + CHECK_NE(0, heap->current_gc_flags() & Heap::kReduceMemoryFootprintMask); + + heap->CollectGarbage(NEW_SPACE); + // NewSpace scavenges should not overwrite the flags. + CHECK_NE(0, heap->current_gc_flags() & Heap::kReduceMemoryFootprintMask); + + heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); + CHECK_EQ(Heap::kNoGCFlags, heap->current_gc_flags()); +} + + TEST(IdleNotificationFinishMarking) { i::FLAG_allow_natives_syntax = true; CcTest::InitializeVM(); SimulateFullSpace(CcTest::heap()->old_space()); IncrementalMarking* marking = CcTest::heap()->incremental_marking(); - marking->Abort(); + marking->Stop(); marking->Start(Heap::kNoGCFlags); CHECK_EQ(CcTest::heap()->gc_count(), 0); @@ -3681,8 +3872,14 @@ static void CheckVectorIC(Handle<JSFunction> f, int ic_slot_index, Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>(f->shared()->feedback_vector()); FeedbackVectorICSlot slot(ic_slot_index); - LoadICNexus nexus(vector, slot); - CHECK(nexus.StateFromFeedback() == desired_state); + if (vector->GetKind(slot) == Code::LOAD_IC) { + LoadICNexus nexus(vector, slot); + CHECK(nexus.StateFromFeedback() == desired_state); + } else { + CHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC); + KeyedLoadICNexus nexus(vector, slot); + CHECK(nexus.StateFromFeedback() == desired_state); + } } @@ -3695,6 +3892,38 @@ static void CheckVectorICCleared(Handle<JSFunction> f, int ic_slot_index) { } +TEST(ICInBuiltInIsClearedAppropriately) { + if (i::FLAG_always_opt) return; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + Handle<JSFunction> apply; + { + LocalContext env; + v8::Local<v8::Value> res = CompileRun("Function.apply"); + Handle<JSObject> maybe_apply = + v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res)); + apply = Handle<JSFunction>::cast(maybe_apply); + TypeFeedbackVector* vector = apply->shared()->feedback_vector(); + CHECK(vector->ICSlots() == 1); + CheckVectorIC(apply, 0, UNINITIALIZED); + CompileRun( + "function b(a1, a2, a3) { return a1 + a2 + a3; }" + "function fun(bar) { bar.apply({}, [1, 2, 3]); };" + "fun(b); fun(b)"); + CheckVectorIC(apply, 0, MONOMORPHIC); + } + + // Fire context dispose notification. + CcTest::isolate()->ContextDisposedNotification(); + SimulateIncrementalMarking(CcTest::heap()); + CcTest::heap()->CollectAllGarbage(); + + // The IC in apply has been cleared, ready to learn again. + CheckVectorIC(apply, 0, PREMONOMORPHIC); +} + + TEST(IncrementalMarkingPreservesMonomorphicConstructor) { if (i::FLAG_always_opt) return; CcTest::InitializeVM(); @@ -4368,6 +4597,149 @@ TEST(Regress173458) { } +#ifdef DEBUG +TEST(Regress513507) { + i::FLAG_flush_optimized_code_cache = false; + i::FLAG_allow_natives_syntax = true; + i::FLAG_gc_global = true; + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + HandleScope scope(isolate); + + // Prepare function whose optimized code map we can use. + Handle<SharedFunctionInfo> shared; + { + HandleScope inner_scope(isolate); + CompileRun("function f() { return 1 }" + "f(); %OptimizeFunctionOnNextCall(f); f();"); + + Handle<JSFunction> f = + v8::Utils::OpenHandle( + *v8::Handle<v8::Function>::Cast( + CcTest::global()->Get(v8_str("f")))); + shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); + CompileRun("f = null"); + } + + // Prepare optimized code that we can use. + Handle<Code> code; + { + HandleScope inner_scope(isolate); + CompileRun("function g() { return 2 }" + "g(); %OptimizeFunctionOnNextCall(g); g();"); + + Handle<JSFunction> g = + v8::Utils::OpenHandle( + *v8::Handle<v8::Function>::Cast( + CcTest::global()->Get(v8_str("g")))); + code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); + if (!code->is_optimized_code()) return; + } + + Handle<FixedArray> lit = isolate->factory()->empty_fixed_array(); + Handle<Context> context(isolate->context()); + + // Add the new code several times to the optimized code map and also set an + // allocation timeout so that expanding the code map will trigger a GC. + heap->set_allocation_timeout(5); + FLAG_gc_interval = 1000; + for (int i = 0; i < 10; ++i) { + BailoutId id = BailoutId(i); + SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); + } +} +#endif // DEBUG + + +TEST(Regress514122) { + i::FLAG_flush_optimized_code_cache = false; + i::FLAG_allow_natives_syntax = true; + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + HandleScope scope(isolate); + + // Perfrom one initial GC to enable code flushing. + CcTest::heap()->CollectAllGarbage(); + + // Prepare function whose optimized code map we can use. + Handle<SharedFunctionInfo> shared; + { + HandleScope inner_scope(isolate); + CompileRun("function f() { return 1 }" + "f(); %OptimizeFunctionOnNextCall(f); f();"); + + Handle<JSFunction> f = + v8::Utils::OpenHandle( + *v8::Handle<v8::Function>::Cast( + CcTest::global()->Get(v8_str("f")))); + shared = inner_scope.CloseAndEscape(handle(f->shared(), isolate)); + CompileRun("f = null"); + } + + // Prepare optimized code that we can use. + Handle<Code> code; + { + HandleScope inner_scope(isolate); + CompileRun("function g() { return 2 }" + "g(); %OptimizeFunctionOnNextCall(g); g();"); + + Handle<JSFunction> g = + v8::Utils::OpenHandle( + *v8::Handle<v8::Function>::Cast( + CcTest::global()->Get(v8_str("g")))); + code = inner_scope.CloseAndEscape(handle(g->code(), isolate)); + if (!code->is_optimized_code()) return; + } + + Handle<FixedArray> lit = isolate->factory()->empty_fixed_array(); + Handle<Context> context(isolate->context()); + + // Add the code several times to the optimized code map. + for (int i = 0; i < 3; ++i) { + HandleScope inner_scope(isolate); + BailoutId id = BailoutId(i); + SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); + } + shared->optimized_code_map()->Print(); + + // Add the code with a literals array to be evacuated. + Page* evac_page; + { + HandleScope inner_scope(isolate); + AlwaysAllocateScope always_allocate(isolate); + // Make sure literal is placed on an old-space evacuation candidate. + SimulateFullSpace(heap->old_space()); + Handle<FixedArray> lit = isolate->factory()->NewFixedArray(23, TENURED); + evac_page = Page::FromAddress(lit->address()); + BailoutId id = BailoutId(100); + SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); + } + + // Heap is ready, force {lit_page} to become an evacuation candidate and + // simulate incremental marking to enqueue optimized code map. + FLAG_manual_evacuation_candidates_selection = true; + evac_page->SetFlag(MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING); + SimulateIncrementalMarking(heap); + + // No matter whether reachable or not, {boomer} is doomed. + Handle<Object> boomer(shared->optimized_code_map(), isolate); + + // Add the code several times to the optimized code map. This will leave old + // copies of the optimized code map unreachable but still marked. + for (int i = 3; i < 6; ++i) { + HandleScope inner_scope(isolate); + BailoutId id = BailoutId(i); + SharedFunctionInfo::AddToOptimizedCodeMap(shared, context, code, lit, id); + } + + // Trigger a GC to flush out the bug. + heap->CollectGarbage(i::OLD_SPACE, "fire in the hole"); + boomer->Print(); +} + + class DummyVisitor : public ObjectVisitor { public: void VisitPointers(Object** start, Object** end) { } @@ -5242,6 +5614,31 @@ TEST(Regress357137) { } +TEST(Regress507979) { + const int kFixedArrayLen = 10; + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + HandleScope handle_scope(isolate); + + Handle<FixedArray> o1 = isolate->factory()->NewFixedArray(kFixedArrayLen); + Handle<FixedArray> o2 = isolate->factory()->NewFixedArray(kFixedArrayLen); + CHECK(heap->InNewSpace(o1->address())); + CHECK(heap->InNewSpace(o2->address())); + + HeapIterator it(heap, i::HeapIterator::kFilterUnreachable); + + // Replace parts of an object placed before a live object with a filler. This + // way the filler object shares the mark bits with the following live object. + o1->Shrink(kFixedArrayLen - 1); + + for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) { + // Let's not optimize the loop away. + CHECK(obj->address() != nullptr); + } +} + + TEST(ArrayShiftSweeping) { i::FLAG_expose_gc = true; CcTest::InitializeVM(); @@ -5387,7 +5784,7 @@ TEST(Regress388880) { CHECK_EQ(Page::kObjectStartOffset, page->Offset(temp2->address())); } - Handle<JSObject> o = factory->NewJSObjectFromMap(map1, TENURED, false); + Handle<JSObject> o = factory->NewJSObjectFromMap(map1, TENURED); o->set_properties(*factory->empty_fixed_array()); // Ensure that the object allocated where we need it. @@ -5399,7 +5796,7 @@ TEST(Regress388880) { // Enable incremental marking to trigger actions in Heap::AdjustLiveBytes() // that would cause crash. IncrementalMarking* marking = CcTest::heap()->incremental_marking(); - marking->Abort(); + marking->Stop(); marking->Start(Heap::kNoGCFlags); CHECK(marking->IsMarking()); @@ -6027,31 +6424,60 @@ TEST(SlotsBufferObjectSlotsRemoval) { // Firstly, let's test the regular slots buffer entry. buffer->Add(HeapObject::RawField(*array, FixedArray::kHeaderSize)); - DCHECK(reinterpret_cast<void*>(buffer->Get(0)) == - HeapObject::RawField(*array, FixedArray::kHeaderSize)); + CHECK(reinterpret_cast<void*>(buffer->Get(0)) == + HeapObject::RawField(*array, FixedArray::kHeaderSize)); SlotsBuffer::RemoveObjectSlots(CcTest::i_isolate()->heap(), buffer, array->address(), array->address() + array->Size()); - DCHECK(reinterpret_cast<void*>(buffer->Get(0)) == - HeapObject::RawField(heap->empty_fixed_array(), - FixedArrayBase::kLengthOffset)); + CHECK(reinterpret_cast<void*>(buffer->Get(0)) == + HeapObject::RawField(heap->empty_fixed_array(), + FixedArrayBase::kLengthOffset)); // Secondly, let's test the typed slots buffer entry. SlotsBuffer::AddTo(NULL, &buffer, SlotsBuffer::EMBEDDED_OBJECT_SLOT, array->address() + FixedArray::kHeaderSize, SlotsBuffer::FAIL_ON_OVERFLOW); - DCHECK(reinterpret_cast<void*>(buffer->Get(1)) == - reinterpret_cast<Object**>(SlotsBuffer::EMBEDDED_OBJECT_SLOT)); - DCHECK(reinterpret_cast<void*>(buffer->Get(2)) == - HeapObject::RawField(*array, FixedArray::kHeaderSize)); + CHECK(reinterpret_cast<void*>(buffer->Get(1)) == + reinterpret_cast<Object**>(SlotsBuffer::EMBEDDED_OBJECT_SLOT)); + CHECK(reinterpret_cast<void*>(buffer->Get(2)) == + HeapObject::RawField(*array, FixedArray::kHeaderSize)); SlotsBuffer::RemoveObjectSlots(CcTest::i_isolate()->heap(), buffer, array->address(), array->address() + array->Size()); - DCHECK(reinterpret_cast<void*>(buffer->Get(1)) == - HeapObject::RawField(heap->empty_fixed_array(), - FixedArrayBase::kLengthOffset)); - DCHECK(reinterpret_cast<void*>(buffer->Get(2)) == - HeapObject::RawField(heap->empty_fixed_array(), - FixedArrayBase::kLengthOffset)); + CHECK(reinterpret_cast<void*>(buffer->Get(1)) == + HeapObject::RawField(heap->empty_fixed_array(), + FixedArrayBase::kLengthOffset)); + CHECK(reinterpret_cast<void*>(buffer->Get(2)) == + HeapObject::RawField(heap->empty_fixed_array(), + FixedArrayBase::kLengthOffset)); delete buffer; } + + +TEST(ContextMeasure) { + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + Isolate* isolate = CcTest::i_isolate(); + LocalContext context; + + int size_upper_limit = 0; + int count_upper_limit = 0; + HeapIterator it(CcTest::heap()); + for (HeapObject* obj = it.next(); obj != NULL; obj = it.next()) { + size_upper_limit += obj->Size(); + count_upper_limit++; + } + + ContextMeasure measure(*isolate->native_context()); + + PrintF("Context size : %d bytes\n", measure.Size()); + PrintF("Context object count: %d\n", measure.Count()); + + CHECK_LE(1000, measure.Count()); + CHECK_LE(50000, measure.Size()); + + CHECK_LE(measure.Count(), count_upper_limit); + CHECK_LE(measure.Size(), size_upper_limit); +} +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/cctest/test-liveedit.cc b/deps/v8/test/cctest/test-liveedit.cc index 8419dc5a43..fdda3f53c6 100644 --- a/deps/v8/test/cctest/test-liveedit.cc +++ b/deps/v8/test/cctest/test-liveedit.cc @@ -29,7 +29,7 @@ #include "src/v8.h" -#include "src/liveedit.h" +#include "src/debug/liveedit.h" #include "test/cctest/cctest.h" diff --git a/deps/v8/test/cctest/test-lockers.cc b/deps/v8/test/cctest/test-lockers.cc index c86a9d67dc..f1dc5a28b4 100644 --- a/deps/v8/test/cctest/test-lockers.cc +++ b/deps/v8/test/cctest/test-lockers.cc @@ -31,11 +31,11 @@ #include "src/api.h" #include "src/base/platform/platform.h" +#include "src/base/smart-pointers.h" #include "src/compilation-cache.h" #include "src/execution.h" #include "src/isolate.h" #include "src/parser.h" -#include "src/smart-pointers.h" #include "src/unicode-inl.h" #include "src/utils.h" #include "test/cctest/cctest.h" @@ -101,7 +101,7 @@ TEST(KangarooIsolates) { v8::Isolate::CreateParams create_params; create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); v8::Isolate* isolate = v8::Isolate::New(create_params); - i::SmartPointer<KangarooThread> thread1; + v8::base::SmartPointer<KangarooThread> thread1; { v8::Locker locker(isolate); v8::Isolate::Scope isolate_scope(isolate); @@ -464,7 +464,8 @@ class LockAndUnlockDifferentIsolatesThread : public JoinableThread { } virtual void Run() { - i::SmartPointer<LockIsolateAndCalculateFibSharedContextThread> thread; + v8::base::SmartPointer<LockIsolateAndCalculateFibSharedContextThread> + thread; v8::Locker lock1(isolate1_); CHECK(v8::Locker::IsLocked(isolate1_)); CHECK(!v8::Locker::IsLocked(isolate2_)); diff --git a/deps/v8/test/cctest/test-macro-assembler-x64.cc b/deps/v8/test/cctest/test-macro-assembler-x64.cc index 4ff8cba68b..4cc52a11e2 100644 --- a/deps/v8/test/cctest/test-macro-assembler-x64.cc +++ b/deps/v8/test/cctest/test-macro-assembler-x64.cc @@ -736,28 +736,27 @@ static void SmiAddTest(MacroAssembler* masm, __ movl(rcx, Immediate(first)); __ Integer32ToSmi(rcx, rcx); - i::SmiOperationExecutionMode mode; - mode.Add(i::PRESERVE_SOURCE_REGISTER); - mode.Add(i::BAILOUT_ON_OVERFLOW); + i::SmiOperationConstraints constraints = + i::SmiOperationConstraint::kPreserveSourceRegister | + i::SmiOperationConstraint::kBailoutOnOverflow; __ incq(rax); - __ SmiAddConstant(r9, rcx, Smi::FromInt(second), mode, exit); + __ SmiAddConstant(r9, rcx, Smi::FromInt(second), constraints, exit); __ cmpq(r9, r8); __ j(not_equal, exit); __ incq(rax); - __ SmiAddConstant(rcx, rcx, Smi::FromInt(second), mode, exit); + __ SmiAddConstant(rcx, rcx, Smi::FromInt(second), constraints, exit); __ cmpq(rcx, r8); __ j(not_equal, exit); __ movl(rcx, Immediate(first)); __ Integer32ToSmi(rcx, rcx); - mode.RemoveAll(); - mode.Add(i::PRESERVE_SOURCE_REGISTER); - mode.Add(i::BAILOUT_ON_NO_OVERFLOW); + constraints = i::SmiOperationConstraint::kPreserveSourceRegister | + i::SmiOperationConstraint::kBailoutOnNoOverflow; Label done; __ incq(rax); - __ SmiAddConstant(rcx, rcx, Smi::FromInt(second), mode, &done); + __ SmiAddConstant(rcx, rcx, Smi::FromInt(second), constraints, &done); __ jmp(exit); __ bind(&done); __ cmpq(rcx, r8); @@ -799,14 +798,14 @@ static void SmiAddOverflowTest(MacroAssembler* masm, __ j(not_equal, exit); } - i::SmiOperationExecutionMode mode; - mode.Add(i::PRESERVE_SOURCE_REGISTER); - mode.Add(i::BAILOUT_ON_OVERFLOW); + i::SmiOperationConstraints constraints = + i::SmiOperationConstraint::kPreserveSourceRegister | + i::SmiOperationConstraint::kBailoutOnOverflow; __ movq(rcx, r11); { Label overflow_ok; __ incq(rax); - __ SmiAddConstant(r9, rcx, Smi::FromInt(y_min), mode, &overflow_ok); + __ SmiAddConstant(r9, rcx, Smi::FromInt(y_min), constraints, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); @@ -817,7 +816,7 @@ static void SmiAddOverflowTest(MacroAssembler* masm, { Label overflow_ok; __ incq(rax); - __ SmiAddConstant(rcx, rcx, Smi::FromInt(y_min), mode, &overflow_ok); + __ SmiAddConstant(rcx, rcx, Smi::FromInt(y_min), constraints, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); @@ -853,7 +852,7 @@ static void SmiAddOverflowTest(MacroAssembler* masm, { Label overflow_ok; __ incq(rax); - __ SmiAddConstant(r9, rcx, Smi::FromInt(y_max), mode, &overflow_ok); + __ SmiAddConstant(r9, rcx, Smi::FromInt(y_max), constraints, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); @@ -861,12 +860,11 @@ static void SmiAddOverflowTest(MacroAssembler* masm, __ j(not_equal, exit); } - mode.RemoveAll(); - mode.Add(i::BAILOUT_ON_OVERFLOW); + constraints = i::SmiOperationConstraint::kBailoutOnOverflow; { Label overflow_ok; __ incq(rax); - __ SmiAddConstant(rcx, rcx, Smi::FromInt(y_max), mode, &overflow_ok); + __ SmiAddConstant(rcx, rcx, Smi::FromInt(y_max), constraints, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); @@ -952,28 +950,27 @@ static void SmiSubTest(MacroAssembler* masm, __ cmpq(rcx, r8); __ j(not_equal, exit); - i::SmiOperationExecutionMode mode; - mode.Add(i::PRESERVE_SOURCE_REGISTER); - mode.Add(i::BAILOUT_ON_OVERFLOW); + i::SmiOperationConstraints constraints = + i::SmiOperationConstraint::kPreserveSourceRegister | + i::SmiOperationConstraint::kBailoutOnOverflow; __ Move(rcx, Smi::FromInt(first)); __ incq(rax); // Test 4. - __ SmiSubConstant(rcx, rcx, Smi::FromInt(second), mode, exit); + __ SmiSubConstant(rcx, rcx, Smi::FromInt(second), constraints, exit); __ cmpq(rcx, r8); __ j(not_equal, exit); __ Move(rcx, Smi::FromInt(first)); __ incq(rax); // Test 5. - __ SmiSubConstant(r9, rcx, Smi::FromInt(second), mode, exit); + __ SmiSubConstant(r9, rcx, Smi::FromInt(second), constraints, exit); __ cmpq(r9, r8); __ j(not_equal, exit); - mode.RemoveAll(); - mode.Add(i::PRESERVE_SOURCE_REGISTER); - mode.Add(i::BAILOUT_ON_NO_OVERFLOW); + constraints = i::SmiOperationConstraint::kPreserveSourceRegister | + i::SmiOperationConstraint::kBailoutOnNoOverflow; __ Move(rcx, Smi::FromInt(first)); Label done; __ incq(rax); // Test 6. - __ SmiSubConstant(rcx, rcx, Smi::FromInt(second), mode, &done); + __ SmiSubConstant(rcx, rcx, Smi::FromInt(second), constraints, &done); __ jmp(exit); __ bind(&done); __ cmpq(rcx, r8); @@ -1015,15 +1012,15 @@ static void SmiSubOverflowTest(MacroAssembler* masm, __ j(not_equal, exit); } - i::SmiOperationExecutionMode mode; - mode.Add(i::PRESERVE_SOURCE_REGISTER); - mode.Add(i::BAILOUT_ON_OVERFLOW); + i::SmiOperationConstraints constraints = + i::SmiOperationConstraint::kPreserveSourceRegister | + i::SmiOperationConstraint::kBailoutOnOverflow; __ movq(rcx, r11); { Label overflow_ok; __ incq(rax); - __ SmiSubConstant(r9, rcx, Smi::FromInt(y_min), mode, &overflow_ok); + __ SmiSubConstant(r9, rcx, Smi::FromInt(y_min), constraints, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); @@ -1034,7 +1031,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm, { Label overflow_ok; __ incq(rax); - __ SmiSubConstant(rcx, rcx, Smi::FromInt(y_min), mode, &overflow_ok); + __ SmiSubConstant(rcx, rcx, Smi::FromInt(y_min), constraints, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); @@ -1070,7 +1067,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm, { Label overflow_ok; __ incq(rax); - __ SmiSubConstant(rcx, rcx, Smi::FromInt(y_max), mode, &overflow_ok); + __ SmiSubConstant(rcx, rcx, Smi::FromInt(y_max), constraints, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); @@ -1078,13 +1075,12 @@ static void SmiSubOverflowTest(MacroAssembler* masm, __ j(not_equal, exit); } - mode.RemoveAll(); - mode.Add(i::BAILOUT_ON_OVERFLOW); + constraints = i::SmiOperationConstraint::kBailoutOnOverflow; __ movq(rcx, r11); { Label overflow_ok; __ incq(rax); - __ SmiSubConstant(rcx, rcx, Smi::FromInt(y_max), mode, &overflow_ok); + __ SmiSubConstant(rcx, rcx, Smi::FromInt(y_max), constraints, &overflow_ok); __ jmp(exit); __ bind(&overflow_ok); __ incq(rax); diff --git a/deps/v8/test/cctest/test-mark-compact.cc b/deps/v8/test/cctest/test-mark-compact.cc index a8cc6c7855..73369d29e5 100644 --- a/deps/v8/test/cctest/test-mark-compact.cc +++ b/deps/v8/test/cctest/test-mark-compact.cc @@ -39,7 +39,7 @@ #include "src/v8.h" -#include "src/full-codegen.h" +#include "src/full-codegen/full-codegen.h" #include "src/global-handles.h" #include "test/cctest/cctest.h" @@ -59,7 +59,7 @@ TEST(MarkingDeque) { Address original_address = reinterpret_cast<Address>(&s); Address current_address = original_address; while (!s.IsFull()) { - s.PushBlack(HeapObject::FromAddress(current_address)); + s.Push(HeapObject::FromAddress(current_address)); current_address += kPointerSize; } diff --git a/deps/v8/test/cctest/test-mementos.cc b/deps/v8/test/cctest/test-mementos.cc index 9aa1e6d30e..a97666384b 100644 --- a/deps/v8/test/cctest/test-mementos.cc +++ b/deps/v8/test/cctest/test-mementos.cc @@ -101,6 +101,7 @@ TEST(PretenuringCallNew) { CcTest::InitializeVM(); if (!i::FLAG_allocation_site_pretenuring) return; if (!i::FLAG_pretenuring_call_new) return; + if (i::FLAG_always_opt) return; v8::HandleScope scope(CcTest::isolate()); Isolate* isolate = CcTest::i_isolate(); diff --git a/deps/v8/test/cctest/test-migrations.cc b/deps/v8/test/cctest/test-migrations.cc index 0cefd54ceb..3ace0488f8 100644 --- a/deps/v8/test/cctest/test-migrations.cc +++ b/deps/v8/test/cctest/test-migrations.cc @@ -14,7 +14,6 @@ #include "src/global-handles.h" #include "src/ic/stub-cache.h" #include "src/macro-assembler.h" -#include "src/smart-pointers.h" #include "test/cctest/cctest.h" using namespace v8::internal; diff --git a/deps/v8/test/cctest/test-object-observe.cc b/deps/v8/test/cctest/test-object-observe.cc index 0295de5e23..07cc772df0 100644 --- a/deps/v8/test/cctest/test-object-observe.cc +++ b/deps/v8/test/cctest/test-object-observe.cc @@ -711,7 +711,7 @@ TEST(DontLeakContextOnObserve) { } CcTest::isolate()->ContextDisposedNotification(); - CheckSurvivingGlobalObjectsCount(1); + CheckSurvivingGlobalObjectsCount(2); } @@ -732,7 +732,7 @@ TEST(DontLeakContextOnGetNotifier) { } CcTest::isolate()->ContextDisposedNotification(); - CheckSurvivingGlobalObjectsCount(1); + CheckSurvivingGlobalObjectsCount(2); } @@ -759,7 +759,7 @@ TEST(DontLeakContextOnNotifierPerformChange) { } CcTest::isolate()->ContextDisposedNotification(); - CheckSurvivingGlobalObjectsCount(1); + CheckSurvivingGlobalObjectsCount(2); } diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc index cfb43911aa..23a3d2621a 100644 --- a/deps/v8/test/cctest/test-parsing.cc +++ b/deps/v8/test/cctest/test-parsing.cc @@ -71,8 +71,6 @@ TEST(ScanKeywords) { { i::Utf8ToUtf16CharacterStream stream(keyword, length); i::Scanner scanner(&unicode_cache); - // The scanner should parse Harmony keywords for this test. - scanner.SetHarmonyModules(true); scanner.Initialize(&stream); CHECK_EQ(key_token.token, scanner.Next()); CHECK_EQ(i::Token::EOS, scanner.Next()); @@ -506,7 +504,8 @@ TEST(PreParseOverflow) { i::GetCurrentStackPosition() - 128 * 1024); size_t kProgramSize = 1024 * 1024; - i::SmartArrayPointer<char> program(i::NewArray<char>(kProgramSize + 1)); + v8::base::SmartArrayPointer<char> program( + i::NewArray<char>(kProgramSize + 1)); memset(program.get(), '(', kProgramSize); program[kProgramSize] = '\0'; @@ -560,7 +559,7 @@ void TestCharacterStream(const char* one_byte_source, unsigned length, i::Isolate* isolate = CcTest::i_isolate(); i::Factory* factory = isolate->factory(); i::HandleScope test_scope(isolate); - i::SmartArrayPointer<i::uc16> uc16_buffer(new i::uc16[length]); + v8::base::SmartArrayPointer<i::uc16> uc16_buffer(new i::uc16[length]); for (unsigned i = 0; i < length; i++) { uc16_buffer[i] = static_cast<i::uc16>(one_byte_source[i]); } @@ -1071,9 +1070,9 @@ TEST(ScopeUsesArgumentsSuperThis) { CHECK(parser.Parse(&info)); CHECK(i::Rewriter::Rewrite(&info)); CHECK(i::Scope::Analyze(&info)); - CHECK(info.function() != NULL); + CHECK(info.literal() != NULL); - i::Scope* script_scope = info.function()->scope(); + i::Scope* script_scope = info.literal()->scope(); CHECK(script_scope->is_script_scope()); CHECK_EQ(1, script_scope->inner_scopes()->length()); @@ -1370,10 +1369,10 @@ TEST(ScopePositions) { info.set_global(); info.set_language_mode(source_data[i].language_mode); parser.Parse(&info); - CHECK(info.function() != NULL); + CHECK(info.literal() != NULL); // Check scope types and positions. - i::Scope* scope = info.function()->scope(); + i::Scope* scope = info.literal()->scope(); CHECK(scope->is_script_scope()); CHECK_EQ(scope->start_position(), 0); CHECK_EQ(scope->end_position(), kProgramSize); @@ -1426,12 +1425,10 @@ i::Handle<i::String> FormatMessage(i::Vector<unsigned> data) { enum ParserFlag { kAllowLazy, kAllowNatives, - kAllowHarmonyModules, kAllowHarmonyArrowFunctions, kAllowHarmonyRestParameters, kAllowHarmonySloppy, - kAllowHarmonyUnicode, - kAllowHarmonyComputedPropertyNames, + kAllowHarmonySloppyLet, kAllowHarmonySpreadCalls, kAllowHarmonyDestructuring, kAllowHarmonySpreadArrays, @@ -1452,17 +1449,14 @@ void SetParserFlags(i::ParserBase<Traits>* parser, i::EnumSet<ParserFlag> flags) { parser->set_allow_lazy(flags.Contains(kAllowLazy)); parser->set_allow_natives(flags.Contains(kAllowNatives)); - parser->set_allow_harmony_modules(flags.Contains(kAllowHarmonyModules)); parser->set_allow_harmony_arrow_functions( flags.Contains(kAllowHarmonyArrowFunctions)); - parser->set_allow_harmony_rest_params( + parser->set_allow_harmony_rest_parameters( flags.Contains(kAllowHarmonyRestParameters)); parser->set_allow_harmony_spreadcalls( flags.Contains(kAllowHarmonySpreadCalls)); parser->set_allow_harmony_sloppy(flags.Contains(kAllowHarmonySloppy)); - parser->set_allow_harmony_unicode(flags.Contains(kAllowHarmonyUnicode)); - parser->set_allow_harmony_computed_property_names( - flags.Contains(kAllowHarmonyComputedPropertyNames)); + parser->set_allow_harmony_sloppy_let(flags.Contains(kAllowHarmonySloppyLet)); parser->set_allow_harmony_destructuring( flags.Contains(kAllowHarmonyDestructuring)); parser->set_allow_harmony_spread_arrays( @@ -1512,7 +1506,7 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, SetParserFlags(&parser, flags); info.set_global(); parser.Parse(&info); - function = info.function(); + function = info.literal(); if (function) { parser_materialized_literals = function->materialized_literal_count(); } @@ -3450,9 +3444,9 @@ TEST(InnerAssignment) { i::Parser parser(&info); CHECK(parser.Parse(&info)); CHECK(i::Compiler::Analyze(&info)); - CHECK(info.function() != NULL); + CHECK(info.literal() != NULL); - i::Scope* scope = info.function()->scope(); + i::Scope* scope = info.literal()->scope(); CHECK_EQ(scope->inner_scopes()->length(), 1); i::Scope* inner_scope = scope->inner_scopes()->at(0); const i::AstRawString* var_name = @@ -4923,9 +4917,7 @@ TEST(InvalidUnicodeEscapes) { "var foob\\v{1234}r = 0;", "var foob\\U{1234}r = 0;", NULL}; - static const ParserFlag always_flags[] = {kAllowHarmonyUnicode}; - RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, - arraysize(always_flags)); + RunParserSyncTest(context_data, data, kError); } @@ -4951,9 +4943,7 @@ TEST(UnicodeEscapes) { // Max value for the unicode escape "\"\\u{10ffff}\"", NULL}; - static const ParserFlag always_flags[] = {kAllowHarmonyUnicode}; - RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags, - arraysize(always_flags)); + RunParserSyncTest(context_data, data, kSuccess); } @@ -5332,7 +5322,6 @@ TEST(ComputedPropertyName) { NULL}; static const ParserFlag always_flags[] = { - kAllowHarmonyComputedPropertyNames, kAllowHarmonySloppy, }; RunParserSyncTest(context_data, error_data, kError, NULL, 0, @@ -5361,7 +5350,6 @@ TEST(ComputedPropertyNameShorthandError) { NULL}; static const ParserFlag always_flags[] = { - kAllowHarmonyComputedPropertyNames, kAllowHarmonySloppy, }; RunParserSyncTest(context_data, error_data, kError, NULL, 0, @@ -5370,6 +5358,8 @@ TEST(ComputedPropertyNameShorthandError) { TEST(BasicImportExportParsing) { + i::FLAG_harmony_modules = true; + const char* kSources[] = { "export let x = 0;", "export var y = 0;", @@ -5429,7 +5419,6 @@ TEST(BasicImportExportParsing) { i::Zone zone; i::ParseInfo info(&zone, script); i::Parser parser(&info); - parser.set_allow_harmony_modules(true); info.set_module(); if (!parser.Parse(&info)) { i::Handle<i::JSObject> exception_handle( @@ -5455,7 +5444,6 @@ TEST(BasicImportExportParsing) { i::Zone zone; i::ParseInfo info(&zone, script); i::Parser parser(&info); - parser.set_allow_harmony_modules(true); info.set_global(); CHECK(!parser.Parse(&info)); } @@ -5464,6 +5452,8 @@ TEST(BasicImportExportParsing) { TEST(ImportExportParsingErrors) { + i::FLAG_harmony_modules = true; + const char* kErrorSources[] = { "export {", "var a; export { a", @@ -5544,7 +5534,6 @@ TEST(ImportExportParsingErrors) { i::Zone zone; i::ParseInfo info(&zone, script); i::Parser parser(&info); - parser.set_allow_harmony_modules(true); info.set_module(); CHECK(!parser.Parse(&info)); } @@ -5575,11 +5564,10 @@ TEST(ModuleParsingInternals) { i::Zone zone; i::ParseInfo info(&zone, script); i::Parser parser(&info); - parser.set_allow_harmony_modules(true); info.set_module(); CHECK(parser.Parse(&info)); CHECK(i::Compiler::Analyze(&info)); - i::FunctionLiteral* func = info.function(); + i::FunctionLiteral* func = info.literal(); i::Scope* module_scope = func->scope(); i::Scope* outer_scope = module_scope->outer_scope(); CHECK(outer_scope->is_script_scope()); @@ -5587,7 +5575,7 @@ TEST(ModuleParsingInternals) { CHECK_EQ(1, outer_scope->num_modules()); CHECK(module_scope->is_module_scope()); CHECK_NOT_NULL(module_scope->module_var()); - CHECK_EQ(i::INTERNAL, module_scope->module_var()->mode()); + CHECK_EQ(i::TEMPORARY, module_scope->module_var()->mode()); i::ModuleDescriptor* descriptor = module_scope->module(); CHECK_NOT_NULL(descriptor); CHECK_EQ(1, descriptor->Length()); @@ -5654,11 +5642,7 @@ TEST(DuplicateProtoNoError) { NULL }; - static const ParserFlag always_flags[] = { - kAllowHarmonyComputedPropertyNames, - }; - RunParserSyncTest(context_data, error_data, kSuccess, NULL, 0, - always_flags, arraysize(always_flags)); + RunParserSyncTest(context_data, error_data, kSuccess); } @@ -5707,8 +5691,8 @@ void TestLanguageMode(const char* source, parser.set_allow_strong_mode(true); info.set_global(); parser.Parse(&info); - CHECK(info.function() != NULL); - CHECK_EQ(expected_language_mode, info.function()->language_mode()); + CHECK(info.literal() != NULL); + CHECK_EQ(expected_language_mode, info.literal()->language_mode()); } @@ -6397,7 +6381,6 @@ TEST(StrongModeFreeVariablesNotDeclared) { TEST(DestructuringPositiveTests) { i::FLAG_harmony_destructuring = true; i::FLAG_harmony_arrow_functions = true; - i::FLAG_harmony_computed_property_names = true; const char* context_data[][2] = {{"'use strict'; let ", " = {};"}, {"var ", " = {};"}, @@ -6446,8 +6429,7 @@ TEST(DestructuringPositiveTests) { "[a,,...rest]", NULL}; // clang-format on - static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames, - kAllowHarmonyArrowFunctions, + static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions, kAllowHarmonyDestructuring}; RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); @@ -6457,9 +6439,7 @@ TEST(DestructuringPositiveTests) { TEST(DestructuringNegativeTests) { i::FLAG_harmony_destructuring = true; i::FLAG_harmony_arrow_functions = true; - i::FLAG_harmony_computed_property_names = true; - static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames, - kAllowHarmonyArrowFunctions, + static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions, kAllowHarmonyDestructuring}; { // All modes. @@ -6509,6 +6489,8 @@ TEST(DestructuringNegativeTests) { "false", "1", "'abc'", + "/abc/", + "`abc`", "class {}", "{+2 : x}", "{-2 : x}", @@ -6529,6 +6511,10 @@ TEST(DestructuringNegativeTests) { "[...rest,...rest1]", "[a,b,...rest,...rest1]", "[a,,..rest,...rest1]", + "{ x : 3 }", + "{ x : 'foo' }", + "{ x : /foo/ }", + "{ x : `foo` }", NULL}; // clang-format on RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, @@ -6622,9 +6608,7 @@ TEST(DestructuringDisallowPatternsInForVarIn) { TEST(DestructuringDuplicateParams) { i::FLAG_harmony_destructuring = true; i::FLAG_harmony_arrow_functions = true; - i::FLAG_harmony_computed_property_names = true; - static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames, - kAllowHarmonyArrowFunctions, + static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions, kAllowHarmonyDestructuring}; const char* context_data[][2] = {{"'use strict';", ""}, {"function outer() { 'use strict';", "}"}, @@ -6652,9 +6636,7 @@ TEST(DestructuringDuplicateParams) { TEST(DestructuringDuplicateParamsSloppy) { i::FLAG_harmony_destructuring = true; i::FLAG_harmony_arrow_functions = true; - i::FLAG_harmony_computed_property_names = true; - static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames, - kAllowHarmonyArrowFunctions, + static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions, kAllowHarmonyDestructuring}; const char* context_data[][2] = { {"", ""}, {"function outer() {", "}"}, {nullptr, nullptr}}; @@ -6677,9 +6659,7 @@ TEST(DestructuringDuplicateParamsSloppy) { TEST(DestructuringDisallowPatternsInSingleParamArrows) { i::FLAG_harmony_destructuring = true; i::FLAG_harmony_arrow_functions = true; - i::FLAG_harmony_computed_property_names = true; - static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames, - kAllowHarmonyArrowFunctions, + static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions, kAllowHarmonyDestructuring}; const char* context_data[][2] = {{"'use strict';", ""}, {"function outer() { 'use strict';", "}"}, @@ -6702,10 +6682,9 @@ TEST(DestructuringDisallowPatternsInRestParams) { i::FLAG_harmony_destructuring = true; i::FLAG_harmony_arrow_functions = true; i::FLAG_harmony_rest_parameters = true; - i::FLAG_harmony_computed_property_names = true; - static const ParserFlag always_flags[] = { - kAllowHarmonyComputedPropertyNames, kAllowHarmonyArrowFunctions, - kAllowHarmonyRestParameters, kAllowHarmonyDestructuring}; + static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions, + kAllowHarmonyRestParameters, + kAllowHarmonyDestructuring}; const char* context_data[][2] = {{"'use strict';", ""}, {"function outer() { 'use strict';", "}"}, {"", ""}, @@ -6827,7 +6806,7 @@ TEST(NewTarget) { } -TEST(LegacyConst) { +TEST(ConstLegacy) { // clang-format off const char* context_data[][2] = { {"", ""}, @@ -6845,9 +6824,58 @@ TEST(LegacyConst) { }; // clang-format on - static const ParserFlag always_flags[] = {kNoLegacyConst}; + static const ParserFlag always_flags[] = {kNoLegacyConst}; RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, arraysize(always_flags)); RunParserSyncTest(context_data, data, kSuccess); } + + +TEST(ConstSloppy) { + // clang-format off + const char* context_data[][2] = { + {"", ""}, + {"{", "}"}, + {NULL, NULL} + }; + + const char* data[] = { + "const x = 1", + "for (const x = 1; x < 1; x++) {}", + "for (const x in {}) {}", + "for (const x of []) {}", + NULL + }; + // clang-format on + static const ParserFlag always_flags[] = {kAllowHarmonySloppy, + kNoLegacyConst}; + RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags, + arraysize(always_flags)); +} + + +TEST(LetSloppy) { + // clang-format off + const char* context_data[][2] = { + {"", ""}, + {"'use strict';", ""}, + {"{", "}"}, + {NULL, NULL} + }; + + const char* data[] = { + "let x", + "let x = 1", + "for (let x = 1; x < 1; x++) {}", + "for (let x in {}) {}", + "for (let x of []) {}", + NULL + }; + // clang-format on + + static const ParserFlag always_flags[] = {kAllowHarmonySloppy, + kAllowHarmonySloppyLet}; + RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags, + arraysize(always_flags)); +} diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc index e7fcbd10e0..f0b623f38c 100644 --- a/deps/v8/test/cctest/test-regexp.cc +++ b/deps/v8/test/cctest/test-regexp.cc @@ -32,55 +32,56 @@ #include "src/ast.h" #include "src/char-predicates-inl.h" -#include "src/jsregexp.h" #include "src/ostreams.h" #include "src/parser.h" -#include "src/regexp-macro-assembler.h" -#include "src/regexp-macro-assembler-irregexp.h" +#include "src/regexp/jsregexp.h" +#include "src/regexp/regexp-macro-assembler.h" +#include "src/regexp/regexp-macro-assembler-irregexp.h" +#include "src/splay-tree-inl.h" #include "src/string-stream.h" #ifdef V8_INTERPRETED_REGEXP -#include "src/interpreter-irregexp.h" +#include "src/regexp/interpreter-irregexp.h" #else // V8_INTERPRETED_REGEXP #include "src/macro-assembler.h" #if V8_TARGET_ARCH_ARM #include "src/arm/assembler-arm.h" // NOLINT #include "src/arm/macro-assembler-arm.h" -#include "src/arm/regexp-macro-assembler-arm.h" +#include "src/regexp/arm/regexp-macro-assembler-arm.h" #endif #if V8_TARGET_ARCH_ARM64 #include "src/arm64/assembler-arm64.h" #include "src/arm64/macro-assembler-arm64.h" -#include "src/arm64/regexp-macro-assembler-arm64.h" +#include "src/regexp/arm64/regexp-macro-assembler-arm64.h" #endif #if V8_TARGET_ARCH_PPC #include "src/ppc/assembler-ppc.h" #include "src/ppc/macro-assembler-ppc.h" -#include "src/ppc/regexp-macro-assembler-ppc.h" +#include "src/regexp/ppc/regexp-macro-assembler-ppc.h" #endif #if V8_TARGET_ARCH_MIPS #include "src/mips/assembler-mips.h" #include "src/mips/macro-assembler-mips.h" -#include "src/mips/regexp-macro-assembler-mips.h" +#include "src/regexp/mips/regexp-macro-assembler-mips.h" #endif #if V8_TARGET_ARCH_MIPS64 #include "src/mips64/assembler-mips64.h" #include "src/mips64/macro-assembler-mips64.h" -#include "src/mips64/regexp-macro-assembler-mips64.h" +#include "src/regexp/mips64/regexp-macro-assembler-mips64.h" #endif #if V8_TARGET_ARCH_X64 +#include "src/regexp/x64/regexp-macro-assembler-x64.h" #include "src/x64/assembler-x64.h" #include "src/x64/macro-assembler-x64.h" -#include "src/x64/regexp-macro-assembler-x64.h" #endif #if V8_TARGET_ARCH_IA32 #include "src/ia32/assembler-ia32.h" #include "src/ia32/macro-assembler-ia32.h" -#include "src/ia32/regexp-macro-assembler-ia32.h" +#include "src/regexp/ia32/regexp-macro-assembler-ia32.h" #endif #if V8_TARGET_ARCH_X87 +#include "src/regexp/x87/regexp-macro-assembler-x87.h" #include "src/x87/assembler-x87.h" #include "src/x87/macro-assembler-x87.h" -#include "src/x87/regexp-macro-assembler-x87.h" #endif #endif // V8_INTERPRETED_REGEXP #include "test/cctest/cctest.h" @@ -413,7 +414,7 @@ static void ExpectError(const char* input, CcTest::i_isolate(), &zone, &reader, false, false, &result)); CHECK(result.tree == NULL); CHECK(!result.error.is_null()); - SmartArrayPointer<char> str = result.error->ToCString(ALLOW_NULLS); + v8::base::SmartArrayPointer<char> str = result.error->ToCString(ALLOW_NULLS); CHECK_EQ(0, strcmp(expected, str.get())); } diff --git a/deps/v8/test/cctest/test-reloc-info.cc b/deps/v8/test/cctest/test-reloc-info.cc index 829fd24f4d..e4d9fed7ec 100644 --- a/deps/v8/test/cctest/test-reloc-info.cc +++ b/deps/v8/test/cctest/test-reloc-info.cc @@ -45,7 +45,7 @@ TEST(Positions) { const int code_size = 10 * KB; int relocation_info_size = 10 * KB; const int buffer_size = code_size + relocation_info_size; - SmartArrayPointer<byte> buffer(new byte[buffer_size]); + v8::base::SmartArrayPointer<byte> buffer(new byte[buffer_size]); byte* pc = buffer.get(); byte* buffer_end = buffer.get() + buffer_size; diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc index 0bae94e219..bf36081201 100644 --- a/deps/v8/test/cctest/test-serialize.cc +++ b/deps/v8/test/cctest/test-serialize.cc @@ -33,7 +33,7 @@ #include "src/bootstrapper.h" #include "src/compilation-cache.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/heap/spaces.h" #include "src/objects.h" #include "src/parser.h" @@ -628,7 +628,11 @@ UNINITIALIZED_DEPENDENT_TEST(CustomContextDeserialization, root = deserializer.DeserializePartial(isolate, global_proxy, &outdated_contexts).ToHandleChecked(); - CHECK_EQ(3, outdated_contexts->length()); + if (FLAG_global_var_shortcuts) { + CHECK_EQ(5, outdated_contexts->length()); + } else { + CHECK_EQ(3, outdated_contexts->length()); + } CHECK(root->IsContext()); Handle<Context> context = Handle<Context>::cast(root); CHECK(context->global_proxy() == *global_proxy); diff --git a/deps/v8/test/cctest/test-simd.cc b/deps/v8/test/cctest/test-simd.cc new file mode 100644 index 0000000000..fd72b695ee --- /dev/null +++ b/deps/v8/test/cctest/test-simd.cc @@ -0,0 +1,117 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/v8.h" + +#include "src/objects.h" +#include "src/ostreams.h" +#include "test/cctest/cctest.h" + +using namespace v8::internal; + +#define FLOAT_TEST(type, lane_count) \ + { \ + float nan = std::numeric_limits<float>::quiet_NaN(); \ + float lanes[lane_count] = {0}; \ + Handle<type> a = factory->New##type(lanes); \ + Handle<type> b = factory->New##type(lanes); \ + CHECK(a->BitwiseEquals(*b)); \ + CHECK(a->SameValue(*b)); \ + CHECK(a->SameValueZero(*b)); \ + CHECK_EQ(a->Hash(), b->Hash()); \ + for (int i = 0; i < lane_count; i++) { \ + a->set_lane(i, -0.0); \ + CHECK(!a->BitwiseEquals(*b)); \ + CHECK_NE(a->Hash(), b->Hash()); \ + CHECK(!a->SameValue(*b)); \ + CHECK(a->SameValueZero(*b)); \ + b->set_lane(i, -0.0); \ + CHECK(a->BitwiseEquals(*b)); \ + CHECK_EQ(a->Hash(), b->Hash()); \ + CHECK(a->SameValue(*b)); \ + CHECK(a->SameValueZero(*b)); \ + a->set_lane(i, nan); \ + CHECK(!a->BitwiseEquals(*b)); \ + CHECK(!a->SameValue(*b)); \ + CHECK(!a->SameValueZero(*b)); \ + CHECK_NE(a->Hash(), b->Hash()); \ + b->set_lane(i, nan); \ + CHECK(a->BitwiseEquals(*b)); \ + CHECK_EQ(a->Hash(), b->Hash()); \ + CHECK(a->SameValue(*b)); \ + CHECK(a->SameValueZero(*b)); \ + } \ + } + +#define INT_TEST(type, lane_count, lane_type) \ + { \ + lane_type lanes[lane_count] = {0}; \ + Handle<type> a = factory->New##type(lanes); \ + Handle<type> b = factory->New##type(lanes); \ + CHECK(a->BitwiseEquals(*b)); \ + CHECK(a->SameValue(*b)); \ + CHECK(a->SameValueZero(*b)); \ + CHECK_EQ(a->Hash(), b->Hash()); \ + for (int i = 0; i < lane_count; i++) { \ + a->set_lane(i, i + 1); \ + CHECK(!a->BitwiseEquals(*b)); \ + CHECK_NE(a->Hash(), b->Hash()); \ + CHECK(!a->SameValue(*b)); \ + CHECK(!a->SameValueZero(*b)); \ + b->set_lane(i, i + 1); \ + CHECK(a->BitwiseEquals(*b)); \ + CHECK_EQ(a->Hash(), b->Hash()); \ + CHECK(a->SameValue(*b)); \ + CHECK(a->SameValueZero(*b)); \ + a->set_lane(i, -(i + 1)); \ + CHECK(!a->BitwiseEquals(*b)); \ + CHECK_NE(a->Hash(), b->Hash()); \ + CHECK(!a->SameValue(*b)); \ + CHECK(!a->SameValueZero(*b)); \ + b->set_lane(i, -(i + 1)); \ + CHECK(a->BitwiseEquals(*b)); \ + CHECK_EQ(a->Hash(), b->Hash()); \ + CHECK(a->SameValue(*b)); \ + CHECK(a->SameValueZero(*b)); \ + } \ + } + +#define BOOL_TEST(type, lane_count) \ + { \ + bool lanes[lane_count] = {false}; \ + Handle<type> a = factory->New##type(lanes); \ + Handle<type> b = factory->New##type(lanes); \ + CHECK(a->BitwiseEquals(*b)); \ + CHECK(a->SameValue(*b)); \ + CHECK(a->SameValueZero(*b)); \ + CHECK_EQ(a->Hash(), b->Hash()); \ + for (int i = 0; i < lane_count; i++) { \ + a->set_lane(i, true); \ + CHECK(!a->BitwiseEquals(*b)); \ + CHECK_NE(a->Hash(), b->Hash()); \ + CHECK(!a->SameValue(*b)); \ + CHECK(!a->SameValueZero(*b)); \ + b->set_lane(i, true); \ + CHECK(a->BitwiseEquals(*b)); \ + CHECK_EQ(a->Hash(), b->Hash()); \ + CHECK(a->SameValue(*b)); \ + CHECK(a->SameValueZero(*b)); \ + } \ + } + +TEST(SimdTypes) { + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + + HandleScope sc(isolate); + + FLOAT_TEST(Float32x4, 4) + INT_TEST(Int32x4, 4, int32_t) + BOOL_TEST(Bool32x4, 4) + INT_TEST(Int16x8, 8, int16_t) + BOOL_TEST(Bool16x8, 8) + INT_TEST(Int8x16, 16, int8_t) + BOOL_TEST(Bool8x16, 16) +} diff --git a/deps/v8/test/cctest/test-spaces.cc b/deps/v8/test/cctest/test-spaces.cc index 3f5e437223..86500c52d3 100644 --- a/deps/v8/test/cctest/test-spaces.cc +++ b/deps/v8/test/cctest/test-spaces.cc @@ -309,7 +309,7 @@ TEST(MemoryAllocator) { heap->MaxExecutableSize())); int total_pages = 0; - OldSpace faked_space(heap, heap->MaxReserved(), OLD_SPACE, NOT_EXECUTABLE); + OldSpace faked_space(heap, OLD_SPACE, NOT_EXECUTABLE); Page* first_page = memory_allocator->AllocatePage( faked_space.AreaSize(), &faked_space, NOT_EXECUTABLE); @@ -379,8 +379,7 @@ TEST(OldSpace) { heap->MaxExecutableSize())); TestMemoryAllocatorScope test_scope(isolate, memory_allocator); - OldSpace* s = new OldSpace(heap, heap->MaxOldGenerationSize(), OLD_SPACE, - NOT_EXECUTABLE); + OldSpace* s = new OldSpace(heap, OLD_SPACE, NOT_EXECUTABLE); CHECK(s != NULL); CHECK(s->SetUp()); diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc index d8d7c96871..ce60b95495 100644 --- a/deps/v8/test/cctest/test-strings.cc +++ b/deps/v8/test/cctest/test-strings.cc @@ -1085,8 +1085,9 @@ TEST(CachedHashOverflow) { CHECK_EQ(results[i]->IsUndefined(), result->IsUndefined()); CHECK_EQ(results[i]->IsNumber(), result->IsNumber()); if (result->IsNumber()) { - CHECK_EQ(Object::ToSmi(isolate, results[i]).ToHandleChecked()->value(), - result->ToInt32(CcTest::isolate())->Value()); + int32_t value = 0; + CHECK(results[i]->ToInt32(&value)); + CHECK_EQ(value, result->ToInt32(CcTest::isolate())->Value()); } } } @@ -1209,8 +1210,8 @@ TEST(SliceFromSlice) { UNINITIALIZED_TEST(OneByteArrayJoin) { v8::Isolate::CreateParams create_params; // Set heap limits. - create_params.constraints.set_max_semi_space_size(1); - create_params.constraints.set_max_old_space_size(6); + create_params.constraints.set_max_semi_space_size(1 * Page::kPageSize / MB); + create_params.constraints.set_max_old_space_size(6 * Page::kPageSize / MB); create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); v8::Isolate* isolate = v8::Isolate::New(create_params); isolate->Enter(); diff --git a/deps/v8/test/cctest/test-threads.cc b/deps/v8/test/cctest/test-threads.cc index 5f2cdae2a2..a9058a523a 100644 --- a/deps/v8/test/cctest/test-threads.cc +++ b/deps/v8/test/cctest/test-threads.cc @@ -32,88 +32,6 @@ #include "src/isolate.h" -enum Turn { FILL_CACHE, CLEAN_CACHE, SECOND_TIME_FILL_CACHE, CACHE_DONE }; - -static Turn turn = FILL_CACHE; - - -class ThreadA : public v8::base::Thread { - public: - ThreadA() : Thread(Options("ThreadA")) {} - void Run() { - v8::Isolate* isolate = CcTest::isolate(); - v8::Locker locker(isolate); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope scope(isolate); - v8::Handle<v8::Context> context = v8::Context::New(isolate); - v8::Context::Scope context_scope(context); - - CHECK_EQ(FILL_CACHE, turn); - - // Fill String.search cache. - v8::Handle<v8::Script> script = v8::Script::Compile( - v8::String::NewFromUtf8( - isolate, - "for (var i = 0; i < 3; i++) {" - " var result = \"a\".search(\"a\");" - " if (result != 0) throw \"result: \" + result + \" @\" + i;" - "};" - "true")); - CHECK(script->Run()->IsTrue()); - - turn = CLEAN_CACHE; - do { - { - v8::Unlocker unlocker(CcTest::isolate()); - } - } while (turn != SECOND_TIME_FILL_CACHE); - - // Rerun the script. - CHECK(script->Run()->IsTrue()); - - turn = CACHE_DONE; - } -}; - - -class ThreadB : public v8::base::Thread { - public: - ThreadB() : Thread(Options("ThreadB")) {} - void Run() { - do { - { - v8::Isolate* isolate = CcTest::isolate(); - v8::Locker locker(isolate); - v8::Isolate::Scope isolate_scope(isolate); - if (turn == CLEAN_CACHE) { - v8::HandleScope scope(isolate); - v8::Handle<v8::Context> context = v8::Context::New(isolate); - v8::Context::Scope context_scope(context); - - // Clear the caches by forcing major GC. - CcTest::heap()->CollectAllGarbage(); - turn = SECOND_TIME_FILL_CACHE; - break; - } - } - } while (true); - } -}; - - -TEST(JSFunctionResultCachesInTwoThreads) { - ThreadA threadA; - ThreadB threadB; - - threadA.Start(); - threadB.Start(); - - threadA.Join(); - threadB.Join(); - - CHECK_EQ(CACHE_DONE, turn); -} - class ThreadIdValidationThread : public v8::base::Thread { public: ThreadIdValidationThread(v8::base::Thread* thread_to_start, diff --git a/deps/v8/test/cctest/test-unboxed-doubles.cc b/deps/v8/test/cctest/test-unboxed-doubles.cc index 4746e47322..3a629bdca0 100644 --- a/deps/v8/test/cctest/test-unboxed-doubles.cc +++ b/deps/v8/test/cctest/test-unboxed-doubles.cc @@ -634,7 +634,7 @@ static Handle<LayoutDescriptor> TestLayoutDescriptorAppend( descriptors->Append(&f); int field_index = f.GetDetails().field_index(); - bool is_inobject = field_index < map->inobject_properties(); + bool is_inobject = field_index < map->GetInObjectProperties(); for (int bit = 0; bit < field_width_in_words; bit++) { CHECK_EQ(is_inobject && (kind == PROP_DOUBLE), !layout_descriptor->IsTagged(field_index + bit)); @@ -763,7 +763,7 @@ static Handle<LayoutDescriptor> TestLayoutDescriptorAppendIfFastOrUseFull( int field_index = details.field_index(); int field_width_in_words = details.field_width_in_words(); - bool is_inobject = field_index < map->inobject_properties(); + bool is_inobject = field_index < map->GetInObjectProperties(); for (int bit = 0; bit < field_width_in_words; bit++) { CHECK_EQ(is_inobject && details.representation().IsDouble(), !layout_desc->IsTagged(field_index + bit)); @@ -1017,7 +1017,7 @@ TEST(DoScavenge) { INSERT_TRANSITION).ToHandleChecked(); // Create object in new space. - Handle<JSObject> obj = factory->NewJSObjectFromMap(map, NOT_TENURED, false); + Handle<JSObject> obj = factory->NewJSObjectFromMap(map, NOT_TENURED); Handle<HeapNumber> heap_number = factory->NewHeapNumber(42.5); obj->WriteToField(0, *heap_number); @@ -1094,7 +1094,7 @@ TEST(DoScavengeWithIncrementalWriteBarrier) { } // Create object in new space. - Handle<JSObject> obj = factory->NewJSObjectFromMap(map, NOT_TENURED, false); + Handle<JSObject> obj = factory->NewJSObjectFromMap(map, NOT_TENURED); Handle<HeapNumber> heap_number = factory->NewHeapNumber(42.5); obj->WriteToField(0, *heap_number); @@ -1351,7 +1351,7 @@ TEST(StoreBufferScanOnScavenge) { INSERT_TRANSITION).ToHandleChecked(); // Create object in new space. - Handle<JSObject> obj = factory->NewJSObjectFromMap(map, NOT_TENURED, false); + Handle<JSObject> obj = factory->NewJSObjectFromMap(map, NOT_TENURED); Handle<HeapNumber> heap_number = factory->NewHeapNumber(42.5); obj->WriteToField(0, *heap_number); @@ -1423,9 +1423,6 @@ TEST(WriteBarriersInCopyJSObject) { my_map = Map::CopyWithField(my_map, name, HeapType::Any(isolate), NONE, Representation::Double(), INSERT_TRANSITION).ToHandleChecked(); - my_map->set_pre_allocated_property_fields(1); - int n_properties = my_map->InitialPropertiesLength(); - CHECK_GE(n_properties, 0); int object_size = my_map->instance_size(); @@ -1503,7 +1500,7 @@ static void TestWriteBarrier(Handle<Map> map, Handle<Map> new_map, Handle<HeapObject> obj_value; { AlwaysAllocateScope always_allocate(isolate); - obj = factory->NewJSObjectFromMap(map, TENURED, false); + obj = factory->NewJSObjectFromMap(map, TENURED); CHECK(old_space->Contains(*obj)); obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS); @@ -1568,7 +1565,7 @@ static void TestIncrementalWriteBarrier(Handle<Map> map, Handle<Map> new_map, Page* ec_page; { AlwaysAllocateScope always_allocate(isolate); - obj = factory->NewJSObjectFromMap(map, TENURED, false); + obj = factory->NewJSObjectFromMap(map, TENURED); CHECK(old_space->Contains(*obj)); // Make sure |obj_value| is placed on an old-space evacuation candidate. diff --git a/deps/v8/test/intl/number-format/check-minimum-fraction-digits.js b/deps/v8/test/intl/number-format/check-minimum-fraction-digits.js new file mode 100755 index 0000000000..57e65be55e --- /dev/null +++ b/deps/v8/test/intl/number-format/check-minimum-fraction-digits.js @@ -0,0 +1,9 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Make sure minimumFractionDigits is honored + +var nf = new Intl.NumberFormat("en-us",{ useGrouping: false, minimumFractionDigits: 4}); + +assertEquals("12345.6789", nf.format(12345.6789)); diff --git a/deps/v8/test/intl/number-format/format-currency.js b/deps/v8/test/intl/number-format/format-currency.js new file mode 100755 index 0000000000..004c566ce4 --- /dev/null +++ b/deps/v8/test/intl/number-format/format-currency.js @@ -0,0 +1,19 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Make sure currency formatting is correct (for USD only displays two decimal +// places, for JPY 0, and for EUR 2). + +var nf_USD = new Intl.NumberFormat(['en'], {style: 'currency', currency: 'USD'}); + +assertEquals("$54,306.40", nf_USD.format(parseFloat(54306.4047970))); + +var nf_JPY = new Intl.NumberFormat(['ja'], + {style: 'currency', currency: 'JPY', currencyDisplay: "code"}); + +assertEquals("JPY54,306", nf_JPY.format(parseFloat(54306.4047970))); + +var nf_EUR = new Intl.NumberFormat(['pt'], {style: 'currency', currency: 'EUR'}); + +assertEquals("ā¬1.000,00", nf_EUR.format(1000.00)); diff --git a/deps/v8/test/intl/string/normalization.js b/deps/v8/test/intl/string/normalization.js index 446d6277db..25d314ea28 100644 --- a/deps/v8/test/intl/string/normalization.js +++ b/deps/v8/test/intl/string/normalization.js @@ -27,6 +27,8 @@ // Tests the new String.prototype.normalize method. +assertEquals(String.prototype.normalize.length, 0); +assertEquals(String.prototype.propertyIsEnumerable("normalize"), false); // Common use case when searching for 'not very exact' match. // These are examples of data one might encounter in real use. diff --git a/deps/v8/test/message/arrow-formal-parameters.js b/deps/v8/test/message/arrow-formal-parameters.js new file mode 100644 index 0000000000..edc0c58053 --- /dev/null +++ b/deps/v8/test/message/arrow-formal-parameters.js @@ -0,0 +1,7 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-arrow-functions + +(b, a, a, d) => a diff --git a/deps/v8/test/message/arrow-formal-parameters.out b/deps/v8/test/message/arrow-formal-parameters.out new file mode 100644 index 0000000000..ee918493f5 --- /dev/null +++ b/deps/v8/test/message/arrow-formal-parameters.out @@ -0,0 +1,4 @@ +*%(basename)s:7: SyntaxError: Duplicate parameter name not allowed in this context +(b, a, a, d) => a + ^ +SyntaxError: Duplicate parameter name not allowed in this context diff --git a/deps/v8/test/message/for-loop-invalid-lhs.js b/deps/v8/test/message/for-loop-invalid-lhs.js new file mode 100644 index 0000000000..c545230348 --- /dev/null +++ b/deps/v8/test/message/for-loop-invalid-lhs.js @@ -0,0 +1,9 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// TODO(adamk): Remove flag after the test runner tests all message tests with +// the preparser: https://code.google.com/p/v8/issues/detail?id=4372 +// Flags: --min-preparse-length=0 + +function f() { for ("unassignable" in {}); } diff --git a/deps/v8/test/message/for-loop-invalid-lhs.out b/deps/v8/test/message/for-loop-invalid-lhs.out new file mode 100644 index 0000000000..1972146f87 --- /dev/null +++ b/deps/v8/test/message/for-loop-invalid-lhs.out @@ -0,0 +1,4 @@ +*%(basename)s:9: SyntaxError: Invalid left-hand side in for-loop +function f() { for ("unassignable" in {}); } + ^^^^^^^^^^^^^^ +SyntaxError: Invalid left-hand side in for-loop diff --git a/deps/v8/test/message/new-target-assignment.js b/deps/v8/test/message/new-target-assignment.js new file mode 100644 index 0000000000..f257d1a5b5 --- /dev/null +++ b/deps/v8/test/message/new-target-assignment.js @@ -0,0 +1,7 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --harmony-new-target + +function f() { new.target = 5 } diff --git a/deps/v8/test/message/new-target-assignment.out b/deps/v8/test/message/new-target-assignment.out new file mode 100644 index 0000000000..5431bd0fc0 --- /dev/null +++ b/deps/v8/test/message/new-target-assignment.out @@ -0,0 +1,4 @@ +*%(basename)s:7: ReferenceError: Invalid left-hand side in assignment +function f() { new.target = 5 } + ^^^^^^^^^^ +ReferenceError: Invalid left-hand side in assignment diff --git a/deps/v8/test/message/new-target-for-loop.js b/deps/v8/test/message/new-target-for-loop.js new file mode 100644 index 0000000000..76a8eecba2 --- /dev/null +++ b/deps/v8/test/message/new-target-for-loop.js @@ -0,0 +1,7 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --harmony-new-target + +function f() { for (new.target in {}); } diff --git a/deps/v8/test/message/new-target-for-loop.out b/deps/v8/test/message/new-target-for-loop.out new file mode 100644 index 0000000000..342b1315e9 --- /dev/null +++ b/deps/v8/test/message/new-target-for-loop.out @@ -0,0 +1,4 @@ +*%(basename)s:7: SyntaxError: Invalid left-hand side in for-loop +function f() { for (new.target in {}); } + ^^^^^^^^^^ +SyntaxError: Invalid left-hand side in for-loop diff --git a/deps/v8/test/message/new-target-postfix-op.js b/deps/v8/test/message/new-target-postfix-op.js new file mode 100644 index 0000000000..573f3ae3a7 --- /dev/null +++ b/deps/v8/test/message/new-target-postfix-op.js @@ -0,0 +1,7 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --harmony-new-target + +function f() { new.target++ } diff --git a/deps/v8/test/message/new-target-postfix-op.out b/deps/v8/test/message/new-target-postfix-op.out new file mode 100644 index 0000000000..17f2081ed6 --- /dev/null +++ b/deps/v8/test/message/new-target-postfix-op.out @@ -0,0 +1,4 @@ +*%(basename)s:7: ReferenceError: Invalid left-hand side expression in postfix operation +function f() { new.target++ } + ^^^^^^^^^^ +ReferenceError: Invalid left-hand side expression in postfix operation diff --git a/deps/v8/test/message/new-target-prefix-op.js b/deps/v8/test/message/new-target-prefix-op.js new file mode 100644 index 0000000000..ad2f98a46c --- /dev/null +++ b/deps/v8/test/message/new-target-prefix-op.js @@ -0,0 +1,7 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --harmony-new-target + +function f() { ++new.target } diff --git a/deps/v8/test/message/new-target-prefix-op.out b/deps/v8/test/message/new-target-prefix-op.out new file mode 100644 index 0000000000..19c847f23e --- /dev/null +++ b/deps/v8/test/message/new-target-prefix-op.out @@ -0,0 +1,4 @@ +*%(basename)s:7: ReferenceError: Invalid left-hand side expression in prefix operation +function f() { ++new.target } + ^^^^^^^^^^ +ReferenceError: Invalid left-hand side expression in prefix operation diff --git a/deps/v8/test/message/strict-formal-parameters.out b/deps/v8/test/message/strict-formal-parameters.out index 3648d38586..3ea3f233b7 100644 --- a/deps/v8/test/message/strict-formal-parameters.out +++ b/deps/v8/test/message/strict-formal-parameters.out @@ -1,4 +1,4 @@ -*%(basename)s:6: SyntaxError: Strict mode function may not have duplicate parameter names +*%(basename)s:6: SyntaxError: Duplicate parameter name not allowed in this context function foo(b, a, a, d) { return a } ^ -SyntaxError: Strict mode function may not have duplicate parameter names +SyntaxError: Duplicate parameter name not allowed in this context diff --git a/deps/v8/test/mjsunit/array-functions-prototype-misc.js b/deps/v8/test/mjsunit/array-functions-prototype-misc.js index 74dc9a6be0..a2c1410837 100644 --- a/deps/v8/test/mjsunit/array-functions-prototype-misc.js +++ b/deps/v8/test/mjsunit/array-functions-prototype-misc.js @@ -312,3 +312,75 @@ Array.prototype[1] = undefined; // Test http://code.google.com/p/chromium/issues/detail?id=21860 Array.prototype.push.apply([], [1].splice(0, -(-1 % 5))); + + +// Check that the Array functions work also properly on non-Arrays +var receiver; + +receiver = 'a string'; +assertThrows(function(){ + Array.prototype.push.call(receiver); +}); + +receiver = 0; +assertEquals(undefined, receiver.length); +assertEquals(0, Array.prototype.push.call(receiver)); +assertEquals(1, Array.prototype.push.call(receiver, 'first')); +assertEquals(undefined, receiver.length); + +receiver = {}; +assertEquals(undefined, receiver.length); +assertEquals(0, Array.prototype.push.call(receiver)); +assertEquals(0, Array.prototype.push.call(receiver)); +assertEquals(0, receiver.length); +assertEquals(1, Array.prototype.push.call(receiver, 'first')); +assertEquals(1, receiver.length); +assertEquals('first', receiver[0]); +assertEquals(2, Array.prototype.push.call(receiver, 'second')); +assertEquals(2, receiver.length); +assertEquals('first', receiver[0]); +assertEquals('second', receiver[1]); + +receiver = {'length': 10}; +assertEquals(10, Array.prototype.push.call(receiver)); +assertEquals(10, receiver.length); +assertEquals(11, Array.prototype.push.call(receiver, 'first')); +assertEquals(11, receiver.length); +assertEquals('first', receiver[10]); +assertEquals(13, Array.prototype.push.call(receiver, 'second', 'third')); +assertEquals(13, receiver.length); +assertEquals('first', receiver[10]); +assertEquals('second', receiver[11]); +assertEquals('third', receiver[12]); + +receiver = { + get length() { return 10; }, + set length(l) {} +}; +assertEquals(10, Array.prototype.push.call(receiver)); +assertEquals(10, receiver.length); +assertEquals(11, Array.prototype.push.call(receiver, 'first')); +assertEquals(10, receiver.length); +assertEquals('first', receiver[10]); +assertEquals(12, Array.prototype.push.call(receiver, 'second', 'third')); +assertEquals(10, receiver.length); +assertEquals('second', receiver[10]); +assertEquals('third', receiver[11]); + +// readonly length +receiver = { + get length() { return 10; }, +}; +assertThrows(function(){ + Array.prototype.push.call(receiver); +}); + +receiver = { + set length(l) {} +}; +assertEquals(0, Array.prototype.push.call(receiver)); +assertEquals(undefined, receiver.length); +assertEquals(1, Array.prototype.push.call(receiver, 'first')); +assertEquals(undefined, receiver.length); +assertEquals(2, Array.prototype.push.call(receiver, 'third', 'second')); +assertEquals(undefined, receiver.length); diff --git a/deps/v8/test/mjsunit/array-push7.js b/deps/v8/test/mjsunit/array-push7.js index b45a739d70..68c3a2a76e 100644 --- a/deps/v8/test/mjsunit/array-push7.js +++ b/deps/v8/test/mjsunit/array-push7.js @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Flags: --harmony-object-observe // Flags: --allow-natives-syntax var v = 0; diff --git a/deps/v8/test/mjsunit/compiler/string-length.js b/deps/v8/test/mjsunit/compiler/string-length.js new file mode 100644 index 0000000000..855a1a6b71 --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/string-length.js @@ -0,0 +1,31 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +assertEquals(0, "".length); +assertEquals(1, "a".length); +assertEquals(2, ("a" + "b").length); + +function id(x) { return x; } + +function f1(x) { + return x.length; +} +assertEquals(0, f1("")); +assertEquals(1, f1("a")); +%OptimizeFunctionOnNextCall(f1); +assertEquals(2, f1("a" + "b")); +assertEquals(3, f1(id("a") + id("b" + id("c")))) + +function f2(x, y, z) { + x = x ? "" + y : "" + z; + return x.length; +} +assertEquals(0, f2(true, "", "a")); +assertEquals(1, f2(false, "", "a")); +%OptimizeFunctionOnNextCall(f2); +assertEquals(0, f2(true, "", "a")); +assertEquals(1, f2(false, "", "a")); +assertEquals(3, f2(true, id("a") + id("b" + id("c")), "")); diff --git a/deps/v8/test/mjsunit/compiler/stubs/floor-stub.js b/deps/v8/test/mjsunit/compiler/stubs/floor-stub.js index e3fc9b6003..0a76d307ba 100644 --- a/deps/v8/test/mjsunit/compiler/stubs/floor-stub.js +++ b/deps/v8/test/mjsunit/compiler/stubs/floor-stub.js @@ -25,30 +25,37 @@ // (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-natives-as=builtins --noalways-opt +// Flags: --allow-natives-syntax --noalways-opt --turbo-filter=* + +var stubs = %GetCodeStubExportsObject(); const kExtraTypeFeedbackMinusZeroSentinel = 1; +const kFirstJSFunctionTypeFeedbackIndex = 5; const kFirstSlotExtraTypeFeedbackIndex = 5; -(function(){ - var floorFunc = function() { - Math.floor(NaN); +(function() { + var stub1 = stubs.MathFloorStub("MathFloorStub", 1); + var tempForTypeVector = function(d) { + return Math.round(d); } - // Execute the function once to make sure it has a type feedback vector. - floorFunc(5); - var stub = builtins.MathFloorStub("MathFloorStub", 0); + tempForTypeVector(5); + var tv = %GetTypeFeedbackVector(tempForTypeVector); + var floorFunc1 = function(v, first) { + if (first) return; + return stub1(stub1, kFirstSlotExtraTypeFeedbackIndex - 1, tv, undefined, v); + }; + %OptimizeFunctionOnNextCall(stub1); + floorFunc1(5, true); + %FixedArraySet(tv, kFirstSlotExtraTypeFeedbackIndex - 1, stub1); assertTrue(kExtraTypeFeedbackMinusZeroSentinel !== - %FixedArrayGet(%GetTypeFeedbackVector(floorFunc), - kFirstSlotExtraTypeFeedbackIndex)); - assertEquals(5.0, stub(floorFunc, 4, 5.5)); + %FixedArrayGet(tv, kFirstSlotExtraTypeFeedbackIndex)); + assertEquals(5.0, floorFunc1(5.5)); assertTrue(kExtraTypeFeedbackMinusZeroSentinel !== - %FixedArrayGet(%GetTypeFeedbackVector(floorFunc), - kFirstSlotExtraTypeFeedbackIndex)); + %FixedArrayGet(tv, kFirstSlotExtraTypeFeedbackIndex)); // Executing floor such that it returns -0 should set the proper sentinel in // the feedback vector. - assertEquals(-Infinity, 1/stub(floorFunc, 4, -0)); + assertEquals(-Infinity, 1/floorFunc1(-0)); assertEquals(kExtraTypeFeedbackMinusZeroSentinel, - %FixedArrayGet(%GetTypeFeedbackVector(floorFunc), - kFirstSlotExtraTypeFeedbackIndex)); - %ClearFunctionTypeFeedback(floorFunc); + %FixedArrayGet(tv, kFirstSlotExtraTypeFeedbackIndex)); + %ClearFunctionTypeFeedback(floorFunc1); })(); diff --git a/deps/v8/test/mjsunit/d8-worker-sharedarraybuffer.js b/deps/v8/test/mjsunit/d8-worker-sharedarraybuffer.js index 791529fc89..d432f97074 100644 --- a/deps/v8/test/mjsunit/d8-worker-sharedarraybuffer.js +++ b/deps/v8/test/mjsunit/d8-worker-sharedarraybuffer.js @@ -27,42 +27,80 @@ // Flags: --harmony-sharedarraybuffer --harmony-atomics -var workerScript = - `onmessage = function(m) { - var sab = m; - var ta = new Uint32Array(sab); - if (sab.byteLength !== 16) { - throw new Error('SharedArrayBuffer transfer byteLength'); - } - for (var i = 0; i < 4; ++i) { - if (ta[i] !== i) { - throw new Error('SharedArrayBuffer transfer value ' + i); - } - } - // Atomically update ta[0] - Atomics.store(ta, 0, 100); - };`; - if (this.Worker) { - var w = new Worker(workerScript); - var sab = new SharedArrayBuffer(16); - var ta = new Uint32Array(sab); - for (var i = 0; i < 4; ++i) { - ta[i] = i; - } + (function TestTransfer() { + var workerScript = + `onmessage = function(m) { + var sab = m; + var ta = new Uint32Array(sab); + if (sab.byteLength !== 16) { + throw new Error('SharedArrayBuffer transfer byteLength'); + } + for (var i = 0; i < 4; ++i) { + if (ta[i] !== i) { + throw new Error('SharedArrayBuffer transfer value ' + i); + } + } + // Atomically update ta[0] + Atomics.store(ta, 0, 100); + };`; + + var w = new Worker(workerScript); + + var sab = new SharedArrayBuffer(16); + var ta = new Uint32Array(sab); + for (var i = 0; i < 4; ++i) { + ta[i] = i; + } + + // Transfer SharedArrayBuffer + w.postMessage(sab, [sab]); + assertEquals(16, sab.byteLength); // ArrayBuffer should not be neutered. + + // Spinwait for the worker to update ta[0] + var ta0; + while ((ta0 = Atomics.load(ta, 0)) == 0) {} + + assertEquals(100, ta0); + + w.terminate(); + + assertEquals(16, sab.byteLength); // Still not neutered. + })(); - // Transfer SharedArrayBuffer - w.postMessage(sab, [sab]); - assertEquals(16, sab.byteLength); // ArrayBuffer should not be neutered. + (function TestTransferMulti() { + var workerScript = + `onmessage = function(msg) { + var sab = msg.sab; + var id = msg.id; + var ta = new Uint32Array(sab); + Atomics.store(ta, id, 1); + postMessage(id); + };`; - // Spinwait for the worker to update ta[0] - var ta0; - while ((ta0 = Atomics.load(ta, 0)) == 0) {} + var sab = new SharedArrayBuffer(16); + var ta = new Uint32Array(sab); - assertEquals(100, ta0); + var id; + var workers = []; + for (id = 0; id < 4; ++id) { + workers[id] = new Worker(workerScript); + workers[id].postMessage({sab: sab, id: id}, [sab]); + } - w.terminate(); + // Spinwait for each worker to update ta[id] + var count = 0; + while (count < 4) { + for (id = 0; id < 4; ++id) { + if (Atomics.compareExchange(ta, id, 1, -1) == 1) { + // Worker is finished. + assertEquals(id, workers[id].getMessage()); + workers[id].terminate(); + count++; + } + } + } + })(); - assertEquals(16, sab.byteLength); // Still not neutered. } diff --git a/deps/v8/test/mjsunit/date-parse.js b/deps/v8/test/mjsunit/date-parse.js index cb4a951c7a..4cd8aa9c3e 100644 --- a/deps/v8/test/mjsunit/date-parse.js +++ b/deps/v8/test/mjsunit/date-parse.js @@ -244,14 +244,22 @@ var testCasesES5Misc = [ ['2000-01T08:00:00.001Z', 946713600001], ['2000-01T08:00:00.099Z', 946713600099], ['2000-01T08:00:00.999Z', 946713600999], - ['2000-01T00:00:00.001-08:00', 946713600001]]; + ['2000-01T00:00:00.001-08:00', 946713600001], + ['2000-01-01T24:00Z', 946771200000], + ['2000-01-01T24:00:00Z', 946771200000], + ['2000-01-01T24:00:00.000Z', 946771200000], + ['2000-01-01T24:00:00.000Z', 946771200000]]; var testCasesES5MiscNegative = [ '2000-01-01TZ', '2000-01-01T60Z', '2000-01-01T60:60Z', '2000-01-0108:00Z', - '2000-01-01T08Z']; + '2000-01-01T08Z', + '2000-01-01T24:01', + '2000-01-01T24:00:01', + '2000-01-01T24:00:00.001', + '2000-01-01T24:00:00.999Z']; // Run all the tests. diff --git a/deps/v8/test/mjsunit/date.js b/deps/v8/test/mjsunit/date.js index 0fa23f8de1..adebbd141f 100644 --- a/deps/v8/test/mjsunit/date.js +++ b/deps/v8/test/mjsunit/date.js @@ -203,110 +203,110 @@ assertEquals(-8640000000000000, Date.UTC(1970, 0, 1 - 100000001, 24)); // Parsing ES5 ISO-8601 dates. -// When TZ is omitted, it defaults to 'Z' meaning UTC. +// When TZ is omitted, it defaults to the local timezone // Check epoch. assertEquals(0, Date.parse("1970-01-01T00:00:00.000+00:00")); assertEquals(0, Date.parse("1970-01-01T00:00:00.000-00:00")); assertEquals(0, Date.parse("1970-01-01T00:00:00.000Z")); -assertEquals(0, Date.parse("1970-01-01T00:00:00.000")); -assertEquals(0, Date.parse("1970-01-01T00:00:00")); -assertEquals(0, Date.parse("1970-01-01T00:00")); -assertEquals(0, Date.parse("1970-01-01")); +assertEquals(0, Date.parse("1970-01-01T00:00:00.000Z")); +assertEquals(0, Date.parse("1970-01-01T00:00:00Z")); +assertEquals(0, Date.parse("1970-01-01T00:00Z")); +assertEquals(0, Date.parse("1970-01-01Z")); assertEquals(0, Date.parse("1970-01T00:00:00.000+00:00")); assertEquals(0, Date.parse("1970-01T00:00:00.000-00:00")); assertEquals(0, Date.parse("1970-01T00:00:00.000Z")); -assertEquals(0, Date.parse("1970-01T00:00:00.000")); -assertEquals(0, Date.parse("1970-01T00:00:00")); -assertEquals(0, Date.parse("1970-01T00:00")); -assertEquals(0, Date.parse("1970-01")); +assertEquals(0, Date.parse("1970-01T00:00:00.000Z")); +assertEquals(0, Date.parse("1970-01T00:00:00Z")); +assertEquals(0, Date.parse("1970-01T00:00Z")); +assertEquals(0, Date.parse("1970-01Z")); assertEquals(0, Date.parse("1970T00:00:00.000+00:00")); assertEquals(0, Date.parse("1970T00:00:00.000-00:00")); assertEquals(0, Date.parse("1970T00:00:00.000Z")); -assertEquals(0, Date.parse("1970T00:00:00.000")); -assertEquals(0, Date.parse("1970T00:00:00")); -assertEquals(0, Date.parse("1970T00:00")); -assertEquals(0, Date.parse("1970")); +assertEquals(0, Date.parse("1970T00:00:00.000Z")); +assertEquals(0, Date.parse("1970T00:00:00Z")); +assertEquals(0, Date.parse("1970T00:00Z")); +assertEquals(0, Date.parse("1970Z")); assertEquals(0, Date.parse("+001970-01-01T00:00:00.000+00:00")); assertEquals(0, Date.parse("+001970-01-01T00:00:00.000-00:00")); assertEquals(0, Date.parse("+001970-01-01T00:00:00.000Z")); -assertEquals(0, Date.parse("+001970-01-01T00:00:00.000")); -assertEquals(0, Date.parse("+001970-01-01T00:00:00")); -assertEquals(0, Date.parse("+001970-01-01T00:00")); -assertEquals(0, Date.parse("+001970-01-01")); +assertEquals(0, Date.parse("+001970-01-01T00:00:00.000Z")); +assertEquals(0, Date.parse("+001970-01-01T00:00:00Z")); +assertEquals(0, Date.parse("+001970-01-01T00:00Z")); +assertEquals(0, Date.parse("+001970-01-01Z")); assertEquals(0, Date.parse("+001970-01T00:00:00.000+00:00")); assertEquals(0, Date.parse("+001970-01T00:00:00.000-00:00")); assertEquals(0, Date.parse("+001970-01T00:00:00.000Z")); -assertEquals(0, Date.parse("+001970-01T00:00:00.000")); -assertEquals(0, Date.parse("+001970-01T00:00:00")); -assertEquals(0, Date.parse("+001970-01T00:00")); -assertEquals(0, Date.parse("+001970-01")); +assertEquals(0, Date.parse("+001970-01T00:00:00.000Z")); +assertEquals(0, Date.parse("+001970-01T00:00:00Z")); +assertEquals(0, Date.parse("+001970-01T00:00Z")); +assertEquals(0, Date.parse("+001970-01Z")); assertEquals(0, Date.parse("+001970T00:00:00.000+00:00")); assertEquals(0, Date.parse("+001970T00:00:00.000-00:00")); assertEquals(0, Date.parse("+001970T00:00:00.000Z")); -assertEquals(0, Date.parse("+001970T00:00:00.000")); -assertEquals(0, Date.parse("+001970T00:00:00")); -assertEquals(0, Date.parse("+001970T00:00")); -assertEquals(0, Date.parse("+001970")); +assertEquals(0, Date.parse("+001970T00:00:00.000Z")); +assertEquals(0, Date.parse("+001970T00:00:00Z")); +assertEquals(0, Date.parse("+001970T00:00Z")); +assertEquals(0, Date.parse("+001970Z")); // Check random date. assertEquals(70671003500, Date.parse("1972-03-28T23:50:03.500+01:00")); assertEquals(70674603500, Date.parse("1972-03-28T23:50:03.500Z")); -assertEquals(70674603500, Date.parse("1972-03-28T23:50:03.500")); -assertEquals(70674603000, Date.parse("1972-03-28T23:50:03")); -assertEquals(70674600000, Date.parse("1972-03-28T23:50")); -assertEquals(70588800000, Date.parse("1972-03-28")); +assertEquals(70674603500, Date.parse("1972-03-28T23:50:03.500Z")); +assertEquals(70674603000, Date.parse("1972-03-28T23:50:03Z")); +assertEquals(70674600000, Date.parse("1972-03-28T23:50Z")); +assertEquals(70588800000, Date.parse("1972-03-28Z")); assertEquals(68338203500, Date.parse("1972-03T23:50:03.500+01:00")); assertEquals(68341803500, Date.parse("1972-03T23:50:03.500Z")); -assertEquals(68341803500, Date.parse("1972-03T23:50:03.500")); -assertEquals(68341803000, Date.parse("1972-03T23:50:03")); -assertEquals(68341800000, Date.parse("1972-03T23:50")); -assertEquals(68256000000, Date.parse("1972-03")); +assertEquals(68341803500, Date.parse("1972-03T23:50:03.500Z")); +assertEquals(68341803000, Date.parse("1972-03T23:50:03Z")); +assertEquals(68341800000, Date.parse("1972-03T23:50Z")); +assertEquals(68256000000, Date.parse("1972-03Z")); assertEquals(63154203500, Date.parse("1972T23:50:03.500+01:00")); assertEquals(63157803500, Date.parse("1972T23:50:03.500Z")); -assertEquals(63157803500, Date.parse("1972T23:50:03.500")); -assertEquals(63157803000, Date.parse("1972T23:50:03")); -assertEquals(63072000000, Date.parse("1972")); +assertEquals(63157803500, Date.parse("1972T23:50:03.500Z")); +assertEquals(63157803000, Date.parse("1972T23:50:03Z")); +assertEquals(63072000000, Date.parse("1972Z")); assertEquals(70671003500, Date.parse("+001972-03-28T23:50:03.500+01:00")); assertEquals(70674603500, Date.parse("+001972-03-28T23:50:03.500Z")); -assertEquals(70674603500, Date.parse("+001972-03-28T23:50:03.500")); -assertEquals(70674603000, Date.parse("+001972-03-28T23:50:03")); -assertEquals(70674600000, Date.parse("+001972-03-28T23:50")); -assertEquals(70588800000, Date.parse("+001972-03-28")); +assertEquals(70674603500, Date.parse("+001972-03-28T23:50:03.500Z")); +assertEquals(70674603000, Date.parse("+001972-03-28T23:50:03Z")); +assertEquals(70674600000, Date.parse("+001972-03-28T23:50Z")); +assertEquals(70588800000, Date.parse("+001972-03-28Z")); assertEquals(68338203500, Date.parse("+001972-03T23:50:03.500+01:00")); assertEquals(68341803500, Date.parse("+001972-03T23:50:03.500Z")); -assertEquals(68341803500, Date.parse("+001972-03T23:50:03.500")); -assertEquals(68341803000, Date.parse("+001972-03T23:50:03")); -assertEquals(68341800000, Date.parse("+001972-03T23:50")); -assertEquals(68256000000, Date.parse("+001972-03")); +assertEquals(68341803500, Date.parse("+001972-03T23:50:03.500Z")); +assertEquals(68341803000, Date.parse("+001972-03T23:50:03Z")); +assertEquals(68341800000, Date.parse("+001972-03T23:50Z")); +assertEquals(68256000000, Date.parse("+001972-03Z")); assertEquals(63154203500, Date.parse("+001972T23:50:03.500+01:00")); assertEquals(63157803500, Date.parse("+001972T23:50:03.500Z")); -assertEquals(63157803500, Date.parse("+001972T23:50:03.500")); -assertEquals(63157803000, Date.parse("+001972T23:50:03")); -assertEquals(63072000000, Date.parse("+001972")); +assertEquals(63157803500, Date.parse("+001972T23:50:03.500Z")); +assertEquals(63157803000, Date.parse("+001972T23:50:03Z")); +assertEquals(63072000000, Date.parse("+001972Z")); // Ensure that ISO-years in the range 00-99 aren't translated to the range // 1950..2049. -assertEquals(-60904915200000, Date.parse("0040-01-01")); -assertEquals(-60273763200000, Date.parse("0060-01-01")); -assertEquals(-62167219200000, Date.parse("0000-01-01")); -assertEquals(-62167219200000, Date.parse("+000000-01-01")); +assertEquals(-60904915200000, Date.parse("0040-01-01T00:00Z")); +assertEquals(-60273763200000, Date.parse("0060-01-01T00:00Z")); +assertEquals(-62167219200000, Date.parse("0000-01-01T00:00Z")); +assertEquals(-62167219200000, Date.parse("+000000-01-01T00:00Z")); // Test negative years. -assertEquals(-63429523200000, Date.parse("-000040-01-01")); -assertEquals(-64060675200000, Date.parse("-000060-01-01")); -assertEquals(-124397510400000, Date.parse("-001972-01-01")); +assertEquals(-63429523200000, Date.parse("-000040-01-01Z")); +assertEquals(-64060675200000, Date.parse("-000060-01-01Z")); +assertEquals(-124397510400000, Date.parse("-001972-01-01Z")); // Check time-zones. assertEquals(70674603500, Date.parse("1972-03-28T23:50:03.500Z")); diff --git a/deps/v8/test/mjsunit/debug-evaluate.js b/deps/v8/test/mjsunit/debug-evaluate.js index accf656d60..46eddef9c4 100644 --- a/deps/v8/test/mjsunit/debug-evaluate.js +++ b/deps/v8/test/mjsunit/debug-evaluate.js @@ -136,6 +136,7 @@ function f() { function g() { var a = 2; f(); + return a; // Use the value to prevent it being removed by DCE. }; a = 1; diff --git a/deps/v8/test/mjsunit/debug-function-scopes.js b/deps/v8/test/mjsunit/debug-function-scopes.js index 8992fe79c5..fac3b16b8d 100644 --- a/deps/v8/test/mjsunit/debug-function-scopes.js +++ b/deps/v8/test/mjsunit/debug-function-scopes.js @@ -42,7 +42,7 @@ function CheckScope(scope_mirror, scope_expectations, expected_scope_type) { } } -// A copy of the scope types from mirror-debugger.js. +// A copy of the scope types from debug/mirrors.js. var ScopeType = { Global: 0, Local: 1, With: 2, diff --git a/deps/v8/test/mjsunit/debug-liveedit-restart-frame.js b/deps/v8/test/mjsunit/debug-liveedit-restart-frame.js index d978a9709f..a3182d7bfa 100644 --- a/deps/v8/test/mjsunit/debug-liveedit-restart-frame.js +++ b/deps/v8/test/mjsunit/debug-liveedit-restart-frame.js @@ -97,8 +97,9 @@ function TestCase(test_scenario, expected_output) { return; } var frame = FindCallFrame(exec_state, change_code); - // Throws if fails. - Debug.LiveEdit.RestartFrame(frame); + var error = frame.restart(); + if (typeof error === 'string') + throw new Error(error); } } diff --git a/deps/v8/test/mjsunit/debug-materialized.js b/deps/v8/test/mjsunit/debug-materialized.js new file mode 100644 index 0000000000..0b01b78df4 --- /dev/null +++ b/deps/v8/test/mjsunit/debug-materialized.js @@ -0,0 +1,41 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --expose-debug-as debug + +function dbg(x) { + debugger; +} + +function foo() { + arguments[0]; + dbg(); +} + +function bar() { + var t = { a : 1 }; + dbg(); + return t.a; +} + +foo(1); +foo(1); +bar(1); +bar(1); +%OptimizeFunctionOnNextCall(foo); +%OptimizeFunctionOnNextCall(bar); + +var Debug = debug.Debug; +Debug.setListener(function(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + for (var i = 0; i < exec_state.frameCount(); i++) { + var f = exec_state.frame(i); + for (var j = 0; j < f.localCount(); j++) { + print("'" + f.localName(j) + "' = " + f.localValue(j).value()); + } + } +}); + +foo(1); +bar(1); diff --git a/deps/v8/test/mjsunit/debug-mirror-cache.js b/deps/v8/test/mjsunit/debug-mirror-cache.js index c690aa0133..8ac6d9a70d 100644 --- a/deps/v8/test/mjsunit/debug-mirror-cache.js +++ b/deps/v8/test/mjsunit/debug-mirror-cache.js @@ -51,8 +51,7 @@ function listener(event, exec_state, event_data, data) { listenerCallCount++; // Check that mirror cache is cleared when entering debugger. - assertEquals(0, debug.next_handle_, "Mirror cache not cleared"); - assertEquals(0, debug.mirror_cache_.length, "Mirror cache not cleared"); + assertTrue(debug.MirrorCacheIsEmpty(), "Mirror cache not cleared"); // Get the debug command processor in paused state. var dcp = exec_state.debugCommandProcessor(false); @@ -66,8 +65,7 @@ function listener(event, exec_state, event_data, data) { Debug.scripts(); // Some mirrors where cached. - assertFalse(debug.next_handle_ == 0, "Mirror cache not used"); - assertFalse(debug.mirror_cache_.length == 0, "Mirror cache not used"); + assertFalse(debug.MirrorCacheIsEmpty(), "Mirror cache not used"); } } catch (e) { print(e); diff --git a/deps/v8/test/mjsunit/debug-optimize.js b/deps/v8/test/mjsunit/debug-optimize.js new file mode 100644 index 0000000000..d1ce63d5a0 --- /dev/null +++ b/deps/v8/test/mjsunit/debug-optimize.js @@ -0,0 +1,54 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug --allow-natives-syntax --use-inlining + +var Debug = debug.Debug; + +function f1() { + return 1; +} + +function f2() { + return 2; +} + +function f3() { + return f1(); +} + +function f4() { + return 4; +} + + +function optimize(f) { + f(); + f(); + %OptimizeFunctionOnNextCall(f); + f(); +} + +optimize(f1); +optimize(f2); +optimize(f3); + +Debug.setListener(function() {}); + +assertOptimized(f1); +assertOptimized(f2); +assertOptimized(f3); + +Debug.setBreakPoint(f1, 1); + +// Setting break point deoptimizes f1 and f3 (which inlines f1). +assertUnoptimized(f1); +assertOptimized(f2); +assertUnoptimized(f3); + +// We can optimize with break points set. +optimize(f4); +assertOptimized(f4); + +Debug.setListener(null); diff --git a/deps/v8/test/mjsunit/debug-return-value.js b/deps/v8/test/mjsunit/debug-return-value.js index 02d6a7cbc9..3ea106c40f 100644 --- a/deps/v8/test/mjsunit/debug-return-value.js +++ b/deps/v8/test/mjsunit/debug-return-value.js @@ -124,6 +124,7 @@ function listener(event, exec_state, event_data, data) { } } catch (e) { exception = e + print(e + e.stack) }; }; diff --git a/deps/v8/test/mjsunit/debug-script-breakpoints.js b/deps/v8/test/mjsunit/debug-script-breakpoints.js index d4ce6dc98b..6f31ef11d8 100644 --- a/deps/v8/test/mjsunit/debug-script-breakpoints.js +++ b/deps/v8/test/mjsunit/debug-script-breakpoints.js @@ -30,37 +30,51 @@ Debug = debug.Debug Debug.setListener(function(){}); +var script_id; +var script_name; + +// Get current script id and name. +var scripts = Debug.scripts(); +for (var i = 0; i < scripts.length; i++) { + var name = scripts[i].name; + var id = scripts[i].id; + if (name !== undefined && name.includes("debug-script-breakpoints.js")) { + script_id = id; + script_name = name; + break; + } +} +assertTrue(script_id !== undefined); +assertTrue(script_name !== undefined); +print("#" + script_id + ": " + script_name); + + +// Checks script name, line and column. +var checkBreakPoint = function(id, line, column) { + var breakpoint = Debug.scriptBreakPoints()[id]; + assertEquals(script_name, breakpoint.script_name()); + assertEquals(line, breakpoint.line()); + assertEquals(column, breakpoint.column()); +} + + // Set and remove a script break point for a named script. -var sbp = Debug.setScriptBreakPointByName("1", 2, 3); +var sbp = Debug.setScriptBreakPointByName(script_name, 35, 5); assertEquals(1, Debug.scriptBreakPoints().length); -assertEquals("1", Debug.scriptBreakPoints()[0].script_name()); -assertEquals(2, Debug.scriptBreakPoints()[0].line()); -assertEquals(3, Debug.scriptBreakPoints()[0].column()); +checkBreakPoint(0, 35, 5); Debug.clearBreakPoint(sbp); assertEquals(0, Debug.scriptBreakPoints().length); // Set three script break points for named scripts. -var sbp1 = Debug.setScriptBreakPointByName("1", 2, 3); -var sbp2 = Debug.setScriptBreakPointByName("2", 3, 4); -var sbp3 = Debug.setScriptBreakPointByName("3", 4, 5); +var sbp1 = Debug.setScriptBreakPointByName(script_name, 36, 3); +var sbp2 = Debug.setScriptBreakPointByName(script_name, 37, 4); +var sbp3 = Debug.setScriptBreakPointByName(script_name, 38, 5); // Check the content of the script break points. assertEquals(3, Debug.scriptBreakPoints().length); -for (var i = 0; i < Debug.scriptBreakPoints().length; i++) { - var x = Debug.scriptBreakPoints()[i]; - if ("1" == x.script_name()) { - assertEquals(2, x.line()); - assertEquals(3, x.column()); - } else if ("2" == x.script_name()) { - assertEquals(3, x.line()); - assertEquals(4, x.column()); - } else if ("3" == x.script_name()) { - assertEquals(4, x.line()); - assertEquals(5, x.column()); - } else { - assertUnreachable("unecpected script_name " + x.script_name()); - } -} +checkBreakPoint(0, 36, 3); +checkBreakPoint(1, 37, 4); +checkBreakPoint(2, 38, 5); // Remove script break points (in another order than they where added). assertEquals(3, Debug.scriptBreakPoints().length); @@ -71,37 +85,33 @@ assertEquals(1, Debug.scriptBreakPoints().length); Debug.clearBreakPoint(sbp2); assertEquals(0, Debug.scriptBreakPoints().length); + +// Checks script id, line and column. +var checkBreakPoint = function(id, line, column) { + var breakpoint = Debug.scriptBreakPoints()[id]; + assertEquals(script_id, breakpoint.script_id()); + assertEquals(line, breakpoint.line()); + assertEquals(column, breakpoint.column()); +} + + // Set and remove a script break point for a script id. -var sbp = Debug.setScriptBreakPointById(1, 2, 3); +var sbp = Debug.setScriptBreakPointById(script_id, 40, 6); assertEquals(1, Debug.scriptBreakPoints().length); -assertEquals(1, Debug.scriptBreakPoints()[0].script_id()); -assertEquals(2, Debug.scriptBreakPoints()[0].line()); -assertEquals(3, Debug.scriptBreakPoints()[0].column()); +checkBreakPoint(0, 40, 6); Debug.clearBreakPoint(sbp); assertEquals(0, Debug.scriptBreakPoints().length); // Set three script break points for script ids. -var sbp1 = Debug.setScriptBreakPointById(1, 2, 3); -var sbp2 = Debug.setScriptBreakPointById(2, 3, 4); -var sbp3 = Debug.setScriptBreakPointById(3, 4, 5); +var sbp1 = Debug.setScriptBreakPointById(script_id, 42, 3); +var sbp2 = Debug.setScriptBreakPointById(script_id, 43, 4); +var sbp3 = Debug.setScriptBreakPointById(script_id, 44, 5); // Check the content of the script break points. assertEquals(3, Debug.scriptBreakPoints().length); -for (var i = 0; i < Debug.scriptBreakPoints().length; i++) { - var x = Debug.scriptBreakPoints()[i]; - if (1 == x.script_id()) { - assertEquals(2, x.line()); - assertEquals(3, x.column()); - } else if (2 == x.script_id()) { - assertEquals(3, x.line()); - assertEquals(4, x.column()); - } else if (3 == x.script_id()) { - assertEquals(4, x.line()); - assertEquals(5, x.column()); - } else { - assertUnreachable("unecpected script_id " + x.script_id()); - } -} +checkBreakPoint(0, 42, 3); +checkBreakPoint(1, 43, 4); +checkBreakPoint(2, 44, 5); // Remove script break points (in another order than they where added). assertEquals(3, Debug.scriptBreakPoints().length); diff --git a/deps/v8/test/mjsunit/debug-stepin-construct-call.js b/deps/v8/test/mjsunit/debug-stepin-construct-call.js new file mode 100644 index 0000000000..5e2145591f --- /dev/null +++ b/deps/v8/test/mjsunit/debug-stepin-construct-call.js @@ -0,0 +1,42 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug + +var break_count = 0; +var exception = null; + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var source_line = exec_state.frame(0).sourceLineText(); + print(source_line); + exec_state.prepareStep(Debug.StepAction.StepIn, 1); + break_count++; + } catch (e) { + exception = e; + } +} + +var Debug = debug.Debug; +Debug.setListener(listener); + + +function f() { + this.x = 1; +} + +function g() { + new f(); +} + +Debug.setBreakPoint(g, 6, Debug.BreakPositionAlignment.BreakPosition); +print(Debug.showBreakPoints(g, undefined, + Debug.BreakPositionAlignment.BreakPosition)); + +g(); +Debug.setListener(null); + +assertEquals(6, break_count); +assertNull(exception); diff --git a/deps/v8/test/mjsunit/element-accessor.js b/deps/v8/test/mjsunit/element-accessor.js new file mode 100644 index 0000000000..452afc8d16 --- /dev/null +++ b/deps/v8/test/mjsunit/element-accessor.js @@ -0,0 +1,33 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(function () { + var o = []; + o.__proto__ = {}; + + function store(o, i, v) { + o[i] = v; + } + + store(o, 0, 0); + store(o, 1, 0); + store(o, 2, 0); + o.__proto__[10000000] = 1; + + var set = 0; + + Object.defineProperty(o, "3", { + get:function() { return 100; }, + set:function(v) { set = v; }}); + + store(o, 3, 1000); + assertEquals(1000, set); + assertEquals(100, o[3]); +})(); + +(function () { + var o = new Int32Array(); + Object.defineProperty(o, "0", {get: function(){}}); + assertEquals(undefined, Object.getOwnPropertyDescriptor(o, "0")); +})(); diff --git a/deps/v8/test/mjsunit/element-read-only.js b/deps/v8/test/mjsunit/element-read-only.js new file mode 100644 index 0000000000..9ec027f6cc --- /dev/null +++ b/deps/v8/test/mjsunit/element-read-only.js @@ -0,0 +1,154 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function f(a, b, c, d) { return arguments; } + +// Ensure non-configurable argument elements stay non-configurable. +(function () { + var args = f(1); + Object.defineProperty(args, "0", {value: 10, configurable: false}); + assertFalse(Object.getOwnPropertyDescriptor(args, "0").configurable); + for (var i = 0; i < 10; i++) { + args[i] = 1; + } + assertFalse(Object.getOwnPropertyDescriptor(args, "0").configurable); +})(); + +// Ensure read-only properties on the prototype chain cause TypeError. + +// Newly added. +(function () { + var o = []; + var proto = {}; + var index = 3; + function store(o, i, v) { "use strict"; o[i] = v; }; + o.__proto__ = proto; + for (var i = 0; i < index; i++) { + store(o, i, 0); + } + Object.defineProperty(proto, index, {value: 100, writable: false}); + assertThrows(function() { store(o, index, 0); }); + assertEquals(100, o[index]); +})(); + +// Reconfigured. +(function () { + var o = []; + var proto = {3: 10000}; + var index = 3; + function store(o, i, v) { "use strict"; o[i] = v; }; + o.__proto__ = proto; + for (var i = 0; i < index; i++) { + store(o, i, 0); + } + Object.defineProperty(proto, index, {value: 100, writable: false}); + assertThrows(function() { store(o, index, 0); }); + assertEquals(100, o[index]); +})(); + +// Newly added to arguments object. +(function () { + var o = []; + var proto = f(100); + var index = 3; + function store(o, i, v) { "use strict"; o[i] = v; }; + o.__proto__ = proto; + for (var i = 0; i < index; i++) { + store(o, i, 0); + } + Object.defineProperty(proto, index, {value: 100, writable: false}); + assertThrows(function() { store(o, index, 0); }); + assertEquals(100, o[index]); +})(); + +// Reconfigured on to arguments object. +(function () { + var o = []; + var proto = f(100, 200, 300, 400); + var index = 3; + function store(o, i, v) { "use strict"; o[i] = v; }; + o.__proto__ = proto; + for (var i = 0; i < index; i++) { + store(o, i, 0); + } + Object.defineProperty(proto, index, {value: 100, writable: false}); + assertThrows(function() { store(o, index, 0); }); + assertEquals(100, o[index]); +})(); + +// Extensions prevented object. +(function () { + var o = []; + var proto = [0, 1, 2, 3]; + var index = 3; + function store(o, i, v) { "use strict"; o[i] = v; }; + o.__proto__ = proto; + for (var i = 0; i < index; i++) { + store(o, i, 0); + } + Object.preventExtensions(proto); + Object.defineProperty(proto, index, {value: 100, writable: false}); + assertThrows(function() { store(o, index, 0); }); + assertEquals(100, o[index]); +})(); + +// Extensions prevented arguments object. +(function () { + var o = []; + var proto = f(100, 200, 300, 400); + var index = 3; + function store(o, i, v) { "use strict"; o[i] = v; }; + o.__proto__ = proto; + for (var i = 0; i < index; i++) { + store(o, i, 0); + } + Object.preventExtensions(proto); + Object.defineProperty(proto, index, {value: 100, writable: false}); + assertThrows(function() { store(o, index, 0); }); + assertEquals(100, o[index]); +})(); + +// Array with large index. +(function () { + var o = []; + var proto = []; + var index = 3; + function store(o, i, v) { "use strict"; o[i] = v; }; + o.__proto__ = proto; + for (var i = 0; i < index; i++) { + store(o, i, 0); + } + proto[1 << 30] = 1; + Object.defineProperty(proto, index, {value: 100, writable: false}); + assertThrows(function() { store(o, index, 0); }); + assertEquals(100, o[index]); +})(); + +// Frozen object. +(function () { + var o = []; + var proto = [0, 1, 2, 3]; + function store(o, i, v) { "use strict"; o[i] = v; }; + o.__proto__ = proto; + for (var i = 0; i < 3; i++) { + store(o, i, 0); + } + Object.freeze(proto); + assertThrows(function() { store(o, 3, 0); }); + assertEquals(3, o[3]); +})(); + +// Frozen arguments object. +(function () { + var o = []; + var proto = f(0, 1, 2, 3); + function store(o, i, v) { "use strict"; o[i] = v; }; + o.__proto__ = proto; + for (var i = 0; i < 3; i++) { + store(o, i, 0); + } + Object.freeze(proto); + assertThrows(function() { store(o, 3, 0); }); + assertEquals(3, o[3]); +})(); diff --git a/deps/v8/test/mjsunit/elements-kind.js b/deps/v8/test/mjsunit/elements-kind.js index cb2d178a7e..4da8a9dc60 100644 --- a/deps/v8/test/mjsunit/elements-kind.js +++ b/deps/v8/test/mjsunit/elements-kind.js @@ -32,15 +32,6 @@ var elements_kind = { fast : 'fast elements', fast_double : 'fast double elements', dictionary : 'dictionary elements', - external_int32 : 'external int8 elements', - external_uint8 : 'external uint8 elements', - external_int16 : 'external int16 elements', - external_uint16 : 'external uint16 elements', - external_int32 : 'external int32 elements', - external_uint32 : 'external uint32 elements', - external_float32 : 'external float32 elements', - external_float64 : 'external float64 elements', - external_uint8_clamped : 'external uint8_clamped elements', fixed_int32 : 'fixed int8 elements', fixed_uint8 : 'fixed uint8 elements', fixed_int16 : 'fixed int16 elements', @@ -58,34 +49,6 @@ function getKind(obj) { if (%HasFastDoubleElements(obj)) return elements_kind.fast_double; if (%HasDictionaryElements(obj)) return elements_kind.dictionary; - // Every external kind is also an external array. - if (%HasExternalInt8Elements(obj)) { - return elements_kind.external_int8; - } - if (%HasExternalUint8Elements(obj)) { - return elements_kind.external_uint8; - } - if (%HasExternalInt16Elements(obj)) { - return elements_kind.external_int16; - } - if (%HasExternalUint16Elements(obj)) { - return elements_kind.external_uint16; - } - if (%HasExternalInt32Elements(obj)) { - return elements_kind.external_int32; - } - if (%HasExternalUint32Elements(obj)) { - return elements_kind.external_uint32; - } - if (%HasExternalFloat32Elements(obj)) { - return elements_kind.external_float32; - } - if (%HasExternalFloat64Elements(obj)) { - return elements_kind.external_float64; - } - if (%HasExternalUint8ClampedElements(obj)) { - return elements_kind.external_uint8_clamped; - } if (%HasFixedInt8Elements(obj)) { return elements_kind.fixed_int8; } @@ -164,15 +127,15 @@ function test_wrapper() { assertKind(elements_kind.fixed_uint8_clamped, new Uint8ClampedArray(512)); var ab = new ArrayBuffer(128); - assertKind(elements_kind.external_int8, new Int8Array(ab)); - assertKind(elements_kind.external_uint8, new Uint8Array(ab)); - assertKind(elements_kind.external_int16, new Int16Array(ab)); - assertKind(elements_kind.external_uint16, new Uint16Array(ab)); - assertKind(elements_kind.external_int32, new Int32Array(ab)); - assertKind(elements_kind.external_uint32, new Uint32Array(ab)); - assertKind(elements_kind.external_float32, new Float32Array(ab)); - assertKind(elements_kind.external_float64, new Float64Array(ab)); - assertKind(elements_kind.external_uint8_clamped, new Uint8ClampedArray(ab)); + assertKind(elements_kind.fixed_int8, new Int8Array(ab)); + assertKind(elements_kind.fixed_uint8, new Uint8Array(ab)); + assertKind(elements_kind.fixed_int16, new Int16Array(ab)); + assertKind(elements_kind.fixed_uint16, new Uint16Array(ab)); + assertKind(elements_kind.fixed_int32, new Int32Array(ab)); + assertKind(elements_kind.fixed_uint32, new Uint32Array(ab)); + assertKind(elements_kind.fixed_float32, new Float32Array(ab)); + assertKind(elements_kind.fixed_float64, new Float64Array(ab)); + assertKind(elements_kind.fixed_uint8_clamped, new Uint8ClampedArray(ab)); // Crankshaft support for smi-only array elements. function monomorphic(array) { diff --git a/deps/v8/test/mjsunit/error-constructors.js b/deps/v8/test/mjsunit/error-constructors.js index 84c6bbfd0c..1ada39de55 100644 --- a/deps/v8/test/mjsunit/error-constructors.js +++ b/deps/v8/test/mjsunit/error-constructors.js @@ -25,8 +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. -// Flags: --allow-natives-syntax - // Check that message and name are not enumerable on Error objects. var desc = Object.getOwnPropertyDescriptor(Error.prototype, 'name'); assertFalse(desc['enumerable']); @@ -62,33 +60,65 @@ var e = new ReferenceError('123'); assertTrue(e.hasOwnProperty('message')); assertTrue(e.hasOwnProperty('stack')); -var e = %MakeReferenceError("my_test_error", [0, 1]); +try { + eval("var error = reference"); +} catch (error) { + e = error; +} + assertTrue(e.hasOwnProperty('stack')); // Check that intercepting property access from toString is prevented for // compiler errors. This is not specified, but allowing interception // through a getter can leak error objects from different // script tags in the same context in a browser setting. -var errors = [SyntaxError, ReferenceError, TypeError]; +var errors = [SyntaxError, ReferenceError, TypeError, RangeError, URIError]; +var error_triggers = ["syntax error", + "var error = reference", + "undefined()", + "String.fromCodePoint(0xFFFFFF)", + "decodeURI('%F')"]; for (var i in errors) { - var name = errors[i].prototype.toString(); + var name = errors[i].name; + // Monkey-patch prototype. var props = ["name", "message", "stack"]; for (var j in props) { errors[i].prototype.__defineGetter__(props[j], fail); } // String conversion should not invoke monkey-patched getters on prototype. - var e = new errors[i]; - assertEquals(name, e.toString()); + var error; + try { + eval(error_triggers[i]); + } catch (e) { + error = e; + } + assertTrue(error.toString().startsWith(name)); + + // Deleting message on the error (exposing the getter) is fine. + delete error.message; + assertEquals(name, error.toString()); + + // Custom properties shadowing the name are fine. + var myerror = { name: "myerror", message: "mymessage"}; + myerror.__proto__ = error; + assertEquals("myerror: mymessage", myerror.toString()); + // Custom getters in actual objects are welcome. - e.__defineGetter__("name", function() { return "mine"; }); - assertEquals("mine", e.toString()); + error.__defineGetter__("name", function() { return "mine"; }); + assertEquals("mine", error.toString()); + + // Custom properties shadowing the name are fine. + var myerror2 = { message: "mymessage"}; + myerror2.__proto__ = error; + assertEquals("mine: mymessage", myerror2.toString()); } -// Monkey-patching non-static errors should still be observable. +// Monkey-patching non-internal errors should still be observable. function MyError() {} MyError.prototype = new Error; -var errors = [Error, RangeError, EvalError, URIError, MyError]; +var errors = [Error, RangeError, EvalError, URIError, + SyntaxError, ReferenceError, TypeError, MyError]; for (var i in errors) { errors[i].prototype.__defineGetter__("name", function() { return "my"; }); errors[i].prototype.__defineGetter__("message", function() { return "moo"; }); diff --git a/deps/v8/test/mjsunit/es6/array-iterator.js b/deps/v8/test/mjsunit/es6/array-iterator.js index 767991eafe..5fab0fbf86 100644 --- a/deps/v8/test/mjsunit/es6/array-iterator.js +++ b/deps/v8/test/mjsunit/es6/array-iterator.js @@ -47,6 +47,9 @@ function TestArrayPrototype() { assertHasOwnProperty(Array.prototype, 'entries', DONT_ENUM); assertHasOwnProperty(Array.prototype, 'keys', DONT_ENUM); assertHasOwnProperty(Array.prototype, Symbol.iterator, DONT_ENUM); + assertEquals('entries', Array.prototype.entries.name); + assertEquals('keys', Array.prototype.keys.name); + assertEquals('values', Array.prototype[Symbol.iterator].name); } TestArrayPrototype(); diff --git a/deps/v8/test/mjsunit/es6/array-reverse-order.js b/deps/v8/test/mjsunit/es6/array-reverse-order.js new file mode 100644 index 0000000000..590491cb68 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/array-reverse-order.js @@ -0,0 +1,10 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ES6 specifically says that elements should be checked with [[HasElement]] before +// [[Get]]. This is observable in case a getter deletes elements. ES5 put the +// [[HasElement]] after the [[Get]]. + +assertTrue(1 in Array.prototype.reverse.call( + {length:2, get 0(){delete this[0];}, 1: "b"})) diff --git a/deps/v8/test/mjsunit/es6/block-conflicts.js b/deps/v8/test/mjsunit/es6/block-conflicts.js index fdd581dd70..0e3d4e5a2a 100644 --- a/deps/v8/test/mjsunit/es6/block-conflicts.js +++ b/deps/v8/test/mjsunit/es6/block-conflicts.js @@ -79,7 +79,11 @@ var letbinds = [ "let x;", "const x = function() {};", "const x = 2, y = 3;", "const y = 4, x = 5;", + "class x { }", ]; +function forCompatible(bind) { + return !bind.startsWith('class'); +} var varbinds = [ "var x;", "var x = 0;", "var x = undefined;", @@ -101,7 +105,9 @@ for (var l = 0; l < letbinds.length; ++l) { TestNoConflict(varbinds[v] + '{' + letbinds[l] + '}'); TestNoConflict('{' + letbinds[l] + '}' + varbinds[v]); // For loop. - TestConflict('for (' + letbinds[l] + '0;) {' + varbinds[v] + '}'); + if (forCompatible(letbinds[l])) { + TestConflict('for (' + letbinds[l] + '0;) {' + varbinds[v] + '}'); + } TestNoConflict('for (' + varbinds[v] + '0;) {' + letbinds[l] + '}'); } @@ -114,8 +120,12 @@ for (var l = 0; l < letbinds.length; ++l) { TestNoConflict(letbinds[l] + '{ ' + letbinds[k] + '}'); TestNoConflict('{' + letbinds[k] +'} ' + letbinds[l]); // For loop. - TestNoConflict('for (' + letbinds[l] + '0;) {' + letbinds[k] + '}'); - TestNoConflict('for (' + letbinds[k] + '0;) {' + letbinds[l] + '}'); + if (forCompatible(letbinds[l])) { + TestNoConflict('for (' + letbinds[l] + '0;) {' + letbinds[k] + '}'); + } + if (forCompatible(letbinds[k])) { + TestNoConflict('for (' + letbinds[k] + '0;) {' + letbinds[l] + '}'); + } } // Test conflicting function/let bindings. @@ -128,7 +138,9 @@ for (var l = 0; l < letbinds.length; ++l) { TestNoConflict(funbind + '{' + letbinds[l] + '}'); TestNoConflict('{' + letbinds[l] + '}' + funbind); // For loop. - TestNoConflict('for (' + letbinds[l] + '0;) {' + funbind + '}'); + if (forCompatible(letbinds[l])) { + TestNoConflict('for (' + letbinds[l] + '0;) {' + funbind + '}'); + } // Test conflicting parameter/let bindings. TestConflict('(function(x) {' + letbinds[l] + '})();'); diff --git a/deps/v8/test/mjsunit/es6/block-const-assign.js b/deps/v8/test/mjsunit/es6/block-const-assign.js index f78faa689d..541dc0d97b 100644 --- a/deps/v8/test/mjsunit/es6/block-const-assign.js +++ b/deps/v8/test/mjsunit/es6/block-const-assign.js @@ -25,8 +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. -// Flags: --harmony-computed-property-names - // 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. diff --git a/deps/v8/test/mjsunit/es6/block-leave.js b/deps/v8/test/mjsunit/es6/block-leave.js index 338631b76e..4c63b77319 100644 --- a/deps/v8/test/mjsunit/es6/block-leave.js +++ b/deps/v8/test/mjsunit/es6/block-leave.js @@ -175,7 +175,7 @@ try { // Verify that the context is correctly set in the stack frame after exiting -// from with. +// from eval. function f() {} (function(x) { diff --git a/deps/v8/test/mjsunit/es6/block-let-declaration.js b/deps/v8/test/mjsunit/es6/block-let-declaration.js index 5fbb12824b..a138144d18 100644 --- a/deps/v8/test/mjsunit/es6/block-let-declaration.js +++ b/deps/v8/test/mjsunit/es6/block-let-declaration.js @@ -33,17 +33,20 @@ let x; let y = 2; const z = 4; +class c { static foo() { return 1; } } // Block local { let y; let x = 3; const z = 5; + class c { static foo() { return 2; } } } assertEquals(undefined, x); assertEquals(2,y); assertEquals(4,z); +assertEquals(1, c.foo()); if (true) { let y; @@ -106,6 +109,16 @@ TestLocalDoesNotThrow("for (;false;) var x;"); TestLocalDoesNotThrow("switch (true) { case true: var x; }"); TestLocalDoesNotThrow("switch (true) { default: var x; }"); +// Test class declarations with initialisers in statement positions. +TestLocalThrows("if (true) class x { };", SyntaxError); +TestLocalThrows("if (true) {} else class x { };", SyntaxError); +TestLocalThrows("do class x { }; while (false)", SyntaxError); +TestLocalThrows("while (false) class x { };", SyntaxError); +TestLocalThrows("label: class x { };", SyntaxError); +TestLocalThrows("for (;false;) class x { };", SyntaxError); +TestLocalDoesNotThrow("switch (true) { case true: class x { }; }"); +TestLocalDoesNotThrow("switch (true) { default: class x { }; }"); + // Test that redeclarations of functions are only allowed in outermost scope. TestLocalThrows("{ let f; var f; }"); TestLocalThrows("{ var f; let f; }"); @@ -113,9 +126,13 @@ TestLocalThrows("{ function f() {} let f; }"); TestLocalThrows("{ let f; function f() {} }"); TestLocalThrows("{ function f() {} var f; }"); TestLocalThrows("{ var f; function f() {} }"); +TestLocalThrows("{ function f() {} class f {} }"); +TestLocalThrows("{ class f {}; function f() {} }"); TestLocalThrows("{ function f() {} function f() {} }"); TestLocalThrows("function f() {} let f;"); TestLocalThrows("let f; function f() {}"); +TestLocalThrows("function f() {} class f {}"); +TestLocalThrows("class f {}; function f() {}"); TestLocalDoesNotThrow("function arg() {}"); TestLocalDoesNotThrow("function f() {} var f;"); TestLocalDoesNotThrow("var f; function f() {}"); diff --git a/deps/v8/test/mjsunit/es6/block-let-semantics.js b/deps/v8/test/mjsunit/es6/block-let-semantics.js index b0a826a007..59eec1ceea 100644 --- a/deps/v8/test/mjsunit/es6/block-let-semantics.js +++ b/deps/v8/test/mjsunit/es6/block-let-semantics.js @@ -70,6 +70,7 @@ TestAll('x += 1; let x;'); TestAll('++x; let x;'); TestAll('x++; let x;'); TestAll('let y = x; const x = 1;'); +TestAll('let y = x; class x {}'); TestAll('f(); let x; function f() { return x + 1; }'); TestAll('f(); let x; function f() { x = 1; }'); @@ -77,6 +78,7 @@ 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(); class x { }; 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; } }'); @@ -84,21 +86,24 @@ 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 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;'); +TestAll('f()(); class x { }; function f() { return function() { return x; } }'); + +for (var kw of ['let x = 2', 'const x = 2', 'class x { }']) { + // Use before initialization with a dynamic lookup. + TestAll(`eval("x"); ${kw};`); + TestAll(`eval("x + 1;"); ${kw};`); + TestAll(`eval("x = 1;"); ${kw};`); + TestAll(`eval("x += 1;"); ${kw};`); + TestAll(`eval("++x;"); ${kw};`); + TestAll(`eval("x++;"); ${kw};`); + + // Use before initialization with check for eval-shadowed bindings. + TestAll(`function f() { eval("var y = 2;"); x + 1; }; f(); ${kw};`); + TestAll(`function f() { eval("var y = 2;"); x = 1; }; f(); ${kw};`); + TestAll(`function f() { eval("var y = 2;"); x += 1; }; f(); ${kw};`); + TestAll(`function f() { eval("var y = 2;"); ++x; }; f(); ${kw};`); + TestAll(`function f() { eval("var y = 2;"); x++; }; f(); ${kw};`); +} // Test that variables introduced by function declarations are created and // initialized upon entering a function / block scope. diff --git a/deps/v8/test/mjsunit/es6/block-scoping.js b/deps/v8/test/mjsunit/es6/block-scoping.js index 5f481b8bf2..719f5231ce 100644 --- a/deps/v8/test/mjsunit/es6/block-scoping.js +++ b/deps/v8/test/mjsunit/es6/block-scoping.js @@ -49,15 +49,19 @@ function f2(one) { var x = one + 1; let y = one + 2; const u = one + 4; + class a { static foo() { return one + 6; } } { let z = one + 3; const v = one + 5; + class b { static foo() { return one + 7; } } assertEquals(1, eval('one')); assertEquals(2, eval('x')); assertEquals(3, eval('y')); assertEquals(4, eval('z')); assertEquals(5, eval('u')); assertEquals(6, eval('v')); + assertEquals(7, eval('a.foo()')); + assertEquals(8, eval('b.foo()')); } } @@ -68,15 +72,19 @@ function f3(one) { var x = one + 1; let y = one + 2; const u = one + 4; + class a { static foo() { return one + 6; } } { let z = one + 3; const v = one + 5; + class b { static foo() { return one + 7; } } assertEquals(1, one); assertEquals(2, x); assertEquals(3, y); assertEquals(4, z); assertEquals(5, u); assertEquals(6, v); + assertEquals(7, a.foo()); + assertEquals(8, b.foo()); } } for (var j = 0; j < 5; ++j) f3(1); @@ -91,9 +99,11 @@ function f4(one) { var x = one + 1; let y = one + 2; const u = one + 4; + class a { static foo() { return one + 6; } } { let z = one + 3; const v = one + 5; + class b { static foo() { return one + 7; } } function f() { assertEquals(1, eval('one')); assertEquals(2, eval('x')); @@ -101,6 +111,8 @@ function f4(one) { assertEquals(4, eval('z')); assertEquals(5, eval('u')); assertEquals(6, eval('v')); + assertEquals(7, eval('a.foo()')); + assertEquals(8, eval('b.foo()')); } f(); } @@ -113,9 +125,11 @@ function f5(one) { var x = one + 1; let y = one + 2; const u = one + 4; + class a { static foo() { return one + 6; } } { let z = one + 3; const v = one + 5; + class b { static foo() { return one + 7; } } function f() { assertEquals(1, one); assertEquals(2, x); @@ -123,6 +137,8 @@ function f5(one) { assertEquals(4, z); assertEquals(5, u); assertEquals(6, v); + assertEquals(7, a.foo()); + assertEquals(8, b.foo()); } f(); } @@ -149,25 +165,43 @@ function f7(a) { var c = 1; var d = 1; const e = 1; - { // let variables shadowing argument, let, const and var variables + class f { static foo() { return 1; } } + { // let variables shadowing argument, let, const, class and var variables let a = 2; let b = 2; let c = 2; let e = 2; + let f = 2; assertEquals(2,a); assertEquals(2,b); assertEquals(2,c); assertEquals(2,e); + assertEquals(2,f); } { // const variables shadowing argument, let, const and var variables const a = 2; const b = 2; const c = 2; const e = 2; + const f = 2; assertEquals(2,a); assertEquals(2,b); assertEquals(2,c); assertEquals(2,e); + assertEquals(2,f); + } + { // class variables shadowing argument, let, const and var variables + class a { static foo() { return 2; } } + class b { static foo() { return 2; } } + class c { static foo() { return 2; } } + class d { static foo() { return 2; } } + class e { static foo() { return 2; } } + class f { static foo() { return 2; } } + assertEquals(2,a.foo()); + assertEquals(2,b.foo()); + assertEquals(2,c.foo()); + assertEquals(2,e.foo()); + assertEquals(2,f.foo()); } try { throw 'stuff1'; @@ -225,16 +259,18 @@ function f7(a) { c = 2; } assertEquals(1,c); - (function(a,b,c,e) { - // arguments shadowing argument, let, const and var variable + (function(a,b,c,e,f) { + // arguments shadowing argument, let, const, class and var variable a = 2; b = 2; c = 2; e = 2; + f = 2; assertEquals(2,a); assertEquals(2,b); assertEquals(2,c); assertEquals(2,e); + assertEquals(2,f); // var variable shadowing var variable var d = 2; })(1,1); @@ -243,6 +279,7 @@ function f7(a) { assertEquals(1,c); assertEquals(1,d); assertEquals(1,e); + assertEquals(1,f.foo()); } f7(1); @@ -253,19 +290,23 @@ function f8() { var let_accessors = []; var var_accessors = []; var const_accessors = []; + var class_accessors = []; for (var i = 0; i < 10; i++) { let x = i; var y = i; const z = i; + class a { static foo() { return x; } } let_accessors[i] = function() { return x; } var_accessors[i] = function() { return y; } const_accessors[i] = function() { return z; } + class_accessors[i] = function() { return a; } } 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]()); + assertEquals(j, class_accessors[j]().foo()); } } f8(); diff --git a/deps/v8/test/mjsunit/harmony/class-computed-property-names-super.js b/deps/v8/test/mjsunit/es6/class-computed-property-names-super.js index a68b53c18f..cb9f25157c 100644 --- a/deps/v8/test/mjsunit/harmony/class-computed-property-names-super.js +++ b/deps/v8/test/mjsunit/es6/class-computed-property-names-super.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-computed-property-names --harmony-sloppy +// Flags: --harmony-sloppy // Flags: --allow-natives-syntax diff --git a/deps/v8/test/mjsunit/harmony/computed-property-names-classes.js b/deps/v8/test/mjsunit/es6/computed-property-names-classes.js index 46a9e9ec2d..eebf99aef5 100644 --- a/deps/v8/test/mjsunit/harmony/computed-property-names-classes.js +++ b/deps/v8/test/mjsunit/es6/computed-property-names-classes.js @@ -4,8 +4,6 @@ 'use strict'; -// Flags: --harmony-computed-property-names - function ID(x) { return x; diff --git a/deps/v8/test/mjsunit/harmony/computed-property-names-deopt.js b/deps/v8/test/mjsunit/es6/computed-property-names-deopt.js index 1f0b0585fc..2f3a597f11 100644 --- a/deps/v8/test/mjsunit/harmony/computed-property-names-deopt.js +++ b/deps/v8/test/mjsunit/es6/computed-property-names-deopt.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-computed-property-names --allow-natives-syntax +// Flags: --allow-natives-syntax (function TestProtoDeopt() { diff --git a/deps/v8/test/mjsunit/harmony/computed-property-names-object-literals-methods.js b/deps/v8/test/mjsunit/es6/computed-property-names-object-literals-methods.js index 7ba15aca92..a5f380ceac 100644 --- a/deps/v8/test/mjsunit/harmony/computed-property-names-object-literals-methods.js +++ b/deps/v8/test/mjsunit/es6/computed-property-names-object-literals-methods.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-computed-property-names - function ID(x) { return x; diff --git a/deps/v8/test/mjsunit/harmony/computed-property-names-super.js b/deps/v8/test/mjsunit/es6/computed-property-names-super.js index bfc31c668f..40b0eab942 100644 --- a/deps/v8/test/mjsunit/harmony/computed-property-names-super.js +++ b/deps/v8/test/mjsunit/es6/computed-property-names-super.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-computed-property-names --allow-natives-syntax +// Flags: --allow-natives-syntax function ID(x) { diff --git a/deps/v8/test/mjsunit/harmony/computed-property-names.js b/deps/v8/test/mjsunit/es6/computed-property-names.js index a559159380..d75278cfe3 100644 --- a/deps/v8/test/mjsunit/harmony/computed-property-names.js +++ b/deps/v8/test/mjsunit/es6/computed-property-names.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-computed-property-names - function ID(x) { return x; diff --git a/deps/v8/test/mjsunit/es6/debug-blockscopes.js b/deps/v8/test/mjsunit/es6/debug-blockscopes.js index 31208d41f4..3f890ebd54 100644 --- a/deps/v8/test/mjsunit/es6/debug-blockscopes.js +++ b/deps/v8/test/mjsunit/es6/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 +// 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. @@ -187,6 +187,14 @@ function CheckScopeContent(content, number, exec_state) { } +function assertEqualsUnlessOptimized(expected, value, f) { + try { + assertEquals(expected, value); + } catch (e) { + assertOptimized(f); + } +} + // Simple empty block scope in local scope. BeginTest("Local block 1"); @@ -517,11 +525,11 @@ function shadowing_1() { { let i = 5; debugger; - assertEquals(27, i); + assertEqualsUnlessOptimized(27, i, shadowing_1); } assertEquals(0, i); debugger; - assertEquals(27, i); + assertEqualsUnlessOptimized(27, i, shadowing_1); } listener_delegate = function (exec_state) { @@ -538,9 +546,9 @@ function shadowing_2() { { let j = 5; debugger; - assertEquals(27, j); + assertEqualsUnlessOptimized(27, j, shadowing_2); } - assertEquals(0, i); + assertEqualsUnlessOptimized(0, i, shadowing_2); } listener_delegate = function (exec_state) { diff --git a/deps/v8/test/mjsunit/es6/debug-function-scopes.js b/deps/v8/test/mjsunit/es6/debug-function-scopes.js index e7049ee3c0..c1a20e7b9e 100644 --- a/deps/v8/test/mjsunit/es6/debug-function-scopes.js +++ b/deps/v8/test/mjsunit/es6/debug-function-scopes.js @@ -45,7 +45,7 @@ function CheckScope(scope_mirror, scope_expectations, expected_scope_type) { } } -// A copy of the scope types from mirror-debugger.js. +// A copy of the scope types from debug/mirrors.js. var ScopeType = { Global: 0, Local: 1, With: 2, diff --git a/deps/v8/test/mjsunit/es6/debug-promises/events.js b/deps/v8/test/mjsunit/es6/debug-promises/events.js index a9f94543f4..3fcb22ff27 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/events.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/events.js @@ -116,9 +116,7 @@ function testDone(iteration) { } var iteration = iteration || 0; - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-all.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-all.js index 0fca57730a..fd4770ebee 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-all.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-all.js @@ -63,10 +63,7 @@ function testDone(iteration) { } } - // Run testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-by-default-reject-handler.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-by-default-reject-handler.js index 63151df016..b7c5861c1f 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-by-default-reject-handler.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-caught-by-default-reject-handler.js @@ -77,10 +77,7 @@ function testDone(iteration) { } } - // Run testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-all.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-all.js index beaf1878fe..0b0c0c8e38 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-all.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-all.js @@ -60,10 +60,7 @@ function testDone(iteration) { } } - // Run testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-late.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-late.js index 4a883da13a..db58790e39 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-late.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-late.js @@ -67,10 +67,7 @@ function testDone(iteration) { } } - // Run testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js index 86e2a815e7..ac23b48b6f 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-uncaught-uncaught.js @@ -60,10 +60,7 @@ function testDone(iteration) { } } - // Run testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js index fc6233da8d..fa263458c4 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-invalid-reject.js @@ -66,10 +66,7 @@ function testDone(iteration) { } } - // Run testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js index 15e464ec60..6b7dc1a77c 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-throw-in-reject.js @@ -78,10 +78,7 @@ function testDone(iteration) { } } - // Run testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js index d11c01ff73..4c57cf0237 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/reject-with-undefined-reject.js @@ -66,10 +66,7 @@ function testDone(iteration) { } } - // Run testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-all.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-all.js index 2fbf05141d..bd6d343f82 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-all.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-all.js @@ -62,10 +62,7 @@ function testDone(iteration) { } } - // Run testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-by-default-reject-handler.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-by-default-reject-handler.js index 36b5565e5f..3c30ad3f7c 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-by-default-reject-handler.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-caught-by-default-reject-handler.js @@ -78,10 +78,7 @@ function testDone(iteration) { } } - // Run testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-all.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-all.js index 72f800bf5b..c4bc6c44e3 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-all.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-all.js @@ -61,10 +61,7 @@ function testDone(iteration) { } } - // Rerun testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-uncaught.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-uncaught.js index 69aa8ebbd2..ba82a1f8cb 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-uncaught.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-uncaught-uncaught.js @@ -61,10 +61,7 @@ function testDone(iteration) { } } - // Run testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js index 1ea1c7f9ff..bd39a155cc 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-with-throw-in-reject.js @@ -81,10 +81,7 @@ function testDone(iteration) { } } - // Run testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-promises/throw-with-undefined-reject.js b/deps/v8/test/mjsunit/es6/debug-promises/throw-with-undefined-reject.js index 94dcdffa22..c88feb9c39 100644 --- a/deps/v8/test/mjsunit/es6/debug-promises/throw-with-undefined-reject.js +++ b/deps/v8/test/mjsunit/es6/debug-promises/throw-with-undefined-reject.js @@ -79,10 +79,7 @@ function testDone(iteration) { } } - // Run testDone through the Object.observe processing loop. - var dummy = {}; - Object.observe(dummy, checkResult); - dummy.dummy = dummy; + %EnqueueMicrotask(checkResult); } testDone(0); diff --git a/deps/v8/test/mjsunit/es6/debug-stepin-microtasks.js b/deps/v8/test/mjsunit/es6/debug-stepin-microtasks.js index 8dbdb3457a..98510ff52b 100644 --- a/deps/v8/test/mjsunit/es6/debug-stepin-microtasks.js +++ b/deps/v8/test/mjsunit/es6/debug-stepin-microtasks.js @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Flags: --harmony-object-observe // Flags: --allow-natives-syntax --expose-debug-as debug Debug = debug.Debug diff --git a/deps/v8/test/mjsunit/es6/microtask-delivery.js b/deps/v8/test/mjsunit/es6/microtask-delivery.js index f74385e635..01b971ddc0 100644 --- a/deps/v8/test/mjsunit/es6/microtask-delivery.js +++ b/deps/v8/test/mjsunit/es6/microtask-delivery.js @@ -25,6 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Flags: --harmony-object-observe // Flags: --allow-natives-syntax var ordering = []; diff --git a/deps/v8/test/mjsunit/es6/promises.js b/deps/v8/test/mjsunit/es6/promises.js index 63b6d2f94a..19239b601b 100644 --- a/deps/v8/test/mjsunit/es6/promises.js +++ b/deps/v8/test/mjsunit/es6/promises.js @@ -29,7 +29,6 @@ // Make sure we don't rely on functions patchable by monkeys. var call = Function.prototype.call.call.bind(Function.prototype.call) -var observe = Object.observe; var getOwnPropertyNames = Object.getOwnPropertyNames; var defineProperty = Object.defineProperty; var numberPrototype = Number.prototype; @@ -87,19 +86,15 @@ function assertAsync(b, s) { } function assertAsyncDone(iteration) { - var iteration = iteration || 0 - var dummy = {} - observe(dummy, - function() { - if (asyncAssertsExpected === 0) - assertAsync(true, "all") - else if (iteration > 10) // Shouldn't take more. - assertAsync(false, "all") - else - assertAsyncDone(iteration + 1) - } - ) - dummy.dummy = dummy + var iteration = iteration || 0; + %EnqueueMicrotask(function() { + if (asyncAssertsExpected === 0) + assertAsync(true, "all") + else if (iteration > 10) // Shouldn't take more. + assertAsync(false, "all") + else + assertAsyncDone(iteration + 1) + }); } diff --git a/deps/v8/test/mjsunit/es6/regress/regress-3750.js b/deps/v8/test/mjsunit/es6/regress/regress-3750.js index a425def2b7..10509bff51 100644 --- a/deps/v8/test/mjsunit/es6/regress/regress-3750.js +++ b/deps/v8/test/mjsunit/es6/regress/regress-3750.js @@ -1,6 +1,8 @@ // Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// +// Flags: --harmony-object-observe 'use strict'; class Example { } diff --git a/deps/v8/test/mjsunit/es6/regress/regress-cr512574.js b/deps/v8/test/mjsunit/es6/regress/regress-cr512574.js new file mode 100644 index 0000000000..2c10e19315 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/regress/regress-cr512574.js @@ -0,0 +1,9 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-destructuring + +function f({}) { + for (var v in []); +}; diff --git a/deps/v8/test/mjsunit/es6/templates.js b/deps/v8/test/mjsunit/es6/templates.js index feb7364613..621b06074e 100644 --- a/deps/v8/test/mjsunit/es6/templates.js +++ b/deps/v8/test/mjsunit/es6/templates.js @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-unicode - var num = 5; var str = "str"; function fn() { return "result"; } diff --git a/deps/v8/test/mjsunit/es6/typedarray-set-length.js b/deps/v8/test/mjsunit/es6/typedarray-set-length.js new file mode 100644 index 0000000000..6dd5bf76e0 --- /dev/null +++ b/deps/v8/test/mjsunit/es6/typedarray-set-length.js @@ -0,0 +1,54 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var typedArrayConstructors = [ + Uint8Array, + Int8Array, + Uint16Array, + Int16Array, + Uint32Array, + Int32Array, + Uint8ClampedArray, + Float32Array, + Float64Array +]; + +var lengthCalled = false; +function lengthValue() { + assertFalse(lengthCalled); + lengthCalled = true; + return 5; +} + +// ToLength should convert these to usable lengths. +var goodNonIntegerLengths = [ + function() { return 4.6; }, + function() { return -5; }, + function() { return NaN; }, + function() { return "5"; }, + function() { return "abc"; }, + function() { return true; }, + function() { return null; }, + function() { return undefined; } +]; + +// This will fail if you use ToLength on it. +function badNonIntegerLength() { + return Symbol("5"); +} + +for (var constructor of typedArrayConstructors) { + lengthCalled = false; + var a = new constructor(10); + a.set({length: {valueOf: lengthValue}}); + assertTrue(lengthCalled); + + for (var lengthFun of goodNonIntegerLengths) { + a.set({length: {valueOf: lengthFun}}); + } + + assertThrows(function() { + a.set({length: {valueOf: badNonIntegerLength}}); + }, TypeError); +} diff --git a/deps/v8/test/mjsunit/es6/typedarray.js b/deps/v8/test/mjsunit/es6/typedarray.js index ef7955ce92..7b1cc06e1c 100644 --- a/deps/v8/test/mjsunit/es6/typedarray.js +++ b/deps/v8/test/mjsunit/es6/typedarray.js @@ -417,6 +417,7 @@ var typedArrayConstructors = [ function TestPropertyTypeChecks(constructor) { function CheckProperty(name) { + assertThrows(function() { 'use strict'; new constructor(10)[name] = 0; }) var d = Object.getOwnPropertyDescriptor(constructor.prototype, name); var o = {}; assertThrows(function() {d.get.call(o);}, TypeError); @@ -756,3 +757,13 @@ TestArbitrary(new DataView(new ArrayBuffer(256))); // Test direct constructor call assertThrows(function() { ArrayBuffer(); }, TypeError); assertThrows(function() { DataView(new ArrayBuffer()); }, TypeError); + +function TestNonConfigurableProperties(constructor) { + var arr = new constructor([100]) + assertFalse(Object.getOwnPropertyDescriptor(arr,"0").configurable) + assertFalse(delete arr[0]) +} + +for(i = 0; i < typedArrayConstructors.length; i++) { + TestNonConfigurableProperties(typedArrayConstructors[i]); +} diff --git a/deps/v8/test/mjsunit/harmony/unicode-escapes.js b/deps/v8/test/mjsunit/es6/unicode-escapes.js index b39ee1a5b0..be269366cf 100644 --- a/deps/v8/test/mjsunit/harmony/unicode-escapes.js +++ b/deps/v8/test/mjsunit/es6/unicode-escapes.js @@ -4,8 +4,6 @@ // ES6 extends the \uxxxx escape and also allows \u{xxxxx}. -// Flags: --harmony-unicode - // Unicode escapes in variable names. (function TestVariableNames1() { diff --git a/deps/v8/test/mjsunit/es7/object-observe-debug-event.js b/deps/v8/test/mjsunit/es7/object-observe-debug-event.js index ed627642cc..06123b8dc2 100644 --- a/deps/v8/test/mjsunit/es7/object-observe-debug-event.js +++ b/deps/v8/test/mjsunit/es7/object-observe-debug-event.js @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Flags: --harmony-object-observe // Flags: --expose-debug-as debug Debug = debug.Debug; diff --git a/deps/v8/test/mjsunit/es7/object-observe-runtime.js b/deps/v8/test/mjsunit/es7/object-observe-runtime.js index 769cd1b296..1a07141af6 100644 --- a/deps/v8/test/mjsunit/es7/object-observe-runtime.js +++ b/deps/v8/test/mjsunit/es7/object-observe-runtime.js @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Flags: --harmony-object-observe // Flags: --allow-natives-syntax // These tests are meant to ensure that that the Object.observe runtime diff --git a/deps/v8/test/mjsunit/es7/object-observe.js b/deps/v8/test/mjsunit/es7/object-observe.js index b2853c4048..5a252a3745 100644 --- a/deps/v8/test/mjsunit/es7/object-observe.js +++ b/deps/v8/test/mjsunit/es7/object-observe.js @@ -25,7 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Flags: --harmony-proxies +// Flags: --harmony-proxies --harmony-object-observe // Flags: --allow-natives-syntax var allObservers = []; diff --git a/deps/v8/test/mjsunit/function-bind.js b/deps/v8/test/mjsunit/function-bind.js index 23dacf157e..ca1ed7e489 100644 --- a/deps/v8/test/mjsunit/function-bind.js +++ b/deps/v8/test/mjsunit/function-bind.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 + // Tests the Function.prototype.bind (ES 15.3.4.5) method. // Simple tests. @@ -298,3 +300,20 @@ assertThrows(function() { f.arguments = 42; }, TypeError); // 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()(); + + +(function TestProtoIsPreserved() { + function fun() {} + + function proto() {} + Object.setPrototypeOf(fun, proto); + var bound = fun.bind({}); + assertEquals(proto, Object.getPrototypeOf(bound)); + + var bound2 = fun.bind({}); + assertTrue(%HaveSameMap(new bound, new bound2)); + + Object.setPrototypeOf(fun, null); + bound = Function.prototype.bind.call(fun, {}); + assertEquals(null, Object.getPrototypeOf(bound)); +})(); diff --git a/deps/v8/test/mjsunit/harmony/atomics.js b/deps/v8/test/mjsunit/harmony/atomics.js index ff403b8bd1..bff9f95a81 100644 --- a/deps/v8/test/mjsunit/harmony/atomics.js +++ b/deps/v8/test/mjsunit/harmony/atomics.js @@ -123,6 +123,21 @@ function testAtomicOp(op, ia, index, expectedIndex, name) { assertEquals(undefined, Atomics.xor(si32a, i, 0), name); assertEquals(undefined, Atomics.exchange(si32a, i, 0), name); }); + + // Monkey-patch length and make sure these functions still return undefined. + Object.defineProperty(si32a, 'length', {get: function() { return 1000; }}); + [2, 100].forEach(function(i) { + var name = String(i); + assertEquals(undefined, Atomics.compareExchange(si32a, i, 0, 0), name); + assertEquals(undefined, Atomics.load(si32a, i), name); + assertEquals(undefined, Atomics.store(si32a, i, 0), name); + assertEquals(undefined, Atomics.add(si32a, i, 0), name); + assertEquals(undefined, Atomics.sub(si32a, i, 0), name); + assertEquals(undefined, Atomics.and(si32a, i, 0), name); + assertEquals(undefined, Atomics.or(si32a, i, 0), name); + assertEquals(undefined, Atomics.xor(si32a, i, 0), name); + assertEquals(undefined, Atomics.exchange(si32a, i, 0), name); + }); })(); (function TestGoodIndex() { @@ -344,6 +359,58 @@ function testAtomicOp(op, ia, index, expectedIndex, name) { } })(); +(function TestToNumber() { + IntegerTypedArrayConstructors.forEach(function(t) { + var sab = new SharedArrayBuffer(1 * t.constr.BYTES_PER_ELEMENT); + var sta = new t.constr(sab); + + var valueOf = {valueOf: function(){ return 3;}}; + var toString = {toString: function(){ return '3';}}; + + [false, true, undefined, valueOf, toString].forEach(function(v) { + var name = Object.prototype.toString.call(sta) + ' - ' + v; + + // CompareExchange + sta[0] = 50; + assertEquals(50, Atomics.compareExchange(sta, 0, v, v), name); + + // Store + assertEquals(+v, Atomics.store(sta, 0, v), name); + assertEquals(v|0, sta[0], name); + + // Add + sta[0] = 120; + assertEquals(120, Atomics.add(sta, 0, v), name); + assertEquals(120 + (v|0), sta[0], name); + + // Sub + sta[0] = 70; + assertEquals(70, Atomics.sub(sta, 0, v), name); + assertEquals(70 - (v|0), sta[0]); + + // And + sta[0] = 0x20; + assertEquals(0x20, Atomics.and(sta, 0, v), name); + assertEquals(0x20 & (v|0), sta[0]); + + // Or + sta[0] = 0x3d; + assertEquals(0x3d, Atomics.or(sta, 0, v), name); + assertEquals(0x3d | (v|0), sta[0]); + + // Xor + sta[0] = 0x25; + assertEquals(0x25, Atomics.xor(sta, 0, v), name); + assertEquals(0x25 ^ (v|0), sta[0]); + + // Exchange + sta[0] = 0x09; + assertEquals(0x09, Atomics.exchange(sta, 0, v), name); + assertEquals(v|0, sta[0]); + }); + }); +})(); + (function TestWrapping() { IntegerTypedArrayConstructors.forEach(function(t) { var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT); diff --git a/deps/v8/test/mjsunit/harmony/block-conflicts-sloppy.js b/deps/v8/test/mjsunit/harmony/block-conflicts-sloppy.js new file mode 100644 index 0000000000..ad947700ac --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/block-conflicts-sloppy.js @@ -0,0 +1,179 @@ +// Copyright 2011 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Test for conflicting variable bindings. + +// Flags: --no-legacy-const --harmony-sloppy --harmony-sloppy-let --harmony-sloppy-function + +function CheckException(e) { + var string = e.toString(); + assertTrue(string.indexOf("has already been declared") >= 0 || + string.indexOf("redeclaration") >= 0); + return 'Conflict'; +} + + +function TestGlobal(s,e) { + try { + return eval(s + e); + } catch (x) { + return CheckException(x); + } +} + + +function TestFunction(s,e) { + try { + return eval("(function(){" + s + " return " + e + "})")(); + } catch (x) { + return CheckException(x); + } +} + + +function TestBlock(s,e) { + try { + return eval("(function(){ {" + s + "} return " + e + "})")(); + } catch (x) { + return CheckException(x); + } +} + +function TestAll(expected,s,opt_e) { + var e = ""; + var msg = s; + if (opt_e) { e = opt_e; msg += opt_e; } + // TODO(littledan): Add tests using Realm.eval to ensure that global eval + // works as expected. + assertEquals(expected === 'LocalConflict' ? 'NoConflict' : expected, + TestGlobal(s,e), "global:'" + msg + "'"); + assertEquals(expected === 'LocalConflict' ? 'NoConflict' : expected, + TestFunction(s,e), "function:'" + msg + "'"); + assertEquals(expected === 'LocalConflict' ? 'Conflict' : expected, + TestBlock(s,e), "block:'" + msg + "'"); +} + + +function TestConflict(s) { + TestAll('Conflict', s); + TestAll('Conflict', 'eval("' + s + '");'); +} + +function TestNoConflict(s) { + TestAll('NoConflict', s, "'NoConflict'"); + TestAll('NoConflict', 'eval("' + s + '");', "'NoConflict'"); +} + +function TestLocalConflict(s) { + TestAll('LocalConflict', s, "'NoConflict'"); + TestAll('NoConflict', 'eval("' + s + '");', "'NoConflict'"); +} + +var letbinds = [ "let x;", + "let x = 0;", + "let x = undefined;", + "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;", + "class x { }", + ]; +function forCompatible(bind) { + return !bind.startsWith('class'); +} +var varbinds = [ "var x;", + "var x = 0;", + "var x = undefined;", + "var x = function() {};", + "var x, y;", + "var y, x;", + ]; +var funbind = "function x() {}"; + +for (var l = 0; l < letbinds.length; ++l) { + // Test conflicting let/var bindings. + for (var v = 0; v < varbinds.length; ++v) { + // Same level. + TestConflict(letbinds[l] + varbinds[v]); + TestConflict(varbinds[v] + letbinds[l]); + // Different level. + TestConflict(letbinds[l] + '{' + varbinds[v] + '}'); + TestConflict('{' + varbinds[v] +'}' + letbinds[l]); + TestNoConflict(varbinds[v] + '{' + letbinds[l] + '}'); + TestNoConflict('{' + letbinds[l] + '}' + varbinds[v]); + // For loop. + if (forCompatible(letbinds[l])) { + TestConflict('for (' + letbinds[l] + '0;) {' + varbinds[v] + '}'); + } + TestNoConflict('for (' + varbinds[v] + '0;) {' + letbinds[l] + '}'); + } + + // Test conflicting let/let bindings. + for (var k = 0; k < letbinds.length; ++k) { + // Same level. + TestConflict(letbinds[l] + letbinds[k]); + TestConflict(letbinds[k] + letbinds[l]); + // Different level. + TestNoConflict(letbinds[l] + '{ ' + letbinds[k] + '}'); + TestNoConflict('{' + letbinds[k] +'} ' + letbinds[l]); + // For loop. + if (forCompatible(letbinds[l])) { + TestNoConflict('for (' + letbinds[l] + '0;) {' + letbinds[k] + '}'); + } + if (forCompatible(letbinds[k])) { + TestNoConflict('for (' + letbinds[k] + '0;) {' + letbinds[l] + '}'); + } + } + + // Test conflicting function/let bindings. + // Same level. + TestConflict(letbinds[l] + funbind); + TestConflict(funbind + letbinds[l]); + // Different level. + TestNoConflict(letbinds[l] + '{' + funbind + '}'); + TestNoConflict('{' + funbind + '}' + letbinds[l]); + TestNoConflict(funbind + '{' + letbinds[l] + '}'); + TestNoConflict('{' + letbinds[l] + '}' + funbind); + // For loop. + if (forCompatible(letbinds[l])) { + TestNoConflict('for (' + letbinds[l] + '0;) {' + funbind + '}'); + } + + // Test conflicting parameter/let bindings. + TestConflict('(function(x) {' + letbinds[l] + '})();'); +} + +// Test conflicting function/var bindings. +for (var v = 0; v < varbinds.length; ++v) { + // Same level. + TestLocalConflict(varbinds[v] + funbind); + TestLocalConflict(funbind + varbinds[v]); + // Different level. + TestLocalConflict(funbind + '{' + varbinds[v] + '}'); + TestLocalConflict('{' + varbinds[v] +'}' + funbind); + TestNoConflict(varbinds[v] + '{' + funbind + '}'); + TestNoConflict('{' + funbind + '}' + varbinds[v]); + // For loop. + TestNoConflict('for (' + varbinds[v] + '0;) {' + funbind + '}'); +} + +// Test conflicting catch/var bindings. +for (var v = 0; v < varbinds.length; ++v) { + TestNoConflict('try {} catch(x) {' + varbinds[v] + '}'); +} + +// Test conflicting parameter/var bindings. +for (var v = 0; v < varbinds.length; ++v) { + TestNoConflict('(function (x) {' + varbinds[v] + '})();'); +} + +// Test conflicting catch/function bindings. +TestNoConflict('try {} catch(x) {' + funbind + '}'); + +// Test conflicting parameter/function bindings. +TestNoConflict('(function (x) {' + funbind + '})();'); diff --git a/deps/v8/test/mjsunit/harmony/block-const-assign-sloppy.js b/deps/v8/test/mjsunit/harmony/block-const-assign-sloppy.js new file mode 100644 index 0000000000..506847c5b6 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/block-const-assign-sloppy.js @@ -0,0 +1,158 @@ +// 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: --no-legacy-const --harmony-sloppy --harmony-sloppy-let + +// 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. + +const decls = [ + // Const declaration. + function(use) { return "const c = 1; " + use + ";" }, TypeError, + function(use) { return "const x = 0, c = 1; " + use + ";" }, TypeError, + function(use) { return "const c = 1, x = (" + use + ");" }, TypeError, + function(use) { return use + "; const c = 1;" }, ReferenceError, + function(use) { return use + "; const x = 0, c = 1;" }, ReferenceError, + function(use) { return "const x = (" + use + "), c = 1;" }, ReferenceError, + function(use) { return "const c = (" + use + ");" }, ReferenceError, + + // Function expression. + function(use) { return "(function c() { " + use + "; })();"; }, TypeError, + // TODO(rossberg): Once we have default parameters, test using 'c' there. + + // Class expression. + function(use) { + return "new class c { constructor() { " + use + " } };"; + }, TypeError, + function(use) { + return "(new class c { m() { " + use + " } }).m();"; + }, TypeError, + function(use) { + return "(new class c { get a() { " + use + " } }).a;"; + }, TypeError, + function(use) { + return "(new class c { set a(x) { " + use + " } }).a = 0;"; + }, TypeError, + function(use) { + return "(class c { static m() { " + use + " } }).s();"; + }, TypeError, + function(use) { + return "(class c extends (" + use + ") {});"; + }, ReferenceError, + function(use) { + return "(class c { [" + use + "]() {} });"; + }, ReferenceError, + function(use) { + return "(class c { get [" + use + "]() {} });"; + }, ReferenceError, + function(use) { + return "(class c { set [" + use + "](x) {} });"; + }, ReferenceError, + function(use) { + return "(class c { static [" + use + "]() {} });"; + }, ReferenceError, + + // For loop. + function(use) { + return "for (const c = 0; " + use + ";) {}" + }, TypeError, + function(use) { + return "for (const x = 0, c = 0; " + use + ";) {}" + }, TypeError, + function(use) { + return "for (const c = 0; ; " + use + ") {}" + }, TypeError, + function(use) { + return "for (const x = 0, c = 0; ; " + use + ") {}" + }, TypeError, + function(use) { + return "for (const c = 0; ;) { " + use + "; }" + }, TypeError, + function(use) { + return "for (const x = 0, c = 0; ;) { " + use + "; }" + }, TypeError, + function(use) { + return "for (const c in {a: 1}) { " + use + "; }" + }, TypeError, + function(use) { + return "for (const c of [1]) { " + use + "; }" + }, TypeError, + function(use) { + return "for (const x = (" + use + "), c = 0; ;) {}" + }, ReferenceError, + function(use) { + return "for (const c = (" + use + "); ;) {}" + }, ReferenceError, +] + +let uses = [ + 'c = 1', + 'c += 1', + '++c', + 'c--', +]; + +let declcontexts = [ + function(decl) { return decl; }, + function(decl) { return "eval(\'" + decl + "\')"; }, + function(decl) { return "{ " + decl + " }"; }, + function(decl) { return "(function() { " + decl + " })()"; }, +]; + +let usecontexts = [ + function(use) { return use; }, + function(use) { return "eval(\"" + use + "\")"; }, + function(use) { return "(function() { " + use + " })()"; }, + function(use) { return "(function() { eval(\"" + use + "\"); })()"; }, + function(use) { return "eval(\"(function() { " + use + "; })\")()"; }, +]; + +function Test(program, error) { + program = "'use strict'; " + program; + try { + print(program, " // throw " + error.name); + eval(program); + } catch (e) { + assertInstanceof(e, error); + if (e === TypeError) { + assertTrue(e.toString().indexOf("Assignment to constant variable") >= 0); + } + return; + } + assertUnreachable(); +} + +for (var d = 0; d < decls.length; d += 2) { + for (var u = 0; u < uses.length; ++u) { + for (var o = 0; o < declcontexts.length; ++o) { + for (var i = 0; i < usecontexts.length; ++i) { + Test(declcontexts[o](decls[d](usecontexts[i](uses[u]))), decls[d + 1]); + } + } + } +} diff --git a/deps/v8/test/mjsunit/harmony/block-for-sloppy.js b/deps/v8/test/mjsunit/harmony/block-for-sloppy.js new file mode 100644 index 0000000000..eee8e0b5cd --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/block-for-sloppy.js @@ -0,0 +1,199 @@ +// 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: --no-legacy-const --harmony-sloppy --harmony-sloppy-let + +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. +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 +// 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(j, 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(k, a[k]()); + assertEquals(k + 10, b[k]()); + } +} +closures2(); + + +function closure_in_for_init() { + let a = []; + for (let i = 0, f = function() { return i }; i < 5; ++i) { + a.push(f); + } + for (let k = 0; k < 5; ++k) { + assertEquals(0, a[k]()); + } +} +closure_in_for_init(); + + +function closure_in_for_cond() { + let a = []; + for (let i = 0; a.push(function () { return i; }), i < 5; ++i) { } + for (let k = 0; k < 5; ++k) { + assertEquals(k, a[k]()); + } +} +closure_in_for_cond(); + + +function closure_in_for_next() { + let a = []; + for (let i = 0; i < 5; a.push(function () { return i; }), ++i) { } + for (let k = 0; k < 5; ++k) { + assertEquals(k + 1, a[k]()); + } +} +closure_in_for_next(); + + +// In a for-in statement the iteration variable is fresh +// for each 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) {}}); + +// Check normal for statement completion values. +assertEquals(1, eval("for (let i = 0; i < 10; i++) { 1; }")); +assertEquals(9, eval("for (let i = 0; i < 10; i++) { i; }")); +assertEquals(undefined, eval("for (let i = 0; false;) { }")); +assertEquals(undefined, eval("for (const i = 0; false;) { }")); +assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { }")); +assertEquals(undefined, eval("for (let i = 0; false;) { i; }")); +assertEquals(undefined, eval("for (const i = 0; false;) { i; }")); +assertEquals(undefined, eval("for (let i = 0; true;) { break; }")); +assertEquals(undefined, eval("for (const i = 0; true;) { break; }")); +assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { continue; }")); +assertEquals(undefined, eval("for (let i = 0; true;) { break; i; }")); +assertEquals(undefined, eval("for (const i = 0; true;) { break; i; }")); +assertEquals(undefined, eval("for (let i = 0; i < 10; i++) { continue; i; }")); +assertEquals(0, eval("for (let i = 0; true;) { i; break; }")); +assertEquals(0, eval("for (const i = 0; true;) { i; break; }")); +assertEquals(9, eval("for (let i = 0; i < 10; i++) { i; continue; }")); +assertEquals(3, eval("for (let i = 0; true; i++) { i; if (i >= 3) break; }")); +assertEquals(2, eval("for (let i = 0; true; i++) { if (i >= 3) break; i; }")); +assertEquals( + 2, eval("for (let i = 0; i < 10; i++) { if (i >= 3) continue; i; }")); +assertEquals(undefined, eval("foo: for (let i = 0; true;) { break foo; }")); +assertEquals(undefined, eval("foo: for (const i = 0; true;) { break foo; }")); +assertEquals(3, eval("foo: for (let i = 3; true;) { i; break foo; }")); diff --git a/deps/v8/test/mjsunit/harmony/block-leave-sloppy.js b/deps/v8/test/mjsunit/harmony/block-leave-sloppy.js new file mode 100644 index 0000000000..fe21341c2e --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/block-leave-sloppy.js @@ -0,0 +1,224 @@ +// 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: --no-legacy-const --harmony-sloppy --harmony-sloppy-let + +// 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' +// to actually verify that the inner context has been discarded. A static +// lookup of 'x' might accidentally succeed. + +{ + let x = 2; + L: { + let x = 3; + assertEquals(3, x); + break L; + assertTrue(false); + } + assertEquals(2, x); +} + +do { + let x = 4; + assertEquals(4,x); + { + let x = 5; + assertEquals(5, x); + continue; + assertTrue(false); + } +} while (false); + +var caught = false; +try { + { + let xx = 18; + throw 25; + assertTrue(false); + } +} catch (e) { + caught = true; + assertEquals(25, e); + (function () { + try { + // NOTE: This checks that the block scope containing xx has been + // removed from the context chain. + eval('xx'); + assertTrue(false); // should not reach here + } catch (e2) { + assertTrue(e2 instanceof ReferenceError); + } + })(); +} +assertTrue(caught); + + +(function(x) { + label: { + let x = 'inner'; + break label; + } + assertEquals('outer', eval('x')); +})('outer'); + + +(function(x) { + label: { + let x = 'middle'; + { + let x = 'inner'; + break label; + } + } + assertEquals('outer', eval('x')); +})('outer'); + + +(function(x) { + for (var i = 0; i < 10; ++i) { + let x = 'inner' + i; + continue; + } + assertEquals('outer', eval('x')); +})('outer'); + + +(function(x) { + label: for (var i = 0; i < 10; ++i) { + let x = 'middle' + i; + for (var j = 0; j < 10; ++j) { + let x = 'inner' + j; + continue label; + } + } + assertEquals('outer', eval('x')); +})('outer'); + + +(function(x) { + try { + let x = 'inner'; + throw 0; + } catch (e) { + assertEquals('outer', eval('x')); + } +})('outer'); + + +(function(x) { + try { + let x = 'middle'; + { + let x = 'inner'; + throw 0; + } + } catch (e) { + assertEquals('outer', eval('x')); + } +})('outer'); + + +try { + (function(x) { + try { + let x = 'inner'; + throw 0; + } finally { + assertEquals('outer', eval('x')); + } + })('outer'); +} catch (e) { + if (e instanceof MjsUnitAssertionError) throw e; +} + + +try { + (function(x) { + try { + let x = 'middle'; + { + let x = 'inner'; + throw 0; + } + } finally { + assertEquals('outer', eval('x')); + } + })('outer'); +} catch (e) { + if (e instanceof MjsUnitAssertionError) throw e; +} + + +// Verify that the context is correctly set in the stack frame after exiting +// from eval. +function f() {} + +(function(x) { + label: { + let x = 'inner'; + break label; + } + f(); // The context could be restored from the stack after the call. + assertEquals('outer', eval('x')); +})('outer'); + + +(function(x) { + for (var i = 0; i < 10; ++i) { + let x = 'inner'; + continue; + } + f(); + assertEquals('outer', eval('x')); +})('outer'); + + +(function(x) { + try { + let x = 'inner'; + throw 0; + } catch (e) { + f(); + assertEquals('outer', eval('x')); + } +})('outer'); + + +try { + (function(x) { + try { + let x = 'inner'; + throw 0; + } finally { + f(); + assertEquals('outer', eval('x')); + } + })('outer'); +} catch (e) { + if (e instanceof MjsUnitAssertionError) throw e; +} diff --git a/deps/v8/test/mjsunit/harmony/block-let-crankshaft-sloppy.js b/deps/v8/test/mjsunit/harmony/block-let-crankshaft-sloppy.js new file mode 100644 index 0000000000..dc5cdfb5b7 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/block-let-crankshaft-sloppy.js @@ -0,0 +1,483 @@ +// 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 +// Flags: --no-legacy-const --harmony-sloppy --harmony-sloppy-let + +// 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, f24, f25, f26, + f27, f28, f29, f30, f31, f32, f33]; + +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); + assertOptimized(func); +} + +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; }); +} + +function f24() { + let x = 1; + { + let x = 2; + { + let x = 3; + assertEquals(3, x); + } + assertEquals(2, x); + } + assertEquals(1, x); +} + +function f25() { + { + let x = 2; + L: { + let x = 3; + assertEquals(3, x); + break L; + assertTrue(false); + } + assertEquals(2, x); + } + assertTrue(true); +} + +function f26() { + { + let x = 1; + L: { + let x = 2; + { + let x = 3; + assertEquals(3, x); + break L; + assertTrue(false); + } + assertTrue(false); + } + assertEquals(1, x); + } +} + + +function f27() { + do { + let x = 4; + assertEquals(4,x); + { + let x = 5; + assertEquals(5, x); + continue; + assertTrue(false); + } + } while (false); +} + +function f28() { + label: for (var i = 0; i < 10; ++i) { + let x = 'middle' + i; + for (var j = 0; j < 10; ++j) { + let x = 'inner' + j; + continue label; + } + } +} + +function f29() { + // Verify that the context is correctly set in the stack frame after exiting + // from with. + + let x = 'outer'; + label: { + let x = 'inner'; + break label; + } + f(); // The context could be restored from the stack after the call. + assertEquals('outer', x); + + function f() { + assertEquals('outer', x); + }; +} + +function f30() { + let x = 'outer'; + for (var i = 0; i < 10; ++i) { + let x = 'inner'; + continue; + } + f(); + assertEquals('outer', x); + + function f() { + assertEquals('outer', x); + }; +} + +function f31() { + { + let x = 'outer'; + label: for (var i = 0; assertEquals('outer', x), i < 10; ++i) { + let x = 'middle' + i; + { + let x = 'inner' + j; + continue label; + } + } + assertEquals('outer', x); + } +} + +var c = true; + +function f32() { + { + let x = 'outer'; + L: { + { + let x = 'inner'; + if (c) { + break L; + } + } + foo(); + } + } + + function foo() { + return 'bar'; + } +} + +function f33() { + { + let x = 'outer'; + L: { + { + let x = 'inner'; + if (c) { + break L; + } + foo(); + } + } + } + + function foo() { + return 'bar'; + } +} + +function TestThrow() { + function f() { + let x = 'outer'; + { + let x = 'inner'; + throw x; + } + } + for (var i = 0; i < 5; i++) { + try { + f(); + } catch (e) { + assertEquals('inner', e); + } + } + %OptimizeFunctionOnNextCall(f); + try { + f(); + } catch (e) { + assertEquals('inner', e); + } + assertOptimized(f); +} + +TestThrow(); + +// Test that temporal dead zone semantics for function and block scoped +// 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 TestBlockLocal(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 TestBlockContext(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); + TestBlockLocal(s); + TestBlockContext(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) { + let y = x + 42; + return y; +} + +function g(x) { + { + let y = x + 42; + return y; + } +} + +for (var i=0; i<10; i++) { + f(i); + g(i); +} + +%OptimizeFunctionOnNextCall(f); +%OptimizeFunctionOnNextCall(g); + +f(12); +g(12); + +assertTrue(%GetOptimizationStatus(f) != 2); +assertTrue(%GetOptimizationStatus(g) != 2); diff --git a/deps/v8/test/mjsunit/harmony/block-let-declaration-sloppy.js b/deps/v8/test/mjsunit/harmony/block-let-declaration-sloppy.js new file mode 100644 index 0000000000..b94576cabc --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/block-let-declaration-sloppy.js @@ -0,0 +1,174 @@ +// 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 let declarations in various settings. + +// Flags: --no-legacy-const --harmony-sloppy --harmony-sloppy-let + +// Global +let x; +let y = 2; +const z = 4; +class c { static foo() { return 1; } } + +// Block local +{ + let y; + let x = 3; + const z = 5; + class c { static foo() { return 2; } } +} + +assertEquals(undefined, x); +assertEquals(2,y); +assertEquals(4,z); +assertEquals(1, c.foo()); + +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(arg){ 'use strict'; " + str + "})", expect); +} + +function TestLocalDoesNotThrow(str) { + assertDoesNotThrow("(function(arg){ 'use strict'; " + str + "})()"); +} + +// 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); +TestLocalDoesNotThrow("switch (true) { case true: let x; }"); +TestLocalDoesNotThrow("switch (true) { default: let x; }"); + +// 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); +TestLocalDoesNotThrow("switch (true) { case true: const x = 1; }"); +TestLocalDoesNotThrow("switch (true) { default: const x = 1; }"); + +// 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 class declarations with initialisers in statement positions. +TestLocalThrows("if (true) class x { };", SyntaxError); +TestLocalThrows("if (true) {} else class x { };", SyntaxError); +TestLocalThrows("do class x { }; while (false)", SyntaxError); +TestLocalThrows("while (false) class x { };", SyntaxError); +TestLocalThrows("label: class x { };", SyntaxError); +TestLocalThrows("for (;false;) class x { };", SyntaxError); +TestLocalDoesNotThrow("switch (true) { case true: class x { }; }"); +TestLocalDoesNotThrow("switch (true) { default: class x { }; }"); + +// Test that redeclarations of functions are only allowed in outermost scope. +TestLocalThrows("{ let f; var f; }"); +TestLocalThrows("{ var f; let f; }"); +TestLocalThrows("{ function f() {} let f; }"); +TestLocalThrows("{ let f; function f() {} }"); +TestLocalThrows("{ function f() {} var f; }"); +TestLocalThrows("{ var f; function f() {} }"); +TestLocalThrows("{ function f() {} class f {} }"); +TestLocalThrows("{ class f {}; function f() {} }"); +TestLocalThrows("{ function f() {} function f() {} }"); +TestLocalThrows("function f() {} let f;"); +TestLocalThrows("let f; function f() {}"); +TestLocalThrows("function f() {} class f {}"); +TestLocalThrows("class f {}; function f() {}"); +TestLocalDoesNotThrow("function arg() {}"); +TestLocalDoesNotThrow("function f() {} var f;"); +TestLocalDoesNotThrow("var f; function f() {}"); +TestLocalDoesNotThrow("function f() {} function f() {}"); + +function g(f) { + function f() { return 1 } + return f() +} +assertEquals(1, g(function() { return 2 })) + + +// Test function declarations in source element and +// sloppy statement positions. +function f() { + // Sloppy 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); +TestLocalDoesNotThrow("function f() { switch (true) { case true: function g() {} } }"); +TestLocalDoesNotThrow("function f() { switch (true) { default: function g() {} } }"); diff --git a/deps/v8/test/mjsunit/harmony/block-let-semantics-sloppy.js b/deps/v8/test/mjsunit/harmony/block-let-semantics-sloppy.js new file mode 100644 index 0000000000..3d529fc36d --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/block-let-semantics-sloppy.js @@ -0,0 +1,192 @@ +// 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-sloppy --no-legacy-const --harmony-sloppy-let --harmony-sloppy-function + +// Test temporal dead zone semantics of let bound variables in +// function and block scopes. + +function TestFunctionLocal(s) { + try { + eval("(function(){" + s + "; })")(); + } catch (e) { + assertInstanceof(e, ReferenceError); + return; + } + assertUnreachable(); +} + +function TestBlockLocal(s,e) { + try { + eval("(function(){ {" + s + ";} })")(); + } catch (e) { + assertInstanceof(e, ReferenceError); + return; + } + assertUnreachable(); +} + + +function TestAll(s) { + TestBlockLocal(s); + TestFunctionLocal(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;'); +TestAll('let y = x; class x {}'); + +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(); class x { }; 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; } }'); +TestAll('f()(); class x { }; function f() { return function() { return x; } }'); + +for (var kw of ['let x = 2', 'const x = 2', 'class x { }']) { + // Use before initialization with a dynamic lookup. + TestAll(`eval("x"); ${kw};`); + TestAll(`eval("x + 1;"); ${kw};`); + TestAll(`eval("x = 1;"); ${kw};`); + TestAll(`eval("x += 1;"); ${kw};`); + TestAll(`eval("++x;"); ${kw};`); + TestAll(`eval("x++;"); ${kw};`); + + // Use before initialization with check for eval-shadowed bindings. + TestAll(`function f() { eval("var y = 2;"); x + 1; }; f(); ${kw};`); + TestAll(`function f() { eval("var y = 2;"); x = 1; }; f(); ${kw};`); + TestAll(`function f() { eval("var y = 2;"); x += 1; }; f(); ${kw};`); + TestAll(`function f() { eval("var y = 2;"); ++x; }; f(); ${kw};`); + TestAll(`function f() { eval("var y = 2;"); x++; }; f(); ${kw};`); +} + +// Test that variables introduced by function declarations are created and +// initialized upon entering a function / block scope. +function f() { + { + assertEquals(2, g1()); + assertEquals(2, eval("g1()")); + + // block scoped function declaration + function g1() { + return 2; + } + } + + assertEquals(3, g2()); + assertEquals(3, eval("g2()")); + // function scoped function declaration + function g2() { + return 3; + } +} +f(); + +// Test that a function declaration introduces a block scoped variable. +TestAll('{ function k() { return 0; } }; k(); '); + +// Test that a function declaration sees the scope it resides in. +function f2() { + let m, n, o, p; + { + m = g; + function g() { + return a; + } + let a = 1; + } + assertEquals(1, m()); + + try { + throw 2; + } catch(b) { + n = h; + function h() { + return b + c; + } + 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/deps/v8/test/mjsunit/harmony/block-scope-class.js b/deps/v8/test/mjsunit/harmony/block-scope-class.js new file mode 100644 index 0000000000..351feaa90e --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/block-scope-class.js @@ -0,0 +1,59 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Test for conflicting variable bindings. + +// Flags: --harmony-sloppy --harmony-sloppy-function + +function AssertEqualsStrictAndSloppy(value, code) { + assertEquals(value, eval("(function() {" + code + "})()")); + assertEquals(value, eval("(function() { 'use strict'; " + code + "})()")); + assertEquals(value, eval("(function() { var x = 0; {" + code + "} })()")); + assertEquals(value, eval("(function() { 'use strict'; var x = 0; {" + + code + "} })()")); +} + +function AssertThrowsStrictAndSloppy(code, error) { + assertThrows("(function() {" + code + "})()", error); + assertThrows("(function() { 'use strict'; " + code + "})()", error); + assertThrows("(function() { var x = 0; { " + code + "} })()", error); + assertThrows("(function() { 'use strict'; var x = 0; {" + code + "} })()", + error); +} + +(function TestClassTDZ() { + AssertEqualsStrictAndSloppy( + "x", "function f() { return x; }; class x { }; return f().name;"); + AssertEqualsStrictAndSloppy + ("x", "class x { }; function f() { return x; }; return f().name;"); + AssertEqualsStrictAndSloppy( + "x", "class x { }; var result = f().name; " + + "function f() { return x; }; return result;"); + AssertThrowsStrictAndSloppy( + "function f() { return x; }; f(); class x { };", ReferenceError); + AssertThrowsStrictAndSloppy( + "f(); function f() { return x; }; class x { };", ReferenceError); + AssertThrowsStrictAndSloppy( + "f(); class x { }; function f() { return x; };", ReferenceError); + AssertThrowsStrictAndSloppy( + "var x = 1; { f(); class x { }; function f() { return x; }; }", + ReferenceError); + AssertThrowsStrictAndSloppy("x = 3; class x { };", ReferenceError) +})(); + +(function TestClassNameConflict() { + AssertThrowsStrictAndSloppy("class x { }; var x;", SyntaxError); + AssertThrowsStrictAndSloppy("var x; class x { };", SyntaxError); + AssertThrowsStrictAndSloppy("class x { }; function x() { };", SyntaxError); + AssertThrowsStrictAndSloppy("function x() { }; class x { };", SyntaxError); + AssertThrowsStrictAndSloppy("class x { }; for (var x = 0; false;) { };", + SyntaxError); + AssertThrowsStrictAndSloppy("for (var x = 0; false;) { }; class x { };", + SyntaxError); +})(); + +(function TestClassMutableBinding() { + AssertEqualsStrictAndSloppy( + "x3", "class x { }; var y = x.name; x = 3; return y + x;") +})(); diff --git a/deps/v8/test/mjsunit/harmony/block-scoping-sloppy.js b/deps/v8/test/mjsunit/harmony/block-scoping-sloppy.js new file mode 100644 index 0000000000..c91a9fbf1c --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/block-scoping-sloppy.js @@ -0,0 +1,310 @@ +// 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 --harmony-sloppy --no-legacy-const --harmony-sloppy-let --harmony-sloppy-function +// Test functionality of block scopes. + +// Hoisting of var declarations. +function f1() { + { + var x = 1; + var y; + } + assertEquals(1, x) + assertEquals(undefined, y) +} +for (var j = 0; j < 5; ++j) f1(); +%OptimizeFunctionOnNextCall(f1); +f1(); +assertTrue(%GetOptimizationStatus(f1) != 2); + +// Dynamic lookup in and through block contexts. +function f2(one) { + var x = one + 1; + let y = one + 2; + const u = one + 4; + class a { static foo() { return one + 6; } } + { + let z = one + 3; + const v = one + 5; + class b { static foo() { return one + 7; } } + assertEquals(1, eval('one')); + assertEquals(2, eval('x')); + assertEquals(3, eval('y')); + assertEquals(4, eval('z')); + assertEquals(5, eval('u')); + assertEquals(6, eval('v')); + assertEquals(7, eval('a.foo()')); + assertEquals(8, eval('b.foo()')); + } +} + +f2(1); + +// Lookup in and through block contexts. +function f3(one) { + var x = one + 1; + let y = one + 2; + const u = one + 4; + class a { static foo() { return one + 6; } } + { + let z = one + 3; + const v = one + 5; + class b { static foo() { return one + 7; } } + assertEquals(1, one); + assertEquals(2, x); + assertEquals(3, y); + assertEquals(4, z); + assertEquals(5, u); + assertEquals(6, v); + assertEquals(7, a.foo()); + assertEquals(8, b.foo()); + } +} +for (var j = 0; j < 5; ++j) f3(1); +%OptimizeFunctionOnNextCall(f3); +f3(1); +assertTrue(%GetOptimizationStatus(f3) != 2); + + + +// Dynamic lookup from closure. +function f4(one) { + var x = one + 1; + let y = one + 2; + const u = one + 4; + class a { static foo() { return one + 6; } } + { + let z = one + 3; + const v = one + 5; + class b { static foo() { return one + 7; } } + 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')); + assertEquals(7, eval('a.foo()')); + assertEquals(8, eval('b.foo()')); + } + f(); + } +} +f4(1); + + +// Lookup from closure. +function f5(one) { + var x = one + 1; + let y = one + 2; + const u = one + 4; + class a { static foo() { return one + 6; } } + { + let z = one + 3; + const v = one + 5; + class b { static foo() { return one + 7; } } + function f() { + assertEquals(1, one); + assertEquals(2, x); + assertEquals(3, y); + assertEquals(4, z); + assertEquals(5, u); + assertEquals(6, v); + assertEquals(7, a.foo()); + assertEquals(8, b.foo()); + } + f(); + } +} +f5(1); + + +// Return from block. +function f6() { + let x = 1; + const u = 3; + { + let y = 2; + const v = 4; + return x + y; + } +} +assertEquals(3, f6(6)); + + +// Variable shadowing and lookup. +function f7(a) { + let b = 1; + var c = 1; + var d = 1; + const e = 1; + class f { static foo() { return 1; } } + { // let variables shadowing argument, let, const, class and var variables + let a = 2; + let b = 2; + let c = 2; + let e = 2; + let f = 2; + assertEquals(2,a); + assertEquals(2,b); + assertEquals(2,c); + assertEquals(2,e); + assertEquals(2,f); + } + { // const variables shadowing argument, let, const and var variables + const a = 2; + const b = 2; + const c = 2; + const e = 2; + const f = 2; + assertEquals(2,a); + assertEquals(2,b); + assertEquals(2,c); + assertEquals(2,e); + assertEquals(2,f); + } + { // class variables shadowing argument, let, const and var variables + class a { static foo() { return 2; } } + class b { static foo() { return 2; } } + class c { static foo() { return 2; } } + class d { static foo() { return 2; } } + class e { static foo() { return 2; } } + class f { static foo() { return 2; } } + assertEquals(2,a.foo()); + assertEquals(2,b.foo()); + assertEquals(2,c.foo()); + assertEquals(2,e.foo()); + assertEquals(2,f.foo()); + } + try { + throw 'stuff1'; + } catch (a) { + assertEquals('stuff1',a); + // catch variable shadowing argument + a = 2; + assertEquals(2,a); + { + // let variable shadowing catch variable + let a = 3; + assertEquals(3,a); + try { + throw 'stuff2'; + } catch (a) { + assertEquals('stuff2',a); + // catch variable shadowing let variable + a = 4; + assertEquals(4,a); + } + assertEquals(3,a); + } + assertEquals(2,a); + } + try { + throw 'stuff3'; + } 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) { + assertEquals('stuff4',c); + // catch variable shadowing catch variable + c = 3; + assertEquals(3,c); + } + (function(c) { + // argument shadowing catch variable + c = 3; + assertEquals(3,c); + })(); + assertEquals('stuff3', c); + (function() { + // var variable shadowing catch variable + var c = 3; + })(); + assertEquals('stuff3', c); + c = 2; + } + assertEquals(1,c); + (function(a,b,c,e,f) { + // arguments shadowing argument, let, const, class and var variable + a = 2; + b = 2; + c = 2; + e = 2; + f = 2; + assertEquals(2,a); + assertEquals(2,b); + assertEquals(2,c); + assertEquals(2,e); + assertEquals(2,f); + // var variable shadowing var variable + var d = 2; + })(1,1); + assertEquals(1,a); + assertEquals(1,b); + assertEquals(1,c); + assertEquals(1,d); + assertEquals(1,e); + assertEquals(1,f.foo()); +} +f7(1); + + +// Ensure let and const variables are block local +// and var variables function local. +function f8() { + var let_accessors = []; + var var_accessors = []; + var const_accessors = []; + var class_accessors = []; + for (var i = 0; i < 10; i++) { + let x = i; + var y = i; + const z = i; + class a { static foo() { return x; } } + let_accessors[i] = function() { return x; } + var_accessors[i] = function() { return y; } + const_accessors[i] = function() { return z; } + class_accessors[i] = function() { return a; } + } + 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]()); + assertEquals(j, class_accessors[j]().foo()); + } +} +f8(); diff --git a/deps/v8/test/mjsunit/harmony/block-scoping-top-level-sloppy.js b/deps/v8/test/mjsunit/harmony/block-scoping-top-level-sloppy.js new file mode 100644 index 0000000000..74492c4ca6 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/block-scoping-top-level-sloppy.js @@ -0,0 +1,34 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --min-preparse-length=0 +// Flags: --no-legacy-const --harmony-sloppy --harmony-sloppy-let + +let xxx = 1; +let f = undefined; +{ + let inner_x = xxx; + f = function() { return inner_x; }; +} + +assertSame(1, f()); + +xxx = 42; +{ + f = function() { return inner_x1; }; + let inner_x1 = xxx; +} + +assertSame(42, f()); + +xxx = 31; +{ + let inner_x1 = xxx; + try { + throw new Error(); + } catch (e) { + f = function() { return inner_x1; }; + } +} +assertSame(31, f()); diff --git a/deps/v8/test/mjsunit/harmony/default-parameters-debug.js b/deps/v8/test/mjsunit/harmony/default-parameters-debug.js new file mode 100644 index 0000000000..ce9e626621 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/default-parameters-debug.js @@ -0,0 +1,58 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug --harmony-default-parameters + +// Get the Debug object exposed from the debug context global object. +Debug = debug.Debug + +listenerComplete = false; +breakPointCount = 0; + +function listener(event, exec_state, event_data, data) { + if (event == Debug.DebugEvent.Break) { + breakPointCount++; + if (breakPointCount == 1) { + // Break point in initializer for parameter `a`, invoked by + // initializer for parameter `b` + assertEquals('default', exec_state.frame(1).evaluate('mode').value()); + + // initializer for `b` can't refer to `b` + assertThrows(function() { + exec_state.frame(1).evaluate('b').value(); + }, ReferenceError); + + assertThrows(function() { + exec_state.frame(1).evaluate('c'); + }, ReferenceError); + } else if (breakPointCount == 2) { + // Break point in IIFE initializer for parameter `c` + assertEquals('modeFn', exec_state.frame(1).evaluate('a.name').value()); + assertEquals('default', exec_state.frame(1).evaluate('b').value()); + assertThrows(function() { + exec_state.frame(1).evaluate('c'); + }, ReferenceError); + } else if (breakPointCount == 3) { + // Break point in function body --- `c` parameter is shadowed + assertEquals('modeFn', exec_state.frame(0).evaluate('a.name').value()); + assertEquals('default', exec_state.frame(0).evaluate('b').value()); + assertEquals('local', exec_state.frame(0).evaluate('d').value()); + } + } +}; + +// Add the debug event listener. +Debug.setListener(listener); + +function f(a = function modeFn(mode) { debugger; return mode; }, + b = a("default"), + c = (function() { debugger; })()) { + var d = 'local'; + debugger; +}; + +f(); + +// Make sure that the debug event listener vas invoked. +assertEquals(3, breakPointCount); diff --git a/deps/v8/test/mjsunit/harmony/default-parameters.js b/deps/v8/test/mjsunit/harmony/default-parameters.js new file mode 100644 index 0000000000..43a7acd1c6 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/default-parameters.js @@ -0,0 +1,251 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-default-parameters --harmony-arrow-functions +// Flags: --harmony-rest-parameters + + +(function TestDefaults() { + function f1(x = 1) { return x } + assertEquals(1, f1()); + assertEquals(1, f1(undefined)); + assertEquals(2, f1(2)); + assertEquals(null, f1(null)); + + function f2(x, y = x) { return x + y; } + assertEquals(8, f2(4)); + assertEquals(8, f2(4, undefined)); + assertEquals(6, f2(4, 2)); + + function f3(x = 1, y) { return x + y; } + assertEquals(8, f3(5, 3)); + assertEquals(3, f3(undefined, 2)); + assertEquals(6, f3(4, 2)); + + function f4(x = () => 1) { return x() } + assertEquals(1, f4()); + assertEquals(1, f4(undefined)); + assertEquals(2, f4(() => 2)); + assertThrows(() => f4(null), TypeError); + + function f5(x, y = () => x) { return x + y(); } + assertEquals(8, f5(4)); + assertEquals(8, f5(4, undefined)); + assertEquals(6, f5(4, () => 2)); + + function f6(x = {a: 1, m() { return 2 }}) { return x.a + x.m(); } + assertEquals(3, f6()); + assertEquals(3, f6(undefined)); + assertEquals(5, f6({a: 2, m() { return 3 }})); + + var g1 = (x = 1) => { return x }; + assertEquals(1, g1()); + assertEquals(1, g1(undefined)); + assertEquals(2, g1(2)); + assertEquals(null, g1(null)); + + var g2 = (x, y = x) => { return x + y; }; + assertEquals(8, g2(4)); + assertEquals(8, g2(4, undefined)); + assertEquals(6, g2(4, 2)); + + var g3 = (x = 1, y) => { return x + y; }; + assertEquals(8, g3(5, 3)); + assertEquals(3, g3(undefined, 2)); + assertEquals(6, g3(4, 2)); + + var g4 = (x = () => 1) => { return x() }; + assertEquals(1, g4()); + assertEquals(1, g4(undefined)); + assertEquals(2, g4(() => 2)); + assertThrows(() => g4(null), TypeError); + + var g5 = (x, y = () => x) => { return x + y(); }; + assertEquals(8, g5(4)); + assertEquals(8, g5(4, undefined)); + assertEquals(6, g5(4, () => 2)); + + var g6 = (x = {a: 1, m() { return 2 }}) => { return x.a + x.m(); }; + assertEquals(3, g6()); + assertEquals(3, g6(undefined)); + assertEquals(5, g6({a: 2, m() { return 3 }})); +}()); + + +(function TestEvalInParameters() { + function f1(x = eval(0)) { return x } + assertEquals(0, f1()); + function f2(x = () => eval(1)) { return x() } + assertEquals(1, f2()); +})(); + + +(function TestParameterScoping() { + // TODO(rossberg): Add checks for variable declarations in defaults. + var x = 1; + + function f1(a = x) { var x = 2; return a; } + assertEquals(1, f1()); + function f2(a = x) { function x() {}; return a; } + assertEquals(1, f2()); + function f3(a = x) { 'use strict'; let x = 2; return a; } + assertEquals(1, f3()); + function f4(a = x) { 'use strict'; const x = 2; return a; } + assertEquals(1, f4()); + function f5(a = x) { 'use strict'; function x() {}; return a; } + assertEquals(1, f5()); + function f6(a = eval("x")) { var x; return a; } + assertEquals(1, f6()); + function f61(a = eval("x")) { 'use strict'; var x; return a; } + assertEquals(1, f61()); + function f62(a = eval("'use strict'; x")) { var x; return a; } + assertEquals(1, f62()); + function f7(a = function() { return x }) { var x; return a(); } + assertEquals(1, f7()); + function f8(a = () => x) { var x; return a(); } + assertEquals(1, f8()); + function f9(a = () => eval("x")) { var x; return a(); } + assertEquals(1, f9()); + function f91(a = () => eval("x")) { 'use strict'; var x; return a(); } + assertEquals(1, f91()); + function f92(a = () => { 'use strict'; return eval("x") }) { var x; return a(); } + assertEquals(1, f92()); + function f93(a = () => eval("'use strict'; x")) { var x; return a(); } + assertEquals(1, f93()); + + var g1 = (a = x) => { var x = 2; return a; }; + assertEquals(1, g1()); + var g2 = (a = x) => { function x() {}; return a; }; + assertEquals(1, g2()); + var g3 = (a = x) => { 'use strict'; let x = 2; return a; }; + assertEquals(1, g3()); + var g4 = (a = x) => { 'use strict'; const x = 2; return a; }; + assertEquals(1, g4()); + var g5 = (a = x) => { 'use strict'; function x() {}; return a; }; + assertEquals(1, g5()); + var g6 = (a = eval("x")) => { var x; return a; }; + assertEquals(1, g6()); + var g61 = (a = eval("x")) => { 'use strict'; var x; return a; }; + assertEquals(1, g61()); + var g62 = (a = eval("'use strict'; x")) => { var x; return a; }; + assertEquals(1, g62()); + var g7 = (a = function() { return x }) => { var x; return a(); }; + assertEquals(1, g7()); + var g8 = (a = () => x) => { var x; return a(); }; + assertEquals(1, g8()); + var g9 = (a = () => eval("x")) => { var x; return a(); }; + assertEquals(1, g9()); + var g91 = (a = () => eval("x")) => { 'use strict'; var x; return a(); }; + assertEquals(1, g91()); + var g92 = (a = () => { 'use strict'; return eval("x") }) => { var x; return a(); }; + assertEquals(1, g92()); + var g93 = (a = () => eval("'use strict'; x")) => { var x; return a(); }; + assertEquals(1, g93()); + + var f11 = function f(x = f) { var f; return x; } + assertSame(f11, f11()); + var f12 = function f(x = f) { function f() {}; return x; } + assertSame(f12, f12()); + var f13 = function f(x = f) { 'use strict'; let f; return x; } + assertSame(f13, f13()); + var f14 = function f(x = f) { 'use strict'; const f = 0; return x; } + assertSame(f14, f14()); + var f15 = function f(x = f) { 'use strict'; function f() {}; return x; } + assertSame(f15, f15()); + var f16 = function f(f = 7, x = f) { return x; } + assertSame(7, f16()); + + var o1 = {f: function(x = this) { return x; }}; + assertSame(o1, o1.f()); + assertSame(1, o1.f(1)); +})(); + + +(function TestParameterTDZ() { + function f1(a = x, x) { return a } + assertThrows(() => f1(undefined, 4), ReferenceError); + assertEquals(4, f1(4, 5)); + function f2(a = eval("x"), x) { return a } + assertThrows(() => f2(undefined, 4), ReferenceError); + assertEquals(4, f2(4, 5)); + function f3(a = eval("x"), x) { 'use strict'; return a } + assertThrows(() => f3(undefined, 4), ReferenceError); + assertEquals(4, f3(4, 5)); + function f4(a = eval("'use strict'; x"), x) { return a } + assertThrows(() => f4(undefined, 4), ReferenceError); + assertEquals(4, f4(4, 5)); + + function f5(a = () => x, x) { return a() } + assertEquals(4, f5(() => 4, 5)); + function f6(a = () => eval("x"), x) { return a() } + assertEquals(4, f6(() => 4, 5)); + function f7(a = () => eval("x"), x) { 'use strict'; return a() } + assertEquals(4, f7(() => 4, 5)); + function f8(a = () => eval("'use strict'; x"), x) { return a() } + assertEquals(4, f8(() => 4, 5)); + + function f11(a = x, x = 2) { return a } + assertThrows(() => f11(), ReferenceError); + assertThrows(() => f11(undefined), ReferenceError); + assertThrows(() => f11(undefined, 4), ReferenceError); + assertEquals(4, f1(4, 5)); + function f12(a = eval("x"), x = 2) { return a } + assertThrows(() => f12(), ReferenceError); + assertThrows(() => f12(undefined), ReferenceError); + assertThrows(() => f12(undefined, 4), ReferenceError); + assertEquals(4, f12(4, 5)); + function f13(a = eval("x"), x = 2) { 'use strict'; return a } + assertThrows(() => f13(), ReferenceError); + assertThrows(() => f13(undefined), ReferenceError); + assertThrows(() => f13(undefined, 4), ReferenceError); + assertEquals(4, f13(4, 5)); + function f14(a = eval("'use strict'; x"), x = 2) { return a } + assertThrows(() => f14(), ReferenceError); + assertThrows(() => f14(undefined), ReferenceError); + assertThrows(() => f14(undefined, 4), ReferenceError); + assertEquals(4, f14(4, 5)); + + function f34(x = function() { return a }, ...a) { return x()[0] } + assertEquals(4, f34(undefined, 4)); + function f35(x = () => a, ...a) { return x()[0] } + assertEquals(4, f35(undefined, 4)); + function f36(x = () => eval("a"), ...a) { return x()[0] } + assertEquals(4, f36(undefined, 4)); + function f37(x = () => eval("a"), ...a) { 'use strict'; return x()[0] } + assertEquals(4, f37(undefined, 4)); + function f38(x = () => { 'use strict'; return eval("a") }, ...a) { return x()[0] } + assertEquals(4, f38(undefined, 4)); + function f39(x = () => eval("'use strict'; a"), ...a) { return x()[0] } + assertEquals(4, f39(undefined, 4)); + + var g34 = (x = function() { return a }, ...a) => { return x()[0] }; + assertEquals(4, g34(undefined, 4)); + var g35 = (x = () => a, ...a) => { return x()[0] }; + assertEquals(4, g35(undefined, 4)); +})(); + + +(function TestArgumentsForNonSimpleParameters() { + function f1(x = 900) { arguments[0] = 1; return x } + assertEquals(9, f1(9)); + assertEquals(900, f1()); + function f2(x = 1001) { x = 2; return arguments[0] } + assertEquals(10, f2(10)); + assertEquals(undefined, f2()); +}()); + + +(function TestFunctionLength() { + // TODO(rossberg): Fix arity. + // assertEquals(0, (function(x = 1) {}).length); + // assertEquals(0, (function(x = 1, ...a) {}).length); + // assertEquals(1, (function(x, y = 1) {}).length); + // assertEquals(1, (function(x, y = 1, ...a) {}).length); + // assertEquals(2, (function(x, y, z = 1) {}).length); + // assertEquals(2, (function(x, y, z = 1, ...a) {}).length); + // assertEquals(1, (function(x, y = 1, z) {}).length); + // assertEquals(1, (function(x, y = 1, z, ...a) {}).length); + // assertEquals(1, (function(x, y = 1, z, v = 2) {}).length); + // assertEquals(1, (function(x, y = 1, z, v = 2, ...a) {}).length); +})(); diff --git a/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount-nolazy.js b/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount-nolazy.js index fdf1233f90..52d7ca06d9 100644 --- a/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount-nolazy.js +++ b/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount-nolazy.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Flags: --harmony-destructuring --harmony-computed-property-names +// Flags: --harmony-destructuring // Flags: --harmony-arrow-functions --no-lazy --allow-natives-syntax diff --git a/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount.js b/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount.js index 85a45ea822..64c1793673 100644 --- a/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount.js +++ b/deps/v8/test/mjsunit/harmony/destructuring-parameters-literalcount.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Flags: --harmony-destructuring --harmony-computed-property-names +// Flags: --harmony-destructuring // Flags: --harmony-arrow-functions --allow-natives-syntax diff --git a/deps/v8/test/mjsunit/harmony/destructuring.js b/deps/v8/test/mjsunit/harmony/destructuring.js index 198d4c0257..69e144b26f 100644 --- a/deps/v8/test/mjsunit/harmony/destructuring.js +++ b/deps/v8/test/mjsunit/harmony/destructuring.js @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Flags: --harmony-destructuring --harmony-computed-property-names -// Flags: --harmony-arrow-functions +// Flags: --harmony-destructuring --harmony-arrow-functions +// Flags: --harmony-default-parameters --harmony-rest-parameters (function TestObjectLiteralPattern() { var { x : x, y : y } = { x : 1, y : 2 }; @@ -227,6 +227,12 @@ } { + let {x, y = () => eval("x+1")} = {x:42}; + assertEquals(42, x); + assertEquals(43, y()); + } + + { let {x = function() {return y+1;}, y} = {y:42}; assertEquals(43, x()); assertEquals(42, y); @@ -716,6 +722,191 @@ }()); +(function TestExpressionsInParameters() { + function f0(x = eval(0)) { return x } + assertEquals(0, f0()); + function f1({a = eval(1)}) { return a } + assertEquals(1, f1({})); + function f2([x = eval(2)]) { return x } + assertEquals(2, f2([])); + function f3({[eval(7)]: x}) { return x } + assertEquals(3, f3({7: 3})); +})(); + + +(function TestParameterScoping() { + var x = 1; + + function f1({a = x}) { var x = 2; return a; } + assertEquals(1, f1({})); + function f2({a = x}) { function x() {}; return a; } + assertEquals(1, f2({})); + function f3({a = x}) { 'use strict'; let x = 2; return a; } + assertEquals(1, f3({})); + function f4({a = x}) { 'use strict'; const x = 2; return a; } + assertEquals(1, f4({})); + function f5({a = x}) { 'use strict'; function x() {}; return a; } + assertEquals(1, f5({})); + function f6({a = eval("x")}) { var x; return a; } + assertEquals(1, f6({})); + function f61({a = eval("x")}) { 'use strict'; var x; return a; } + assertEquals(1, f61({})); + function f62({a = eval("'use strict'; x")}) { var x; return a; } + assertEquals(1, f62({})); + function f7({a = function() { return x }}) { var x; return a(); } + assertEquals(1, f7({})); + function f8({a = () => x}) { var x; return a(); } + assertEquals(1, f8({})); + function f9({a = () => eval("x")}) { var x; return a(); } + assertEquals(1, f9({})); + function f91({a = () => eval("x")}) { 'use strict'; var x; return a(); } + assertEquals(1, f91({})); + function f92({a = () => { 'use strict'; return eval("x") }}) { var x; return a(); } + assertEquals(1, f92({})); + function f93({a = () => eval("'use strict'; x")}) { var x; return a(); } + assertEquals(1, f93({})); + + var g1 = ({a = x}) => { var x = 2; return a; }; + assertEquals(1, g1({})); + var g2 = ({a = x}) => { function x() {}; return a; }; + assertEquals(1, g2({})); + var g3 = ({a = x}) => { 'use strict'; let x = 2; return a; }; + assertEquals(1, g3({})); + var g4 = ({a = x}) => { 'use strict'; const x = 2; return a; }; + assertEquals(1, g4({})); + var g5 = ({a = x}) => { 'use strict'; function x() {}; return a; }; + assertEquals(1, g5({})); + var g6 = ({a = eval("x")}) => { var x; return a; }; + assertEquals(1, g6({})); + var g61 = ({a = eval("x")}) => { 'use strict'; var x; return a; }; + assertEquals(1, g61({})); + var g62 = ({a = eval("'use strict'; x")}) => { var x; return a; }; + assertEquals(1, g62({})); + var g7 = ({a = function() { return x }}) => { var x; return a(); }; + assertEquals(1, g7({})); + var g8 = ({a = () => x}) => { var x; return a(); }; + assertEquals(1, g8({})); + var g9 = ({a = () => eval("x")}) => { var x; return a(); }; + assertEquals(1, g9({})); + var g91 = ({a = () => eval("x")}) => { 'use strict'; var x; return a(); }; + assertEquals(1, g91({})); + var g92 = ({a = () => { 'use strict'; return eval("x") }}) => { var x; return a(); }; + assertEquals(1, g92({})); + var g93 = ({a = () => eval("'use strict'; x")}) => { var x; return a(); }; + assertEquals(1, g93({})); + + var f11 = function f({x = f}) { var f; return x; } + assertSame(f11, f11({})); + var f12 = function f({x = f}) { function f() {}; return x; } + assertSame(f12, f12({})); + var f13 = function f({x = f}) { 'use strict'; let f; return x; } + assertSame(f13, f13({})); + var f14 = function f({x = f}) { 'use strict'; const f = 0; return x; } + assertSame(f14, f14({})); + var f15 = function f({x = f}) { 'use strict'; function f() {}; return x; } + assertSame(f15, f15({})); + var f16 = function f({f = 7, x = f}) { return x; } + assertSame(7, f16({})); + + var y = 'a'; + function f20({[y]: x}) { var y = 'b'; return x; } + assertEquals(1, f20({a: 1, b: 2})); + function f21({[eval('y')]: x}) { var y = 'b'; return x; } + assertEquals(1, f21({a: 1, b: 2})); + var g20 = ({[y]: x}) => { var y = 'b'; return x; }; + assertEquals(1, g20({a: 1, b: 2})); + var g21 = ({[eval('y')]: x}) => { var y = 'b'; return x; }; + assertEquals(1, g21({a: 1, b: 2})); +})(); + + +(function TestParameterDestructuringTDZ() { + function f1({a = x}, x) { return a } + assertThrows(() => f1({}, 4), ReferenceError); + assertEquals(4, f1({a: 4}, 5)); + function f2({a = eval("x")}, x) { return a } + assertThrows(() => f2({}, 4), ReferenceError); + assertEquals(4, f2({a: 4}, 5)); + function f3({a = eval("x")}, x) { 'use strict'; return a } + assertThrows(() => f3({}, 4), ReferenceError); + assertEquals(4, f3({a: 4}, 5)); + function f4({a = eval("'use strict'; x")}, x) { return a } + assertThrows(() => f4({}, 4), ReferenceError); + assertEquals(4, f4({a: 4}, 5)); + + function f5({a = () => x}, x) { return a() } + assertEquals(4, f5({a: () => 4}, 5)); + function f6({a = () => eval("x")}, x) { return a() } + assertEquals(4, f6({a: () => 4}, 5)); + function f7({a = () => eval("x")}, x) { 'use strict'; return a() } + assertEquals(4, f7({a: () => 4}, 5)); + function f8({a = () => eval("'use strict'; x")}, x) { return a() } + assertEquals(4, f8({a: () => 4}, 5)); + + function f11({a = b}, {b}) { return a } + assertThrows(() => f11({}, {b: 4}), ReferenceError); + assertEquals(4, f11({a: 4}, {b: 5})); + function f12({a = eval("b")}, {b}) { return a } + assertThrows(() => f12({}, {b: 4}), ReferenceError); + assertEquals(4, f12({a: 4}, {b: 5})); + function f13({a = eval("b")}, {b}) { 'use strict'; return a } + assertThrows(() => f13({}, {b: 4}), ReferenceError); + assertEquals(4, f13({a: 4}, {b: 5})); + function f14({a = eval("'use strict'; b")}, {b}) { return a } + assertThrows(() => f14({}, {b: 4}), ReferenceError); + assertEquals(4, f14({a: 4}, {b: 5})); + + function f15({a = () => b}, {b}) { return a() } + assertEquals(4, f15({a: () => 4}, {b: 5})); + function f16({a = () => eval("b")}, {b}) { return a() } + assertEquals(4, f16({a: () => 4}, {b: 5})); + function f17({a = () => eval("b")}, {b}) { 'use strict'; return a() } + assertEquals(4, f17({a: () => 4}, {b: 5})); + function f18({a = () => eval("'use strict'; b")}, {b}) { return a() } + assertEquals(4, f18({a: () => 4}, {b: 5})); + + // TODO(caitp): TDZ for rest parameters is not working yet. + // function f30({x = a}, ...a) { return x[0] } + // assertThrows(() => f30({}), ReferenceError); + // assertEquals(4, f30({a: [4]}, 5)); + // function f31({x = eval("a")}, ...a) { return x[0] } + // assertThrows(() => f31({}), ReferenceError); + // assertEquals(4, f31({a: [4]}, 5)); + // function f32({x = eval("a")}, ...a) { 'use strict'; return x[0] } + // assertThrows(() => f32({}), ReferenceError); + // assertEquals(4, f32({a: [4]}, 5)); + // function f33({x = eval("'use strict'; a")}, ...a) { return x[0] } + // assertThrows(() => f33({}), ReferenceError); + // assertEquals(4, f33({a: [4]}, 5)); + + function f34({x = function() { return a }}, ...a) { return x()[0] } + assertEquals(4, f34({}, 4)); + function f35({x = () => a}, ...a) { return x()[0] } + assertEquals(4, f35({}, 4)); + function f36({x = () => eval("a")}, ...a) { return x()[0] } + assertEquals(4, f36({}, 4)); + function f37({x = () => eval("a")}, ...a) { 'use strict'; return x()[0] } + assertEquals(4, f37({}, 4)); + function f38({x = () => { 'use strict'; return eval("a") }}, ...a) { return x()[0] } + assertEquals(4, f38({}, 4)); + function f39({x = () => eval("'use strict'; a")}, ...a) { return x()[0] } + assertEquals(4, f39({}, 4)); + + // var g30 = ({x = a}, ...a) => {}; + // assertThrows(() => g30({}), ReferenceError); + // var g31 = ({x = eval("a")}, ...a) => {}; + // assertThrows(() => g31({}), ReferenceError); + // var g32 = ({x = eval("a")}, ...a) => { 'use strict'; }; + // assertThrows(() => g32({}), ReferenceError); + // var g33 = ({x = eval("'use strict'; a")}, ...a) => {}; + // assertThrows(() => g33({}), ReferenceError); + var g34 = ({x = function() { return a }}, ...a) => { return x()[0] }; + assertEquals(4, g34({}, 4)); + var g35 = ({x = () => a}, ...a) => { return x()[0] }; + assertEquals(4, g35({}, 4)); +})(); + + (function TestDuplicatesInParameters() { assertThrows("'use strict';function f(x,x){}", SyntaxError); assertThrows("'use strict';function f({x,x}){}", SyntaxError); @@ -724,12 +915,38 @@ assertThrows("'use strict';var f = ({x,x}) => {};", SyntaxError); assertThrows("'use strict';var f = (x, {x}) => {};", SyntaxError); - function ok(x) { var x; }; ok(); + function ok1(x) { var x; return x; }; + assertEquals(1, ok1(1)); + function ok2(x) { 'use strict'; { let x = 2; return x; } }; + assertEquals(2, ok2(1)); + assertThrows("function f({x}) { var x; }; f({});", SyntaxError); + assertThrows("function f({x}) { { var x; } }; f({});", SyntaxError); + assertThrows("'use strict'; function f(x) { let x = 0; }; f({});", SyntaxError); assertThrows("'use strict'; function f({x}) { let x = 0; }; f({});", SyntaxError); }()); +(function TestArgumentsForNonSimpleParameters() { + function f1({}, x) { arguments[1] = 0; return x } + assertEquals(6, f1({}, 6)); + function f2({}, x) { x = 2; return arguments[1] } + assertEquals(7, f2({}, 7)); + function f3(x, {}) { arguments[0] = 0; return x } + assertEquals(6, f3(6, {})); + function f4(x, {}) { x = 2; return arguments[0] } + assertEquals(7, f4(7, {})); + function f5(x, ...a) { arguments[0] = 0; return x } + assertEquals(6, f5(6, {})); + function f6(x, ...a) { x = 2; return arguments[0] } + assertEquals(6, f6(6, {})); + function f7({a: x}) { x = 2; return arguments[0].a } + assertEquals(5, f7({a: 5})); + function f8(x, ...a) { a = []; return arguments[1] } + assertEquals(6, f8(5, 6)); +}()); + + (function TestForInOfTDZ() { assertThrows("'use strict'; let x = {}; for (let [x, y] of {x});", ReferenceError); assertThrows("'use strict'; let x = {}; for (let [y, x] of {x});", ReferenceError); diff --git a/deps/v8/test/mjsunit/harmony/futex.js b/deps/v8/test/mjsunit/harmony/futex.js new file mode 100644 index 0000000000..c7e1f5ce2a --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/futex.js @@ -0,0 +1,274 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-atomics --harmony-sharedarraybuffer + +(function TestFailsWithNonSharedArray() { + var ab = new ArrayBuffer(16); + + var i8a = new Int8Array(ab); + var i16a = new Int16Array(ab); + var i32a = new Int32Array(ab); + var ui8a = new Uint8Array(ab); + var ui8ca = new Uint8ClampedArray(ab); + var ui16a = new Uint16Array(ab); + var ui32a = new Uint32Array(ab); + var f32a = new Float32Array(ab); + var f64a = new Float64Array(ab); + + [i8a, i16a, i32a, ui8a, ui8ca, ui16a, ui32a, f32a, f64a].forEach(function( + ta) { + assertThrows(function() { Atomics.futexWait(ta, 0, 0); }); + assertThrows(function() { Atomics.futexWake(ta, 0, 1); }); + assertThrows(function() { Atomics.futexWakeOrRequeue(ta, 0, 1, 0, 0); }); + }); +})(); + +(function TestFailsWithNonSharedInt32Array() { + var sab = new SharedArrayBuffer(16); + + var i8a = new Int8Array(sab); + var i16a = new Int16Array(sab); + var ui8a = new Uint8Array(sab); + var ui8ca = new Uint8ClampedArray(sab); + var ui16a = new Uint16Array(sab); + var ui32a = new Uint32Array(sab); + var f32a = new Float32Array(sab); + var f64a = new Float64Array(sab); + + [i8a, i16a, ui8a, ui8ca, ui16a, ui32a, f32a, f64a].forEach(function( + ta) { + assertThrows(function() { Atomics.futexWait(ta, 0, 0); }); + assertThrows(function() { Atomics.futexWake(ta, 0, 1); }); + assertThrows(function() { Atomics.futexWakeOrRequeue(ta, 0, 1, 0, 0); }); + }); +})(); + +(function TestInvalidIndex() { + var i32a = new Int32Array(new SharedArrayBuffer(16)); + + // Valid indexes are 0-3. + [-1, 4, 100].forEach(function(invalidIndex) { + assertEquals(undefined, Atomics.futexWait(i32a, invalidIndex, 0)); + assertEquals(undefined, Atomics.futexWake(i32a, invalidIndex, 0)); + var validIndex = 0; + assertEquals(undefined, Atomics.futexWakeOrRequeue(i32a, invalidIndex, 0, 0, + validIndex)); + assertEquals(undefined, Atomics.futexWakeOrRequeue(i32a, validIndex, 0, 0, + invalidIndex)); + }); + +})(); + +(function TestWaitTimeout() { + var i32a = new Int32Array(new SharedArrayBuffer(16)); + var waitMs = 100; + var startTime = new Date(); + assertEquals(Atomics.TIMEDOUT, Atomics.futexWait(i32a, 0, 0, waitMs)); + var endTime = new Date(); + assertTrue(endTime - startTime >= waitMs); +})(); + +(function TestWaitNotEqual() { + var i32a = new Int32Array(new SharedArrayBuffer(16)); + assertEquals(Atomics.NOTEQUAL, Atomics.futexWait(i32a, 0, 42)); +})(); + +(function TestWaitNegativeTimeout() { + var i32a = new Int32Array(new SharedArrayBuffer(16)); + assertEquals(Atomics.TIMEDOUT, Atomics.futexWait(i32a, 0, 0, -1)); + assertEquals(Atomics.TIMEDOUT, Atomics.futexWait(i32a, 0, 0, -Infinity)); +})(); + +//// WORKER ONLY TESTS + +if (this.Worker) { + + var TestWaitWithTimeout = function(timeout) { + var sab = new SharedArrayBuffer(16); + var i32a = new Int32Array(sab); + + var workerScript = + `onmessage = function(sab) { + var i32a = new Int32Array(sab); + var result = Atomics.futexWait(i32a, 0, 0, ${timeout}); + postMessage(result); + };`; + + var worker = new Worker(workerScript); + worker.postMessage(sab, [sab]); + + // Spin until the worker is waiting on the futex. + while (%AtomicsFutexNumWaitersForTesting(i32a, 0) != 1) {} + + Atomics.futexWake(i32a, 0, 1); + assertEquals(Atomics.OK, worker.getMessage()); + worker.terminate(); + }; + + // Test various infinite timeouts + TestWaitWithTimeout(undefined); + TestWaitWithTimeout(NaN); + TestWaitWithTimeout(Infinity); + + + (function TestWakeMulti() { + var sab = new SharedArrayBuffer(20); + var i32a = new Int32Array(sab); + + // SAB values: + // i32a[id], where id in range [0, 3]: + // 0 => Worker |id| is still waiting on the futex + // 1 => Worker |id| is not waiting on futex, but has not be reaped by the + // main thread. + // 2 => Worker |id| has been reaped. + // + // i32a[4]: + // always 0. Each worker is waiting on this index. + + var workerScript = + `onmessage = function(msg) { + var id = msg.id; + var i32a = new Int32Array(msg.sab); + + // Wait on i32a[4] (should be zero). + var result = Atomics.futexWait(i32a, 4, 0); + // Set i32a[id] to 1 to notify the main thread which workers were + // woken up. + Atomics.store(i32a, id, 1); + postMessage(result); + };`; + + var id; + var workers = []; + for (id = 0; id < 4; id++) { + workers[id] = new Worker(workerScript); + workers[id].postMessage({sab: sab, id: id}, [sab]); + } + + // Spin until all workers are waiting on the futex. + while (%AtomicsFutexNumWaitersForTesting(i32a, 4) != 4) {} + + // Wake up three waiters. + assertEquals(3, Atomics.futexWake(i32a, 4, 3)); + + var wokenCount = 0; + var waitingId = 0 + 1 + 2 + 3; + while (wokenCount < 3) { + for (id = 0; id < 4; id++) { + // Look for workers that have not yet been reaped. Set i32a[id] to 2 + // when they've been processed so we don't look at them again. + if (Atomics.compareExchange(i32a, id, 1, 2) == 1) { + assertEquals(Atomics.OK, workers[id].getMessage()); + workers[id].terminate(); + waitingId -= id; + wokenCount++; + } + } + } + + assertEquals(3, wokenCount); + assertEquals(0, Atomics.load(i32a, waitingId)); + assertEquals(1, %AtomicsFutexNumWaitersForTesting(i32a, 4)); + + // Finally wake the last waiter. + assertEquals(1, Atomics.futexWake(i32a, 4, 1)); + assertEquals(Atomics.OK, workers[waitingId].getMessage()); + workers[waitingId].terminate(); + + assertEquals(0, %AtomicsFutexNumWaitersForTesting(i32a, 4)); + + })(); + + (function TestWakeOrRequeue() { + var sab = new SharedArrayBuffer(24); + var i32a = new Int32Array(sab); + + // SAB values: + // i32a[id], where id in range [0, 3]: + // 0 => Worker |id| is still waiting on the futex + // 1 => Worker |id| is not waiting on futex, but has not be reaped by the + // main thread. + // 2 => Worker |id| has been reaped. + // + // i32a[4]: + // always 0. Each worker will initially wait on this index. + // + // i32a[5]: + // always 0. Requeued workers will wait on this index. + + var workerScript = + `onmessage = function(msg) { + var id = msg.id; + var i32a = new Int32Array(msg.sab); + + var result = Atomics.futexWait(i32a, 4, 0, Infinity); + Atomics.store(i32a, id, 1); + postMessage(result); + };`; + + var workers = []; + for (id = 0; id < 4; id++) { + workers[id] = new Worker(workerScript); + workers[id].postMessage({sab: sab, id: id}, [sab]); + } + + // Spin until all workers are waiting on the futex. + while (%AtomicsFutexNumWaitersForTesting(i32a, 4) != 4) {} + + var index1 = 4; + var index2 = 5; + + // If futexWakeOrRequeue is called with the incorrect value, it shouldn't + // wake any waiters. + assertEquals(Atomics.NOTEQUAL, + Atomics.futexWakeOrRequeue(i32a, index1, 1, 42, index2)); + + assertEquals(4, %AtomicsFutexNumWaitersForTesting(i32a, index1)); + assertEquals(0, %AtomicsFutexNumWaitersForTesting(i32a, index2)); + + // Now wake with the correct value. + assertEquals(1, Atomics.futexWakeOrRequeue(i32a, index1, 1, 0, index2)); + + // The workers that are still waiting should atomically be transferred to + // the new index. + assertEquals(3, %AtomicsFutexNumWaitersForTesting(i32a, index2)); + + // The woken worker may not have been scheduled yet. Look for which thread + // has set its i32a value to 1. + var wokenCount = 0; + while (wokenCount < 1) { + for (id = 0; id < 4; id++) { + if (Atomics.compareExchange(i32a, id, 1, 2) == 1) { + wokenCount++; + } + } + } + + assertEquals(0, %AtomicsFutexNumWaitersForTesting(i32a, index1)); + + // Wake the remaining waiters. + assertEquals(3, Atomics.futexWake(i32a, index2, 3)); + + // As above, wait until the workers have been scheduled. + wokenCount = 0; + while (wokenCount < 3) { + for (id = 0; id < 4; id++) { + if (Atomics.compareExchange(i32a, id, 1, 2) == 1) { + wokenCount++; + } + } + } + + assertEquals(0, %AtomicsFutexNumWaitersForTesting(i32a, index1)); + assertEquals(0, %AtomicsFutexNumWaitersForTesting(i32a, index2)); + + for (id = 0; id < 4; ++id) { + assertEquals(Atomics.OK, workers[id].getMessage()); + workers[id].terminate(); + } + + })(); + +} diff --git a/deps/v8/test/mjsunit/harmony/new-target.js b/deps/v8/test/mjsunit/harmony/new-target.js index 587461a958..d98f5f8098 100644 --- a/deps/v8/test/mjsunit/harmony/new-target.js +++ b/deps/v8/test/mjsunit/harmony/new-target.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-classes --harmony-new-target --harmony-reflect +// Flags: --harmony-new-target --harmony-reflect --harmony-destructuring // Flags: --harmony-rest-parameters --harmony-arrow-functions @@ -368,3 +368,31 @@ a2 = 3; f(1, 2, 3); })(); + + +(function TestOtherScopes() { + function f1() { return eval("'use strict'; new.target") } + assertSame(f1, new f1); + function f2() { with ({}) return new.target } + assertSame(f2, new f2); + function f3({a}) { return new.target } + assertSame(f3, new f3({})); + function f4(...a) { return new.target } + assertSame(f4, new f4); + function f5() { 'use strict'; { let x; return new.target } } + assertSame(f5, new f5); + function f6() { with ({'new.target': 42}) return new.target } + assertSame(f6, new f6); +})(); + + +(function TestEarlyErrors() { + assertThrows(function() { Function("new.target = 42"); }, ReferenceError); + assertThrows(function() { Function("var foo = 1; new.target = foo = 42"); }, ReferenceError); + assertThrows(function() { Function("var foo = 1; foo = new.target = 42"); }, ReferenceError); + assertThrows(function() { Function("new.target--"); }, ReferenceError); + assertThrows(function() { Function("--new.target"); }, ReferenceError); + assertThrows(function() { Function("(new.target)++"); }, ReferenceError); + assertThrows(function() { Function("++(new.target)"); }, ReferenceError); + assertThrows(function() { Function("for (new.target of {});"); }, SyntaxError); +})(); diff --git a/deps/v8/test/mjsunit/harmony/proxies.js b/deps/v8/test/mjsunit/harmony/proxies.js index 585574eb43..f1d37b445a 100644 --- a/deps/v8/test/mjsunit/harmony/proxies.js +++ b/deps/v8/test/mjsunit/harmony/proxies.js @@ -382,6 +382,10 @@ function TestSet2(create, handler) { assertEquals(46, (function(n) { return p[n] = 46 })(99)) assertEquals("99", key) assertEquals(46, val) + + assertEquals(47, p["0"] = 47) + assertEquals("0", key) + assertEquals(47, val) } TestSet({ diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-405844.js b/deps/v8/test/mjsunit/harmony/regress/regress-405844.js index fbe7310d79..3d3561f7a5 100644 --- a/deps/v8/test/mjsunit/harmony/regress/regress-405844.js +++ b/deps/v8/test/mjsunit/harmony/regress/regress-405844.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Flags: --harmony-proxies +// Flags: --harmony-proxies --harmony-object-observe var proxy = Proxy.create({ fix: function() { return {}; } }); Object.preventExtensions(proxy); diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-4298.js b/deps/v8/test/mjsunit/harmony/regress/regress-4298.js new file mode 100644 index 0000000000..98e69d1acf --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/regress/regress-4298.js @@ -0,0 +1,8 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --harmony-spread-arrays + +var arr = [1, 2, ...[3]]; +assertEquals([1, 2, 3], arr); diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-4417.js b/deps/v8/test/mjsunit/harmony/regress/regress-4417.js new file mode 100644 index 0000000000..fb773f5fac --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/regress/regress-4417.js @@ -0,0 +1,12 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --harmony-spread-arrays + +var arr = [1, 2, 3]; +assertEquals({arr: [1, 2, 3]}, {arr: [...arr]}); +assertEquals([[1, 2, 3]], [[...arr]]); + +assertEquals({arr: [6, 5, [1, 2, 3]]}, {arr: [6, 5, [...arr]]}); +assertEquals([8, 7, [6, 5, [1, 2, 3]]], [8, 7, [6, 5, [...arr]]]); diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-513474.js b/deps/v8/test/mjsunit/harmony/regress/regress-513474.js new file mode 100644 index 0000000000..ec4bc84a30 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/regress/regress-513474.js @@ -0,0 +1,7 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-rest-parameters + +(function(...a) { function f() { eval() } })(); diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-517455.js b/deps/v8/test/mjsunit/harmony/regress/regress-517455.js new file mode 100644 index 0000000000..a59fa181b7 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/regress/regress-517455.js @@ -0,0 +1,8 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --harmony-destructuring + +function f({x = ""}) { eval(x) } +f({}) diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-crbug-451770.js b/deps/v8/test/mjsunit/harmony/regress/regress-crbug-451770.js index eaf1d1961f..770c8073cf 100644 --- a/deps/v8/test/mjsunit/harmony/regress/regress-crbug-451770.js +++ b/deps/v8/test/mjsunit/harmony/regress/regress-crbug-451770.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --harmony-computed-property-names --harmony-sloppy +// Flags: --harmony-sloppy assertThrows(function f() { var t = { toString: function() { throw new Error(); } }; diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js b/deps/v8/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js index 301ece70fe..1460889f45 100644 --- a/deps/v8/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js +++ b/deps/v8/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js @@ -25,6 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Flags: --harmony-object-observe // Flags: --allow-natives-syntax // // Test passes if it does not crash. diff --git a/deps/v8/test/mjsunit/harmony/simd.js b/deps/v8/test/mjsunit/harmony/simd.js new file mode 100644 index 0000000000..0c52072646 --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/simd.js @@ -0,0 +1,560 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-simd --harmony-tostring --harmony-reflect +// Flags: --allow-natives-syntax --expose-natives-as natives --noalways-opt + +function lanesForType(typeName) { + // The lane count follows the first 'x' in the type name, which begins with + // 'float', 'int', or 'bool'. + return Number.parseInt(typeName.substr(typeName.indexOf('x') + 1)); +} + + +// Creates an instance that has been zeroed, so it can be used for equality +// testing. +function createInstance(type) { + // Provide enough parameters for the longest type (currently 16). It's + // important that instances be consistent to better test that different SIMD + // types can't be compared and are never equal or the same in any sense. + return SIMD[type](0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); +} + + +function isValidSimdString(string, value, type, lanes) { + var simdFn = SIMD[type], + parseFn = + type.indexOf('Float') === 0 ? Number.parseFloat : Number.parseInt, + indexOfOpenParen = string.indexOf('('); + // Check prefix (e.g. SIMD.Float32x4.) + if (string.substr(0, indexOfOpenParen) !== 'SIMD.' + type) + return false; + // Remove type name (e.g. SIMD.Float32x4) and open parenthesis. + string = string.substr(indexOfOpenParen + 1); + var laneStrings = string.split(','); + if (laneStrings.length !== lanes) + return false; + for (var i = 0; i < lanes; i++) { + var fromString = parseFn(laneStrings[i]), + fromValue = simdFn.extractLane(value, i); + if (Math.abs(fromString - fromValue) > Number.EPSILON) + return false; + } + return true; +} + + +var simdTypeNames = ['Float32x4', 'Int32x4', 'Bool32x4', + 'Int16x8', 'Bool16x8', + 'Int8x16', 'Bool8x16']; + +var nonSimdValues = [347, 1.275, NaN, "string", null, undefined, {}, + function() {}]; + +function checkTypeMatrix(type, fn) { + // Check against non-SIMD types. + nonSimdValues.forEach(fn); + // Check against SIMD values of a different type. + for (var i = 0; i < simdTypeNames.length; i++) { + var otherType = simdTypeNames[i]; + if (type != otherType) fn(createInstance(otherType)); + } +} + + +// Test different forms of constructor calls. +function TestConstructor(type, lanes) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + + assertFalse(Object === simdFn.prototype.constructor) + assertFalse(simdFn === Object.prototype.constructor) + assertSame(simdFn, simdFn.prototype.constructor) + + assertSame(simdFn, instance.__proto__.constructor) + assertSame(simdFn, Object(instance).__proto__.constructor) + assertSame(simdFn.prototype, instance.__proto__) + assertSame(simdFn.prototype, Object(instance).__proto__) +} + + +function TestType(type, lanes) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + var typeofString = type.charAt(0).toLowerCase() + type.slice(1); + + assertEquals(typeofString, typeof instance) + assertTrue(typeof instance === typeofString) + assertTrue(typeof Object(instance) === 'object') + assertEquals(null, %_ClassOf(instance)) + assertEquals(type, %_ClassOf(Object(instance))) +} + + +function TestPrototype(type, lanes) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + + assertSame(Object.prototype, simdFn.prototype.__proto__) + assertSame(simdFn.prototype, instance.__proto__) + assertSame(simdFn.prototype, Object(instance).__proto__) +} + + +function TestValueOf(type, lanes) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + + assertTrue(instance === Object(instance).valueOf()) + assertTrue(instance === instance.valueOf()) + assertTrue(simdFn.prototype.valueOf.call(Object(instance)) === instance) + assertTrue(simdFn.prototype.valueOf.call(instance) === instance) +} + + +function TestGet(type, lanes) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + + assertEquals(undefined, instance.a) + assertEquals(undefined, instance["a" + "b"]) + assertEquals(undefined, instance["" + "1"]) + assertEquals(undefined, instance[42]) +} + + +function TestToBoolean(type, lanes) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + + assertTrue(Boolean(Object(instance))) + assertFalse(!Object(instance)) + assertTrue(Boolean(instance).valueOf()) + assertFalse(!instance) + assertTrue(!!instance) + assertTrue(instance && true) + assertFalse(!instance && false) + assertTrue(!instance || true) + assertEquals(1, instance ? 1 : 2) + assertEquals(2, !instance ? 1 : 2) + if (!instance) assertUnreachable(); + if (instance) {} else assertUnreachable(); +} + + +function TestToString(type, lanes) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + + assertEquals(instance.toString(), String(instance)) + assertTrue(isValidSimdString(instance.toString(), instance, type, lanes)) + assertTrue( + isValidSimdString(Object(instance).toString(), instance, type, lanes)) + assertTrue(isValidSimdString( + simdFn.prototype.toString.call(instance), instance, type, lanes)) +} + + +function TestToNumber(type, lanes) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + + assertThrows(function() { Number(Object(instance)) }, TypeError) + assertThrows(function() { +Object(instance) }, TypeError) + assertThrows(function() { Number(instance) }, TypeError) + assertThrows(function() { instance + 0 }, TypeError) +} + + +function TestCoercions(type, lanes) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + // Test that setting a lane to value 'a' results in a lane with value 'b'. + function test(a, b) { + for (var i = 0; i < lanes; i++) { + var ainstance = simdFn.replaceLane(instance, i, a); + var lane_value = simdFn.extractLane(ainstance, i); + assertSame(b, lane_value); + } + } + + switch (type) { + case 'Float32x4': + test(0, 0); + test(-0, -0); + test(NaN, NaN); + test(null, 0); + test(undefined, NaN); + test("5.25", 5.25); + test(Number.MAX_VALUE, Infinity); + test(-Number.MAX_VALUE, -Infinity); + test(Number.MIN_VALUE, 0); + break; + case 'Int32x4': + test(Infinity, 0); + test(-Infinity, 0); + test(NaN, 0); + test(0, 0); + test(-0, 0); + test(Number.MIN_VALUE, 0); + test(-Number.MIN_VALUE, 0); + test(0.1, 0); + test(-0.1, 0); + test(1, 1); + test(1.1, 1); + test(-1, -1); + test(-1.6, -1); + test(2147483647, 2147483647); + test(2147483648, -2147483648); + test(2147483649, -2147483647); + test(4294967295, -1); + test(4294967296, 0); + test(4294967297, 1); + break; + case 'Int16x8': + test(Infinity, 0); + test(-Infinity, 0); + test(NaN, 0); + test(0, 0); + test(-0, 0); + test(Number.MIN_VALUE, 0); + test(-Number.MIN_VALUE, 0); + test(0.1, 0); + test(-0.1, 0); + test(1, 1); + test(1.1, 1); + test(-1, -1); + test(-1.6, -1); + test(32767, 32767); + test(32768, -32768); + test(32769, -32767); + test(65535, -1); + test(65536, 0); + test(65537, 1); + break; + case 'Int8x16': + test(Infinity, 0); + test(-Infinity, 0); + test(NaN, 0); + test(0, 0); + test(-0, 0); + test(Number.MIN_VALUE, 0); + test(-Number.MIN_VALUE, 0); + test(0.1, 0); + test(-0.1, 0); + test(1, 1); + test(1.1, 1); + test(-1, -1); + test(-1.6, -1); + test(127, 127); + test(128, -128); + test(129, -127); + test(255, -1); + test(256, 0); + test(257, 1); + break; + case 'Bool32x4': + case 'Bool16x8': + case 'Bool8x16': + test(true, true); + test(false, false); + test(0, false); + test(1, true); + test(0.1, true); + test(NaN, false); + test(null, false); + test("", false); + test("false", true); + break; + } +} + + +function TestEquality(type, lanes) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + + // Every SIMD value should equal itself, and non-strictly equal its wrapper. + assertSame(instance, instance) + assertEquals(instance, instance) + assertTrue(Object.is(instance, instance)) + assertTrue(instance === instance) + assertTrue(instance == instance) + assertFalse(instance === Object(instance)) + assertFalse(Object(instance) === instance) + assertFalse(instance == Object(instance)) + assertFalse(Object(instance) == instance) + assertTrue(instance === instance.valueOf()) + assertTrue(instance.valueOf() === instance) + assertTrue(instance == instance.valueOf()) + assertTrue(instance.valueOf() == instance) + assertFalse(Object(instance) === Object(instance)) + assertEquals(Object(instance).valueOf(), Object(instance).valueOf()) + + function notEqual(other) { + assertFalse(instance === other) + assertFalse(other === instance) + assertFalse(instance == other) + assertFalse(other == instance) + } + + // SIMD values should not be equal to instances of different types. + checkTypeMatrix(type, function(other) { + assertFalse(instance === other) + assertFalse(other === instance) + assertFalse(instance == other) + assertFalse(other == instance) + }); + + // Test that f(a, b) is the same as f(SIMD(a), SIMD(b)) for equality and + // strict equality, at every lane. + function test(a, b) { + for (var i = 0; i < lanes; i++) { + var aval = simdFn.replaceLane(instance, i, a); + var bval = simdFn.replaceLane(instance, i, b); + assertSame(a == b, aval == bval); + assertSame(a === b, aval === bval); + } + } + + switch (type) { + case 'Float32x4': + test(1, 2.5); + test(1, 1); + test(0, 0); + test(-0, +0); + test(+0, -0); + test(-0, -0); + test(0, NaN); + test(NaN, NaN); + break; + case 'Int32x4': + case 'Int16x8': + case 'Int8x16': + test(1, 2); + test(1, 1); + test(1, -1); + break; + case 'Bool32x4': + case 'Bool16x8': + case 'Bool8x16': + test(true, false); + test(false, true); + break; + } +} + + +function TestSameValue(type, lanes) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + var sameValue = natives.$sameValue; + var sameValueZero = natives.$sameValueZero; + + // SIMD values should not be the same as instances of different types. + checkTypeMatrix(type, function(other) { + assertFalse(sameValue(instance, other)); + assertFalse(sameValueZero(instance, other)); + }); + + // Test that f(a, b) is the same as f(SIMD(a), SIMD(b)) for sameValue and + // sameValueZero, at every lane. + function test(a, b) { + for (var i = 0; i < lanes; i++) { + var aval = simdFn.replaceLane(instance, i, a); + var bval = simdFn.replaceLane(instance, i, b); + assertSame(sameValue(a, b), sameValue(aval, bval)); + assertSame(sameValueZero(a, b), sameValueZero(aval, bval)); + } + } + + switch (type) { + case 'Float32x4': + test(1, 2.5); + test(1, 1); + test(0, 0); + test(-0, +0); + test(+0, -0); + test(-0, -0); + test(0, NaN); + test(NaN, NaN); + break; + case 'Int32x4': + case 'Int16x8': + case 'Int8x16': + test(1, 2); + test(1, 1); + test(1, -1); + break; + case 'Bool32x4': + case 'Bool16x8': + case 'Bool8x16': + test(true, false); + test(false, true); + break; + } +} + + +function TestComparison(type, lanes) { + var simdFn = SIMD[type]; + var a = createInstance(type), b = createInstance(type); + + function compare(other) { + var throwFuncs = [ + function lt() { a < b; }, + function gt() { a > b; }, + function le() { a <= b; }, + function ge() { a >= b; }, + function lt_same() { a < a; }, + function gt_same() { a > a; }, + function le_same() { a <= a; }, + function ge_same() { a >= a; }, + ]; + + for (var f of throwFuncs) { + assertThrows(f, TypeError); + %OptimizeFunctionOnNextCall(f); + assertThrows(f, TypeError); + assertThrows(f, TypeError); + } + } + + // Test comparison against the same SIMD type. + compare(b); + // Test comparison against other types. + checkTypeMatrix(type, compare); +} + + +// Test SIMD value wrapping/boxing over non-builtins. +function TestCall(type, lanes) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + simdFn.prototype.getThisProto = function () { + return Object.getPrototypeOf(this); + } + assertTrue(instance.getThisProto() === simdFn.prototype) +} + + +function TestAsSetKey(type, lanes, set) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + + function test(set, key) { + assertFalse(set.has(key)); + assertFalse(set.delete(key)); + if (!(set instanceof WeakSet)) { + assertSame(set, set.add(key)); + assertTrue(set.has(key)); + assertTrue(set.delete(key)); + } else { + // SIMD values can't be used as keys in WeakSets. + assertThrows(function() { set.add(key) }); + } + assertFalse(set.has(key)); + assertFalse(set.delete(key)); + assertFalse(set.has(key)); + } + + test(set, instance); +} + + +function TestAsMapKey(type, lanes, map) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + + function test(map, key, value) { + assertFalse(map.has(key)); + assertSame(undefined, map.get(key)); + assertFalse(map.delete(key)); + if (!(map instanceof WeakMap)) { + assertSame(map, map.set(key, value)); + assertSame(value, map.get(key)); + assertTrue(map.has(key)); + assertTrue(map.delete(key)); + } else { + // SIMD values can't be used as keys in WeakMaps. + assertThrows(function() { map.set(key, value) }); + } + assertFalse(map.has(key)); + assertSame(undefined, map.get(key)); + assertFalse(map.delete(key)); + assertFalse(map.has(key)); + assertSame(undefined, map.get(key)); + } + + test(map, instance, {}); +} + + +// Test SIMD type with Harmony reflect-apply. +function TestReflectApply(type) { + var simdFn = SIMD[type]; + var instance = createInstance(type); + + function returnThis() { return this; } + function returnThisStrict() { 'use strict'; return this; } + function noop() {} + function noopStrict() { 'use strict'; } + var R = void 0; + + assertSame(SIMD[type].prototype, + Object.getPrototypeOf( + Reflect.apply(returnThis, instance, []))); + assertSame(instance, Reflect.apply(returnThisStrict, instance, [])); + + assertThrows( + function() { 'use strict'; Reflect.apply(instance); }, TypeError); + assertThrows( + function() { Reflect.apply(instance); }, TypeError); + assertThrows( + function() { Reflect.apply(noopStrict, R, instance); }, TypeError); + assertThrows( + function() { Reflect.apply(noop, R, instance); }, TypeError); +} + + +function TestSIMDTypes() { + for (var i = 0; i < simdTypeNames.length; ++i) { + var type = simdTypeNames[i], + lanes = lanesForType(type); + TestConstructor(type, lanes); + TestType(type, lanes); + TestPrototype(type, lanes); + TestValueOf(type, lanes); + TestGet(type, lanes); + TestToBoolean(type, lanes); + TestToString(type, lanes); + TestToNumber(type, lanes); + TestCoercions(type, lanes); + TestEquality(type, lanes); + TestSameValue(type, lanes); + TestComparison(type, lanes); + TestCall(type, lanes); + TestAsSetKey(type, lanes, new Set); + TestAsSetKey(type, lanes, new WeakSet); + TestAsMapKey(type, lanes, new Map); + TestAsMapKey(type, lanes, new WeakMap); + TestReflectApply(type); + } +} +TestSIMDTypes(); + +// Tests for the global SIMD object. +function TestSIMDObject() { + assertSame(typeof SIMD, 'object'); + assertSame(SIMD.constructor, Object); + assertSame(Object.getPrototypeOf(SIMD), Object.prototype); + assertSame(SIMD + "", "[object SIMD]"); + // The SIMD object is mutable. + SIMD.foo = "foo"; + assertSame(SIMD.foo, "foo"); + delete SIMD.foo; + delete SIMD.Bool8x16; + assertSame(SIMD.Bool8x16, undefined); +} +TestSIMDObject() diff --git a/deps/v8/test/mjsunit/harmony/super.js b/deps/v8/test/mjsunit/harmony/super.js index 21b31d96c9..601addaa0e 100644 --- a/deps/v8/test/mjsunit/harmony/super.js +++ b/deps/v8/test/mjsunit/harmony/super.js @@ -3,7 +3,8 @@ // found in the LICENSE file. // Flags: --harmony-arrow-functions --allow-natives-syntax -// Flags: --harmony-spreadcalls +// Flags: --harmony-spreadcalls --harmony-destructuring +// Flags: --harmony-rest-parameters --harmony-sloppy (function TestSuperNamedLoads() { function Base() { } @@ -1979,7 +1980,8 @@ TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44); class Derived extends Base { constructor() { - super(); + let r = super(); + assertEquals(this, r); derivedCalled++; } } @@ -1995,7 +1997,8 @@ TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44); class DerivedDerived extends Derived { constructor() { - super(); + let r = super(); + assertEquals(this, r); derivedDerivedCalled++; } } @@ -2015,7 +2018,8 @@ TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44); } class Derived2 extends Base2 { constructor(v1, v2) { - super(v1); + let r = super(v1); + assertEquals(this, r); this.fromDerived = v2; } } @@ -2119,6 +2123,34 @@ TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44); })(); +(function TestSuperInOtherScopes() { + var p = {x: 99}; + var o0 = {__proto__: p, f() { return eval("'use strict'; super.x") }}; + assertEquals(p.x, o0.f()); + var o1 = {__proto__: p, f() { with ({}) return super.x }}; + assertEquals(p.x, o1.f()); + var o2 = {__proto__: p, f({a}) { return super.x }}; + assertEquals(p.x, o2.f({})); + var o3 = {__proto__: p, f(...a) { return super.x }}; + assertEquals(p.x, o3.f()); + var o4 = {__proto__: p, f() { 'use strict'; { let x; return super.x } }}; + assertEquals(p.x, o4.f()); +})(); + + +(function TestSuperCallInOtherScopes() { + class C {constructor() { this.x = 99 }} + class D0 extends C {constructor() { eval("'use strict'; super()") }} + assertEquals(99, (new D0).x); + class D2 extends C {constructor({a}) { super() }} + assertEquals(99, (new D2({})).x); + class D3 extends C {constructor(...a) { super() }} + assertEquals(99, (new D3()).x); + class D4 extends C {constructor() { { let x; super() } }} + assertEquals(99, (new D4).x); +})(); + + (function TestSuperCallInEval() { 'use strict'; class Base { @@ -2128,7 +2160,8 @@ TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44); } class Derived extends Base { constructor(x) { - eval('super(x)'); + let r = eval('super(x)'); + assertEquals(this, r); } } let d = new Derived(42); @@ -2145,7 +2178,8 @@ TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44); } class Derived extends Base { constructor(x) { - (() => super(x))(); + let r = (() => super(x))(); + assertEquals(this, r); } } let d = new Derived(42); @@ -2181,6 +2215,47 @@ TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44); })(); +(function TestSuperCallInLoop() { + 'use strict'; + class Base { + constructor(x) { + this.x = x; + } + } + class Derived extends Base { + constructor(x, n) { + for (var i = 0; i < n; ++i) { + super(x); + } + } + } + + let o = new Derived(23, 1); + assertEquals(23, o.x); + assertInstanceof(o, Derived); + + assertThrows("new Derived(42, 0)", ReferenceError); + assertThrows("new Derived(65, 2)", ReferenceError); +})(); + + +(function TestSuperCallReentrant() { + 'use strict'; + class Base { + constructor(fun) { + this.x = fun(); + } + } + class Derived extends Base { + constructor(x) { + let f = () => super(() => x) + super(f); + } + } + assertThrows("new Derived(23)", ReferenceError); +})(); + + (function TestSuperCallSpreadInEval() { 'use strict'; class Base { @@ -2190,7 +2265,8 @@ TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44); } class Derived extends Base { constructor(x) { - eval('super(...[x])'); + let r = eval('super(...[x])'); + assertEquals(this, r); } } let d = new Derived(42); @@ -2207,7 +2283,8 @@ TestKeyedSetterCreatingOwnPropertiesNonConfigurable(42, 43, 44); } class Derived extends Base { constructor(x) { - (() => super(...[x]))(); + let r = (() => super(...[x]))(); + assertEquals(this, r); } } let d = new Derived(42); diff --git a/deps/v8/test/mjsunit/harmony/typed-array-includes.js b/deps/v8/test/mjsunit/harmony/typed-array-includes.js new file mode 100644 index 0000000000..017a4301ee --- /dev/null +++ b/deps/v8/test/mjsunit/harmony/typed-array-includes.js @@ -0,0 +1,203 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-array-includes + +// Largely ported from +// https://github.com/tc39/Array.prototype.includes/tree/master/test/built-ins/TypedArray/prototype/includes +// using https://www.npmjs.org/package/test262-to-mjsunit with further edits + + +function testTypedArrays(callback) { + [ + Uint8Array, + Int8Array, + Uint16Array, + Int16Array, + Uint32Array, + Int32Array, + Uint8ClampedArray, + Float32Array, + Float64Array + ] + .forEach(callback); +} + +testTypedArrays.floatOnly = function (callback) { + [Float32Array, Float64Array].forEach(callback); +}; + + +// %TypedArray%.prototype.includes throws a TypeError when used on non-typed +// arrays +(function() { + var taIncludes = Uint8Array.prototype.includes; + + assertThrows(function() { + taIncludes.call({ + length: 2, + 0: 1, + 1: 2 + }, 2); + }, TypeError); + + assertThrows(function() { + taIncludes.call([1, 2, 3], 2); + }, TypeError); + + assertThrows(function() { + taIncludes.call(null, 2); + }, TypeError); + + assertThrows(function() { + taIncludes.call(undefined, 2); + }, TypeError); +})(); + + +// %TypedArray%.prototype.includes should terminate if ToNumber ends up being +// called on a symbol fromIndex +(function() { + testTypedArrays(function(TypedArrayConstructor) { + var ta = new TypedArrayConstructor([1, 2, 3]); + + assertThrows(function() { + ta.includes(2, Symbol()); + }, TypeError); + }); +})(); + + +// %TypedArray%.prototype.includes should terminate if an exception occurs +// converting the fromIndex to a number +(function() { + function Test262Error() {} + + var fromIndex = { + valueOf: function() { + throw new Test262Error(); + } + }; + + testTypedArrays(function(TypedArrayConstructor) { + var ta = new TypedArrayConstructor([1, 2, 3]); + + assertThrows(function() { + ta.includes(2, fromIndex); + }, Test262Error); + }); +})(); + + +// %TypedArray%.prototype.includes should search the whole array, as the +// optional second argument fromIndex defaults to 0 +(function() { + testTypedArrays(function(TypedArrayConstructor) { + var ta = new TypedArrayConstructor([1, 2, 3]); + assertTrue(ta.includes(1)); + assertTrue(ta.includes(2)); + assertTrue(ta.includes(3)); + }); +})(); + + +// %TypedArray%.prototype.includes returns false if fromIndex is greater or +// equal to the length of the array +(function() { + testTypedArrays(function(TypedArrayConstructor) { + var ta = new TypedArrayConstructor([1, 2]); + assertFalse(ta.includes(2, 3)); + assertFalse(ta.includes(2, 2)); + }); +})(); + + +// %TypedArray%.prototype.includes searches the whole array if the computed +// index from the given negative fromIndex argument is less than 0 +(function() { + testTypedArrays(function(TypedArrayConstructor) { + var ta = new TypedArrayConstructor([1, 3]); + assertTrue(ta.includes(1, -4)); + assertTrue(ta.includes(1, -4)); + }); +})(); + + +// %TypedArray%.prototype.includes should use a negative value as the offset +// from the end of the array to compute fromIndex +(function() { + testTypedArrays(function(TypedArrayConstructor) { + var ta = new TypedArrayConstructor([12, 13]); + assertTrue(ta.includes(13, -1)); + assertFalse(ta.includes(12, -1)); + assertTrue(ta.includes(12, -2)); + }); +})(); + + +// %TypedArray%.prototype.includes converts its fromIndex parameter to an +// integer +(function() { + testTypedArrays(function(TypedArrayConstructor) { + var ta = new TypedArrayConstructor([1, 2, 3]); + assertFalse(ta.includes(1, 3.3)); + assertTrue(ta.includes(1, -Infinity)); + assertTrue(ta.includes(3, 2.9)); + assertTrue(ta.includes(3, NaN)); + + var numberLike = { + valueOf: function() { + return 2; + } + }; + + assertFalse(ta.includes(1, numberLike)); + assertFalse(ta.includes(1, "2")); + assertTrue(ta.includes(3, numberLike)); + assertTrue(ta.includes(3, "2")); + }); +})(); + + +// %TypedArray%.prototype.includes should have length 1 +(function() { + assertEquals(1, Uint8Array.prototype.includes.length); +})(); + + +// %TypedArray%.prototype.includes should have name property with value +// 'includes' +(function() { + assertEquals("includes", Uint8Array.prototype.includes.name); +})(); + + +// %TypedArray%.prototype.includes should always return false on zero-length +// typed arrays +(function() { + testTypedArrays(function(TypedArrayConstructor) { + var ta = new TypedArrayConstructor([]); + assertFalse(ta.includes(2)); + assertFalse(ta.includes()); + assertFalse(ta.includes(undefined)); + assertFalse(ta.includes(NaN)); + }); +})(); + + +// %TypedArray%.prototype.includes should use the SameValueZero algorithm to +// compare +(function() { + testTypedArrays.floatOnly(function(FloatArrayConstructor) { + assertTrue(new FloatArrayConstructor([1, 2, NaN]).includes(NaN)); + assertTrue(new FloatArrayConstructor([1, 2, -0]).includes(+0)); + assertTrue(new FloatArrayConstructor([1, 2, -0]).includes(-0)); + assertTrue(new FloatArrayConstructor([1, 2, +0]).includes(-0)); + assertTrue(new FloatArrayConstructor([1, 2, +0]).includes(+0)); + assertFalse(new FloatArrayConstructor([1, 2, -Infinity]).includes(+Infinity)); + assertTrue(new FloatArrayConstructor([1, 2, -Infinity]).includes(-Infinity)); + assertFalse(new FloatArrayConstructor([1, 2, +Infinity]).includes(-Infinity)); + assertTrue(new FloatArrayConstructor([1, 2, +Infinity]).includes(+Infinity)); + }); +})(); diff --git a/deps/v8/test/mjsunit/invalid-lhs.js b/deps/v8/test/mjsunit/invalid-lhs.js index 52ee89582a..d28dc9ccf8 100644 --- a/deps/v8/test/mjsunit/invalid-lhs.js +++ b/deps/v8/test/mjsunit/invalid-lhs.js @@ -50,9 +50,9 @@ assertDoesNotThrow("if (false) ++(eval('12'))", ReferenceError); assertDoesNotThrow("if (false) (eval('12'))++", ReferenceError); // For in: -assertThrows("for (12 in [1]) print(12);", ReferenceError); +assertThrows("for (12 in [1]) print(12);", SyntaxError); assertThrows("for (eval('var x') in [1]) print(12);", ReferenceError); -assertThrows("if (false) for (12 in [1]) print(12);", ReferenceError); +assertThrows("if (false) for (12 in [1]) print(12);", SyntaxError); assertDoesNotThrow("if (false) for (eval('0') in [1]) print(12);", ReferenceError); // For: @@ -64,7 +64,7 @@ assertDoesNotThrow("if (false) for (eval('var x') = 1;;) print(12);", ReferenceE // Assignments to 'this'. assertThrows("this = 42", ReferenceError); assertThrows("function f() { this = 12; }", ReferenceError); -assertThrows("for (this in {x:3, y:4, z:5}) ;", ReferenceError); +assertThrows("for (this in {x:3, y:4, z:5}) ;", SyntaxError); assertThrows("for (this = 0;;) ;", ReferenceError); assertThrows("this++", ReferenceError); assertThrows("++this", ReferenceError); diff --git a/deps/v8/test/mjsunit/messages.js b/deps/v8/test/mjsunit/messages.js index c30e59f3e1..45443c75d1 100644 --- a/deps/v8/test/mjsunit/messages.js +++ b/deps/v8/test/mjsunit/messages.js @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --stack-size=100 --harmony --harmony-reflect --harmony-arrays -// Flags: --harmony-regexps --strong-mode +// Flags: --stack-size=100 --harmony --harmony-reflect --harmony-regexps +// Flags: --harmony-simd --strong-mode function test(f, expected, type) { try { @@ -308,11 +308,6 @@ test(function() { "a" + 1; }, "In strong mode, implicit conversions are deprecated", TypeError); -// kSymbolToPrimitive -test(function() { - 1 + Object(Symbol()); -}, "Cannot convert a Symbol wrapper object to a primitive value", TypeError); - // kSymbolToString test(function() { "" + Symbol(); @@ -323,6 +318,11 @@ test(function() { 1 + Symbol(); }, "Cannot convert a Symbol value to a number", TypeError); +// kSimdToNumber +test(function() { + 1 + SIMD.Float32x4(1, 2, 3, 4); +}, "Cannot convert a SIMD value to a number", TypeError); + // kUndefinedOrNullToObject test(function() { Array.prototype.toString.call(null); diff --git a/deps/v8/test/mjsunit/migrations.js b/deps/v8/test/mjsunit/migrations.js index 288bc61031..a18d884059 100644 --- a/deps/v8/test/mjsunit/migrations.js +++ b/deps/v8/test/mjsunit/migrations.js @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-ayle license that can be // found in the LICENSE file. +// Flags: --harmony-object-observe // Flags: --allow-natives-syntax --track-fields --expose-gc var global = Function('return this')(); diff --git a/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status index 6c6a9b9755..0b333f10c9 100644 --- a/deps/v8/test/mjsunit/mjsunit.status +++ b/deps/v8/test/mjsunit/mjsunit.status @@ -132,6 +132,7 @@ # TODO(jarin/mstarzinger): Investigate debugger issues with TurboFan. 'debug-evaluate-const': [PASS, NO_VARIANTS], 'debug-evaluate-locals': [PASS, NO_VARIANTS], + 'debug-evaluate-locals-capturing': [PASS, NO_VARIANTS], 'debug-liveedit-check-stack': [PASS, NO_VARIANTS], # only in no-snap mode. 'debug-liveedit-double-call': [PASS, NO_VARIANTS], 'debug-set-variable-value': [PASS, NO_VARIANTS], @@ -244,6 +245,17 @@ # BUG(v8:3838). 'regress/regress-3116': [PASS, ['isolates', FLAKY]], + + # BUG(chromium:508074). Remove this once the issue is fixed. + 'harmony/arrow-rest-params': [PASS, NO_VARIANTS], + 'harmony/rest-params': [PASS, ['no_snap == True', NO_VARIANTS]], + + # BUG(v8:4378). + 'regress/regress-crbug-501711': [PASS, ['isolates', SKIP]], + 'regress/regress-4279': [PASS, ['isolates', SKIP]], + + # BUG(chromium:518748) + 'regress/regress-crbug-518748': [SKIP], }], # ALWAYS ['novfp3 == True', { @@ -301,11 +313,15 @@ # Issue 3723. 'regress/regress-3717': [SKIP], - # Issue 478788. - 'es7/object-observe': [SKIP], # BUG(v8:4237) 'regress/regress-3976': [SKIP], + + # BUG(v8:4359) + 'strong/load-proxy': [SKIP], + + # BUG(v8:4381) + 'for-in-opt': [PASS, FAIL], }], # 'gc_stress == True' ############################################################################## @@ -647,7 +663,6 @@ 'assert-opt-and-deopt': [SKIP], 'never-optimize': [SKIP], 'regress/regress-2185-2': [SKIP], - 'harmony/object-observe': [SKIP], 'readonly': [SKIP], 'array-feedback': [SKIP], diff --git a/deps/v8/test/mjsunit/opt-elements-kind.js b/deps/v8/test/mjsunit/opt-elements-kind.js index 5f4f437299..515305a928 100644 --- a/deps/v8/test/mjsunit/opt-elements-kind.js +++ b/deps/v8/test/mjsunit/opt-elements-kind.js @@ -33,19 +33,19 @@ // Flags: --stress-runs=2 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' + fast_smi_only : 'fast smi only elements', + fast : 'fast elements', + fast_double : 'fast double elements', + dictionary : 'dictionary elements', + fixed_int32 : 'fixed int8 elements', + fixed_uint8 : 'fixed uint8 elements', + fixed_int16 : 'fixed int16 elements', + fixed_uint16 : 'fixed uint16 elements', + fixed_int32 : 'fixed int32 elements', + fixed_uint32 : 'fixed uint32 elements', + fixed_float32 : 'fixed float32 elements', + fixed_float64 : 'fixed float64 elements', + fixed_uint8_clamped : 'fixed uint8_clamped elements' } function getKind(obj) { @@ -53,34 +53,33 @@ function getKind(obj) { if (%HasFastObjectElements(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 (%HasFixedInt8Elements(obj)) { + return elements_kind.fixed_int8; } - if (%HasExternalUnsignedByteElements(obj)) { - return elements_kind.external_unsigned_byte; + if (%HasFixedUint8Elements(obj)) { + return elements_kind.fixed_uint8; } - if (%HasExternalShortElements(obj)) { - return elements_kind.external_short; + if (%HasFixedInt16Elements(obj)) { + return elements_kind.fixed_int16; } - if (%HasExternalUnsignedShortElements(obj)) { - return elements_kind.external_unsigned_short; + if (%HasFixedUint16Elements(obj)) { + return elements_kind.fixed_uint16; } - if (%HasExternalIntElements(obj)) { - return elements_kind.external_int; + if (%HasFixedInt32Elements(obj)) { + return elements_kind.fixed_int32; } - if (%HasExternalUnsignedIntElements(obj)) { - return elements_kind.external_unsigned_int; + if (%HasFixedUint32Elements(obj)) { + return elements_kind.fixed_uint32; } - if (%HasExternalFloatElements(obj)) { - return elements_kind.external_float; + if (%HasFixedFloat32Elements(obj)) { + return elements_kind.fixed_float32; } - if (%HasExternalDoubleElements(obj)) { - return elements_kind.external_double; + if (%HasFixedFloat64Elements(obj)) { + return elements_kind.fixed_float64; } - if (%HasExternalPixelElements(obj)) { - return elements_kind.external_pixel; + if (%HasFixedUint8ClampedElements(obj)) { + return elements_kind.fixed_uint8_clamped; } } diff --git a/deps/v8/test/mjsunit/osr-elements-kind.js b/deps/v8/test/mjsunit/osr-elements-kind.js index 389b6dac6f..bd15ef37e4 100644 --- a/deps/v8/test/mjsunit/osr-elements-kind.js +++ b/deps/v8/test/mjsunit/osr-elements-kind.js @@ -33,19 +33,19 @@ // Flags: --stress-runs=2 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' + fast_smi_only : 'fast smi only elements', + fast : 'fast elements', + fast_double : 'fast double elements', + dictionary : 'dictionary elements', + fixed_int32 : 'fixed int8 elements', + fixed_uint8 : 'fixed uint8 elements', + fixed_int16 : 'fixed int16 elements', + fixed_uint16 : 'fixed uint16 elements', + fixed_int32 : 'fixed int32 elements', + fixed_uint32 : 'fixed uint32 elements', + fixed_float32 : 'fixed float32 elements', + fixed_float64 : 'fixed float64 elements', + fixed_uint8_clamped : 'fixed uint8_clamped elements' } function getKind(obj) { @@ -53,34 +53,33 @@ function getKind(obj) { if (%HasFastObjectElements(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 (%HasFixedInt8Elements(obj)) { + return elements_kind.fixed_int8; } - if (%HasExternalUnsignedByteElements(obj)) { - return elements_kind.external_unsigned_byte; + if (%HasFixedUint8Elements(obj)) { + return elements_kind.fixed_uint8; } - if (%HasExternalShortElements(obj)) { - return elements_kind.external_short; + if (%HasFixedInt16Elements(obj)) { + return elements_kind.fixed_int16; } - if (%HasExternalUnsignedShortElements(obj)) { - return elements_kind.external_unsigned_short; + if (%HasFixedUint16Elements(obj)) { + return elements_kind.fixed_uint16; } - if (%HasExternalIntElements(obj)) { - return elements_kind.external_int; + if (%HasFixedInt32Elements(obj)) { + return elements_kind.fixed_int32; } - if (%HasExternalUnsignedIntElements(obj)) { - return elements_kind.external_unsigned_int; + if (%HasFixedUint32Elements(obj)) { + return elements_kind.fixed_uint32; } - if (%HasExternalFloatElements(obj)) { - return elements_kind.external_float; + if (%HasFixedFloat32Elements(obj)) { + return elements_kind.fixed_float32; } - if (%HasExternalDoubleElements(obj)) { - return elements_kind.external_double; + if (%HasFixedFloat64Elements(obj)) { + return elements_kind.fixed_float64; } - if (%HasExternalPixelElements(obj)) { - return elements_kind.external_pixel; + if (%HasFixedUint8ClampedElements(obj)) { + return elements_kind.fixed_uint8_clamped; } } diff --git a/deps/v8/test/mjsunit/primitive-keyed-access.js b/deps/v8/test/mjsunit/primitive-keyed-access.js new file mode 100644 index 0000000000..c83975a8d3 --- /dev/null +++ b/deps/v8/test/mjsunit/primitive-keyed-access.js @@ -0,0 +1,49 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +Object.defineProperty(Number.prototype, "0", + { set: function(v) { set = v; }}); +Object.defineProperty(String.prototype, "0", + { set: function(v) { set = v; }}); +Object.defineProperty(String.prototype, "3", + { set: function(v) { set = v; }}); + +var set; +var n = 1; +set = 0; +n[0] = 100; +assertEquals(100, set); +var s = "bla"; +s[0] = 200; +assertEquals(100, set); +s[3] = 300; +assertEquals(300, set); + +assertThrows(function(){"use strict"; var o = "123"; o[1] = 10; }); +assertThrows(function(){"use strict"; var o = ""; o[1] = 10; }); +assertThrows(function(){"use strict"; var o = 1; o[1] = 10; }); + +assertThrows(function() { + "use strict"; + var sym = Symbol('66'); + sym.a = 0; +}); + +assertThrows(function() { + "use strict"; + var sym = Symbol('66'); + sym['a' + 'b'] = 0; +}); + +assertThrows(function() { + "use strict"; + var sym = Symbol('66'); + sym[62] = 0; +}); + +assertThrows(function() { + "use strict"; + var o = "bla"; + o["0"] = 1; +}); diff --git a/deps/v8/test/mjsunit/regress-4399.js b/deps/v8/test/mjsunit/regress-4399.js new file mode 100644 index 0000000000..a8fdab7d9d --- /dev/null +++ b/deps/v8/test/mjsunit/regress-4399.js @@ -0,0 +1,8 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + + +if (this.Worker) { + assertThrows(function() { Worker.prototype.constructor("55"); }); +} diff --git a/deps/v8/test/mjsunit/regress/cross-script-vars.js b/deps/v8/test/mjsunit/regress/cross-script-vars.js new file mode 100644 index 0000000000..fd235f997b --- /dev/null +++ b/deps/v8/test/mjsunit/regress/cross-script-vars.js @@ -0,0 +1,575 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +function PrintDesc(desc, s) { + var json; + if (desc) { + json = JSON.stringify(desc); + } else { + json = "<no such property>"; + } + if (s === undefined) { + print(json); + } else { + print(s + ": " + json); + } +} + + +var counters; +var test_realm; +var cfg; + + +function GetDescriptor() { + var code = 'Object.getOwnPropertyDescriptor(global, "x")'; + var desc = Realm.eval(test_realm, code); +// PrintDesc(desc); + return desc; +} + +function SetUp() { + counters = {}; + Realm.shared = {counters: counters}; + test_realm = Realm.create(); + Realm.eval(test_realm, 'var global = Realm.global(Realm.current());'); + print("====================="); + print("Test realm: " + test_realm); + assertEquals(undefined, GetDescriptor()); +} + +function TearDown() { + Realm.dispose(test_realm); + print("OK"); +} + + +function AddStrict(code, cfg) { + return cfg.strict ? '"use strict"; ' + code : code; +} + +function ForceMutablePropertyCellType() { + Realm.eval(test_realm, 'global.x = {}; global.x = undefined;'); +} + +function DeclareVar() { + var code = 'var x;'; + return Realm.eval(test_realm, AddStrict(code, cfg)); +} + +function DefineVar(v) { + var code = 'var x = ' + v; + return Realm.eval(test_realm, AddStrict(code, cfg)); +} + +function DefineLoadVar() { + var name = 'LoadVar_' + test_realm; + var code = + 'var x;' + + 'function ' + name + '() {' + + ' return x;' + + '};'; + return Realm.eval(test_realm, AddStrict(code, cfg)); +} + +function LoadVar() { + var name = 'LoadVar_' + test_realm; + var code = + (cfg.optimize ? '%OptimizeFunctionOnNextCall(' + name + ');' : '') + + name + '();'; + return Realm.eval(test_realm, AddStrict(code, cfg)); +} + +function DefineStoreVar() { + var name = 'StoreVar_' + test_realm; + var code = 'var g = (Function("return this"))();' + + 'var x;' + + 'function ' + name + '(v) {' + +// ' %DebugPrint(g);' + + ' return x = v;' + + '};'; + return Realm.eval(test_realm, AddStrict(code, cfg)); +} + +function StoreVar(v) { + var name = 'StoreVar_' + test_realm; + var code = + (cfg.optimize ? '%OptimizeFunctionOnNextCall(' + name + ');' : '') + + name + '(' + v + ');'; + return Realm.eval(test_realm, AddStrict(code, cfg)); +} + +// It does 13 iterations which results in 27 loads +// and 14 stores. +function LoadStoreLoop() { + var code = 'for(var x = 0; x < 13; x++);'; + return Realm.eval(test_realm, AddStrict(code, cfg)); +} + +function DefineRWDataProperty() { + var code = + 'Object.defineProperty(global, "x", { ' + + ' value: 42, ' + + ' writable: true, ' + + ' enumerable: true, ' + + ' configurable: true ' + + '});'; + return Realm.eval(test_realm, AddStrict(code, cfg)); +} + +function DefineRODataProperty() { + var code = + 'Object.defineProperty(global, "x", { ' + + ' value: 42, ' + + ' writable: false, ' + + ' enumerable: true, ' + + ' configurable: true ' + + '});'; + return Realm.eval(test_realm, AddStrict(code, cfg)); +} + +function SetX_(v) { + var code = + 'global.x_ = ' + v + '; '; + return Realm.eval(test_realm, code); +} + +function DefineRWAccessorProperty() { + var code = + 'Object.defineProperty(global, "x", {' + + ' get: function() { Realm.shared.counters.get_count++; return this.x_; },' + + ' set: function(v) { Realm.shared.counters.set_count++; this.x_ = v; },' + + ' enumerable: true, configurable: true' + + '});'; + counters.get_count = 0; + counters.set_count = 0; + return Realm.eval(test_realm, AddStrict(code, cfg)); +} + +function DefineROAccessorProperty() { + var code = + 'Object.defineProperty(global, "x", {' + + ' get: function() { Realm.shared.counters.get_count++; return this.x_; },' + + ' enumerable: true, configurable: true' + + '});'; + counters.get_count = 0; + counters.set_count = 0; + return Realm.eval(test_realm, AddStrict(code, cfg)); +} + + +function testSuite(opt_cfg) { + // + // Non strict. + // + + (function() { + SetUp(); + cfg = {optimize: opt_cfg.optimize, strict: false}; + DeclareVar(); + DefineLoadVar(); + DefineStoreVar(); + assertEquals(undefined, LoadVar()); + assertEquals(false, GetDescriptor().configurable); + + // Force property cell type to kMutable. + DefineVar(undefined); + DefineVar(153); + assertEquals(false, GetDescriptor().configurable); + + assertEquals(153, LoadVar()); + assertEquals(113, StoreVar(113)); + assertEquals(113, LoadVar()); + LoadStoreLoop(); + assertEquals(13, LoadVar()); + TearDown(); + })(); + + + (function() { + SetUp(); + cfg = {optimize: opt_cfg.optimize, strict: false}; + ForceMutablePropertyCellType(); + DefineLoadVar(); + DefineStoreVar(); + DefineRWDataProperty(); + assertEquals(42, LoadVar()); + assertEquals(true, GetDescriptor().configurable); + + DefineVar(153); + assertEquals(true, GetDescriptor().configurable); + + assertEquals(153, LoadVar()); + assertEquals(113, StoreVar(113)); + assertEquals(113, LoadVar()); + LoadStoreLoop(); + assertEquals(13, LoadVar()); + + // Now reconfigure to accessor. + DefineRWAccessorProperty(); + assertEquals(undefined, GetDescriptor().value); + assertEquals(true, GetDescriptor().configurable); + assertEquals(0, counters.get_count); + assertEquals(0, counters.set_count); + + assertEquals(undefined, LoadVar()); + assertEquals(1, counters.get_count); + assertEquals(0, counters.set_count); + + LoadStoreLoop(); + assertEquals(28, counters.get_count); + assertEquals(14, counters.set_count); + + assertEquals(13, LoadVar()); + assertEquals(29, counters.get_count); + assertEquals(14, counters.set_count); + + TearDown(); + })(); + + + (function() { + SetUp(); + cfg = {optimize: opt_cfg.optimize, strict: false}; + ForceMutablePropertyCellType(); + DefineLoadVar(); + DefineStoreVar(); + DefineRODataProperty(); + assertEquals(42, LoadVar()); + assertEquals(true, GetDescriptor().configurable); + + DefineVar(153); + + assertEquals(42, LoadVar()); + assertEquals(113, StoreVar(113)); + assertEquals(42, LoadVar()); + LoadStoreLoop(); + assertEquals(42, LoadVar()); + + // Now reconfigure to accessor property. + DefineRWAccessorProperty(); + assertEquals(undefined, GetDescriptor().value); + assertEquals(true, GetDescriptor().configurable); + assertEquals(0, counters.get_count); + assertEquals(0, counters.set_count); + + assertEquals(undefined, LoadVar()); + assertEquals(1, counters.get_count); + assertEquals(0, counters.set_count); + + LoadStoreLoop(); + assertEquals(28, counters.get_count); + assertEquals(14, counters.set_count); + + assertEquals(13, LoadVar()); + assertEquals(29, counters.get_count); + assertEquals(14, counters.set_count); + + TearDown(); + })(); + + + (function() { + SetUp(); + cfg = {optimize: opt_cfg.optimize, strict: false}; + ForceMutablePropertyCellType(); + DefineLoadVar(); + DefineStoreVar(); + DefineRWAccessorProperty(); + assertEquals(0, counters.get_count); + assertEquals(0, counters.set_count); + assertEquals(true, GetDescriptor().configurable); + + assertEquals(undefined, LoadVar()); + assertEquals(1, counters.get_count); + assertEquals(0, counters.set_count); + + DefineVar(153); + assertEquals(true, GetDescriptor().configurable); + assertEquals(1, counters.get_count); + assertEquals(1, counters.set_count); + + assertEquals(153, LoadVar()); + assertEquals(2, counters.get_count); + assertEquals(1, counters.set_count); + + assertEquals(113, StoreVar(113)); + assertEquals(2, counters.get_count); + assertEquals(2, counters.set_count); + + assertEquals(113, LoadVar()); + assertEquals(3, counters.get_count); + assertEquals(2, counters.set_count); + + LoadStoreLoop(); + assertEquals(30, counters.get_count); + assertEquals(16, counters.set_count); + + assertEquals(13, LoadVar()); + assertEquals(31, counters.get_count); + assertEquals(16, counters.set_count); + + // Now reconfigure to data property. + DefineRWDataProperty(); + assertEquals(42, GetDescriptor().value); + assertEquals(42, LoadVar()); + assertEquals(113, StoreVar(113)); + assertEquals(31, counters.get_count); + assertEquals(16, counters.set_count); + + TearDown(); + })(); + + + (function() { + SetUp(); + cfg = {optimize: opt_cfg.optimize, strict: false}; + ForceMutablePropertyCellType(); + DefineLoadVar(); + DefineStoreVar(); + DefineROAccessorProperty(); + assertEquals(0, counters.get_count); + assertEquals(0, counters.set_count); + assertEquals(true, GetDescriptor().configurable); + + assertEquals(undefined, LoadVar()); + assertEquals(1, counters.get_count); + assertEquals(0, counters.set_count); + + SetX_(42); + assertEquals(42, LoadVar()); + assertEquals(2, counters.get_count); + assertEquals(0, counters.set_count); + + DefineVar(153); + assertEquals(true, GetDescriptor().configurable); + assertEquals(2, counters.get_count); + assertEquals(0, counters.set_count); + + assertEquals(42, LoadVar()); + assertEquals(3, counters.get_count); + assertEquals(0, counters.set_count); + + assertEquals(113, StoreVar(113)); + assertEquals(3, counters.get_count); + assertEquals(0, counters.set_count); + + assertEquals(42, LoadVar()); + assertEquals(4, counters.get_count); + assertEquals(0, counters.set_count); + + LoadStoreLoop(); + assertEquals(5, counters.get_count); + assertEquals(0, counters.set_count); + + assertEquals(42, LoadVar()); + assertEquals(6, counters.get_count); + assertEquals(0, counters.set_count); + + // Now reconfigure to data property. + DefineRWDataProperty(); + assertEquals(42, GetDescriptor().value); + assertEquals(42, LoadVar()); + assertEquals(113, StoreVar(113)); + assertEquals(6, counters.get_count); + assertEquals(0, counters.set_count); + + TearDown(); + })(); + + + // + // Strict. + // + + (function() { + SetUp(); + cfg = {optimize: opt_cfg.optimize, strict: true}; + DeclareVar(); + DefineLoadVar(); + DefineStoreVar(); + assertEquals(undefined, LoadVar()); + assertEquals(false, GetDescriptor().configurable); + + // Force property cell type to kMutable. + DefineVar(undefined); + DefineVar(153); + assertEquals(false, GetDescriptor().configurable); + + assertEquals(153, LoadVar()); + assertEquals(113, StoreVar(113)); + assertEquals(113, LoadVar()); + LoadStoreLoop(); + assertEquals(13, LoadVar()); + TearDown(); + })(); + + + (function() { + SetUp(); + cfg = {optimize: opt_cfg.optimize, strict: true}; + ForceMutablePropertyCellType(); + DefineLoadVar(); + DefineStoreVar(); + DefineRWDataProperty(); + assertEquals(42, LoadVar()); + assertEquals(true, GetDescriptor().configurable); + + DefineVar(153); + assertEquals(true, GetDescriptor().configurable); + + assertEquals(153, LoadVar()); + assertEquals(113, StoreVar(113)); + assertEquals(113, LoadVar()); + LoadStoreLoop(); + assertEquals(13, LoadVar()); + TearDown(); + })(); + + + (function() { + SetUp(); + cfg = {optimize: opt_cfg.optimize, strict: true}; + ForceMutablePropertyCellType(); + DefineLoadVar(); + DefineStoreVar(); + DefineRWDataProperty(); + assertEquals(true, GetDescriptor().configurable); + assertEquals(true, GetDescriptor().writable); + assertEquals(113, StoreVar(113)); + + DefineRODataProperty(); + assertEquals(true, GetDescriptor().configurable); + assertEquals(false, GetDescriptor().writable); + + assertEquals(42, LoadVar()); + assertEquals(true, GetDescriptor().configurable); + assertThrows('DefineVar(153)'); + assertEquals(42, LoadVar()); + assertThrows('StoreVar(113)'); + assertThrows('StoreVar(113)'); + assertEquals(42, LoadVar()); + assertThrows('StoreVar(42)'); + assertEquals(42, LoadVar()); + assertThrows('LoadStoreLoop()'); + assertEquals(42, LoadVar()); + TearDown(); + })(); + + + (function() { + SetUp(); + cfg = {optimize: opt_cfg.optimize, strict: true}; + ForceMutablePropertyCellType(); + DefineLoadVar(); + DefineStoreVar(); + DefineRWAccessorProperty(); + assertEquals(0, counters.get_count); + assertEquals(0, counters.set_count); + assertEquals(true, GetDescriptor().configurable); + + assertEquals(undefined, LoadVar()); + assertEquals(1, counters.get_count); + assertEquals(0, counters.set_count); + + DefineVar(153); + assertEquals(true, GetDescriptor().configurable); + assertEquals(1, counters.get_count); + assertEquals(1, counters.set_count); + + assertEquals(153, LoadVar()); + assertEquals(2, counters.get_count); + assertEquals(1, counters.set_count); + + assertEquals(113, StoreVar(113)); + assertEquals(2, counters.get_count); + assertEquals(2, counters.set_count); + + assertEquals(113, LoadVar()); + assertEquals(3, counters.get_count); + assertEquals(2, counters.set_count); + + LoadStoreLoop(); + assertEquals(30, counters.get_count); + assertEquals(16, counters.set_count); + + assertEquals(13, LoadVar()); + assertEquals(31, counters.get_count); + assertEquals(16, counters.set_count); + + // Now reconfigure to data property. + DefineRWDataProperty(); + assertEquals(42, GetDescriptor().value); + assertEquals(42, LoadVar()); + assertEquals(113, StoreVar(113)); + assertEquals(31, counters.get_count); + assertEquals(16, counters.set_count); + + TearDown(); + })(); + + + (function() { + SetUp(); + cfg = {optimize: opt_cfg.optimize, strict: true}; + ForceMutablePropertyCellType(); + DefineLoadVar(); + DefineStoreVar(); + DefineROAccessorProperty(); + assertEquals(0, counters.get_count); + assertEquals(0, counters.set_count); + assertEquals(true, GetDescriptor().configurable); + + assertEquals(undefined, LoadVar()); + assertEquals(1, counters.get_count); + assertEquals(0, counters.set_count); + + SetX_(42); + assertEquals(42, LoadVar()); + assertEquals(2, counters.get_count); + assertEquals(0, counters.set_count); + + assertThrows('DefineVar(153)'); + assertEquals(true, GetDescriptor().configurable); + assertEquals(2, counters.get_count); + assertEquals(0, counters.set_count); + + assertEquals(42, LoadVar()); + assertEquals(3, counters.get_count); + assertEquals(0, counters.set_count); + + assertThrows('StoreVar(113)'); + assertEquals(3, counters.get_count); + assertEquals(0, counters.set_count); + + assertEquals(42, LoadVar()); + assertEquals(4, counters.get_count); + assertEquals(0, counters.set_count); + + assertThrows('LoadStoreLoop()'); + assertEquals(4, counters.get_count); + assertEquals(0, counters.set_count); + + assertEquals(42, LoadVar()); + assertEquals(5, counters.get_count); + assertEquals(0, counters.set_count); + + // Now reconfigure to data property. + DefineRWDataProperty(); + assertEquals(42, GetDescriptor().value); + assertEquals(42, LoadVar()); + assertEquals(113, StoreVar(113)); + assertEquals(5, counters.get_count); + assertEquals(0, counters.set_count); + + TearDown(); + })(); + +} // testSuite + + +testSuite({optimize: false}); +testSuite({optimize: true}); diff --git a/deps/v8/test/mjsunit/regress/regress-119429.js b/deps/v8/test/mjsunit/regress/regress-119429.js index a87648754a..859702ac7e 100644 --- a/deps/v8/test/mjsunit/regress/regress-119429.js +++ b/deps/v8/test/mjsunit/regress/regress-119429.js @@ -30,7 +30,7 @@ var d = 0; function recurse() { if (++d == 25135) { // A magic number just below stack overflow on ia32 - %DebugBreak(); + %HandleDebuggerStatement(); } recurse(); } diff --git a/deps/v8/test/mjsunit/regress/regress-3315.js b/deps/v8/test/mjsunit/regress/regress-3315.js index a1105e2848..bfd7df29b8 100644 --- a/deps/v8/test/mjsunit/regress/regress-3315.js +++ b/deps/v8/test/mjsunit/regress/regress-3315.js @@ -1,6 +1,8 @@ // Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// +// Flags: --harmony-object-observe var indexZeroCallCount = 0; var indexOneCallCount = 0; diff --git a/deps/v8/test/mjsunit/regress/regress-356589.js b/deps/v8/test/mjsunit/regress/regress-356589.js index f93c545640..a47f51bac1 100644 --- a/deps/v8/test/mjsunit/regress/regress-356589.js +++ b/deps/v8/test/mjsunit/regress/regress-356589.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: --harmony-object-observe + // This test passes if it does not crash in debug mode arr = ['a', 'b', 'c', 'd']; diff --git a/deps/v8/test/mjsunit/regress/regress-417709a.js b/deps/v8/test/mjsunit/regress/regress-417709a.js index d210c10429..5500be2cf0 100644 --- a/deps/v8/test/mjsunit/regress/regress-417709a.js +++ b/deps/v8/test/mjsunit/regress/regress-417709a.js @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Flags: --harmony-object-observe // Flags: --stack-size=100 var a = []; diff --git a/deps/v8/test/mjsunit/regress/regress-4271.js b/deps/v8/test/mjsunit/regress/regress-4271.js new file mode 100644 index 0000000000..bc18771e72 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-4271.js @@ -0,0 +1,24 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +if (this.Worker) { + // Throw rather than overflow internal field index + assertThrows(function() { + Worker.prototype.terminate(); + }); + + assertThrows(function() { + Worker.prototype.getMessage(); + }); + + assertThrows(function() { + Worker.prototype.postMessage({}); + }); + + // Don't throw for real worker + var worker = new Worker(''); + worker.getMessage(); + worker.postMessage({}); + worker.terminate(); +} diff --git a/deps/v8/test/mjsunit/regress/regress-4279.js b/deps/v8/test/mjsunit/regress/regress-4279.js new file mode 100644 index 0000000000..64ef967d89 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-4279.js @@ -0,0 +1,11 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +if (this.Worker && this.quit) { + try { + new Function(new Worker("55")); + } catch(err) {} + + quit(); +} diff --git a/deps/v8/test/mjsunit/regress/regress-4296.js b/deps/v8/test/mjsunit/regress/regress-4296.js new file mode 100644 index 0000000000..5774952a94 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-4296.js @@ -0,0 +1,40 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(function () { + var o = new String("ab"); + function store(o, i, v) { o[i] = v; } + function load(o, i) { return o[i]; } + + // Initialize the IC. + store(o, 2, 10); + load(o, 2); + + store(o, 0, 100); + assertEquals("a", load(o, 0)); +})(); + +(function () { + var o = {__proto__: new String("ab")}; + function store(o, i, v) { o[i] = v; } + function load(o, i) { return o[i]; } + + // Initialize the IC. + store(o, 2, 10); + load(o, 2); + + store(o, 0, 100); + assertEquals("a", load(o, 0)); +})(); + +(function () { + "use strict"; + var o = {__proto__: {}}; + function store(o, i, v) { o[i] = v; } + + // Initialize the IC. + store(o, 0, 100); + o.__proto__.__proto__ = new String("bla"); + assertThrows(function () { store(o, 1, 100) }); +})(); diff --git a/deps/v8/test/mjsunit/regress/regress-4309-1.js b/deps/v8/test/mjsunit/regress/regress-4309-1.js new file mode 100644 index 0000000000..a13fd43a4a --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-4309-1.js @@ -0,0 +1,37 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug --allow-natives-syntax + +var Debug = debug.Debug; + +var exception = null; + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var scopes = exec_state.frame().allScopes(); + assertEquals(3, scopes.length); + assertEquals(debug.ScopeType.Local, scopes[0].scopeType()); + assertEquals(debug.ScopeType.Script, scopes[1].scopeType()); + assertEquals(debug.ScopeType.Global, scopes[2].scopeType()); + } catch (e) { + exception = e; + } +} + +function f() { + eval(''); + debugger; +} + +f(); +f(); + +%OptimizeFunctionOnNextCall(f); +Debug.setListener(listener); + +f(); + +assertNull(exception); diff --git a/deps/v8/test/mjsunit/regress/regress-4309-2.js b/deps/v8/test/mjsunit/regress/regress-4309-2.js new file mode 100644 index 0000000000..984b0071c1 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-4309-2.js @@ -0,0 +1,34 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug --allow-natives-syntax + +var Debug = debug.Debug; + +var exception = null; + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var scope = exec_state.frame().scope(0); + assertEquals(5, scope.scopeObject().property("i").value().value()); + } catch (e) { + exception = e; + } +} + +function f() { + eval('var i = 5'); + debugger; +} + +f(); +f(); + +%OptimizeFunctionOnNextCall(f); +Debug.setListener(listener); + +f(); + +assertNull(exception); diff --git a/deps/v8/test/mjsunit/regress/regress-4309-3.js b/deps/v8/test/mjsunit/regress/regress-4309-3.js new file mode 100644 index 0000000000..687dd4c44a --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-4309-3.js @@ -0,0 +1,39 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug --allow-natives-syntax + +var Debug = debug.Debug; + +var exception = null; + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + try { + var scopes = exec_state.frame().allScopes(); + assertEquals(4, scopes.length); + assertEquals(debug.ScopeType.With, scopes[0].scopeType()); + assertEquals(debug.ScopeType.Local, scopes[1].scopeType()); + assertEquals(debug.ScopeType.Script, scopes[2].scopeType()); + assertEquals(debug.ScopeType.Global, scopes[3].scopeType()); + } catch (e) { + exception = e; + } +} + +function f() { + with({}) { + debugger; + } +} + +f(); +f(); + +%OptimizeFunctionOnNextCall(f); +Debug.setListener(listener); + +f(); + +assertNull(exception); diff --git a/deps/v8/test/mjsunit/regress/regress-4320.js b/deps/v8/test/mjsunit/regress/regress-4320.js new file mode 100644 index 0000000000..df6a99b28f --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-4320.js @@ -0,0 +1,21 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --expose-debug-as debug + +var Debug = debug.Debug; + +function f() { g(); } + +function g() { } + +f(); +f(); +%OptimizeFunctionOnNextCall(f); +f(); + +Debug.setListener(function() {}); +Debug.setBreakPoint(g, 0); + +f(); diff --git a/deps/v8/test/mjsunit/regress/regress-4325.js b/deps/v8/test/mjsunit/regress/regress-4325.js new file mode 100644 index 0000000000..e88bdd3b08 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-4325.js @@ -0,0 +1,48 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --expose-gc + +function Inner() { + this.p1 = 0; + this.p2 = 3; +} + +function Outer() { + this.p3 = 0; +} + +var i1 = new Inner(); +var i2 = new Inner(); +var o1 = new Outer(); +o1.inner = i1; +// o1.map now thinks "inner" has type Inner.map1. +// Deprecate Inner.map1: +i1.p1 = 0.5; +// Let Inner.map1 die by migrating i2 to Inner.map2: +print(i2.p1); +gc(); +// o1.map's descriptor for "inner" is now a cleared WeakCell; +// o1.inner's actual map is Inner.map2. +// Prepare Inner.map3, deprecating Inner.map2. +i2.p2 = 0.5; +// Deprecate o1's map. +var o2 = new Outer(); +o2.p3 = 0.5; +o2.inner = i2; +// o2.map (Outer.map2) now says that o2.inner's type is Inner.map3. +// Migrate o1 to Outer.map2. +print(o1.p3); +// o1.map now thinks that o1.inner has map Inner.map3 just like o2.inner, +// but in fact o1.inner.map is still Inner.map2! + +function loader(o) { + return o.inner.p2; +} +loader(o2); +loader(o2); +%OptimizeFunctionOnNextCall(loader); +assertEquals(0.5, loader(o2)); +assertEquals(3, loader(o1)); +gc(); // Crashes with --verify-heap. diff --git a/deps/v8/test/mjsunit/regress/regress-455207.js b/deps/v8/test/mjsunit/regress/regress-455207.js new file mode 100644 index 0000000000..88fec4a3b9 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-455207.js @@ -0,0 +1,12 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +"use strict"; +var s = ""; +for (var i = 16; i < 1085; i++) { + s += ("var a" + i + " = " + i + ";"); +} +s += "const x = 10;" + + "assertEquals(10, x); x = 11; assertEquals(11, x)"; +assertThrows(function() { eval(s); }); diff --git a/deps/v8/test/mjsunit/regress/regress-509961.js b/deps/v8/test/mjsunit/regress/regress-509961.js new file mode 100644 index 0000000000..d28bc8a268 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-509961.js @@ -0,0 +1,10 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var o = { x: 0 }; +delete o.x; +function store(o, p, v) { o[p] = v; } +store(o, "x", 1); +store(o, "x", 1); +store(o, "0", 1); diff --git a/deps/v8/test/mjsunit/regress/regress-514362.js b/deps/v8/test/mjsunit/regress/regress-514362.js new file mode 100644 index 0000000000..f69cfecebe --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-514362.js @@ -0,0 +1,21 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --expose-debug-as debug + +function bar(x) { debugger; } +function foo() { bar(arguments[0]); } +function wrap() { return foo(1); } + +wrap(); +wrap(); +%OptimizeFunctionOnNextCall(wrap); + +var Debug = debug.Debug; +Debug.setListener(function(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Break) return; + for (var i = 0; i < exec_state.frameCount(); i++) exec_state.frame(i); +}); + +wrap(); diff --git a/deps/v8/test/mjsunit/regress/regress-581.js b/deps/v8/test/mjsunit/regress/regress-581.js index ab345a9b61..1b40f580e2 100644 --- a/deps/v8/test/mjsunit/regress/regress-581.js +++ b/deps/v8/test/mjsunit/regress/regress-581.js @@ -36,7 +36,6 @@ assertThrows(function() { a.concat(a); }, RangeError); var b = []; b[pow31 - 3] = 32; -b[pow31 - 2] = "out_of_bounds"; var ab = a.concat(b); assertEquals(2 * pow31 - 1, ab.length); assertEquals(31, ab[pow31]); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-490021.js b/deps/v8/test/mjsunit/regress/regress-crbug-490021.js new file mode 100644 index 0000000000..745c0a8010 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-490021.js @@ -0,0 +1,15 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +var global = new Object(3); +function f() { + global[0] = global[0] >>> 15.5; +} + +f(); +f(); +%OptimizeFunctionOnNextCall(f); +f(); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-501711.js b/deps/v8/test/mjsunit/regress/regress-crbug-501711.js index f8eda6e8d8..b253e9c912 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-501711.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-501711.js @@ -8,7 +8,11 @@ function f() { try { f(); } catch(e) { - Realm.create(); + try { + Realm.create(); + } catch (e) { + quit(); + } } } f(); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-501809.js b/deps/v8/test/mjsunit/regress/regress-crbug-501809.js index b348e5d5f6..c3abadfab5 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-501809.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-501809.js @@ -6,4 +6,4 @@ var sab = new SharedArrayBuffer(8); var ta = new Int32Array(sab); ta.__defineSetter__('length', function() {;}); -assertThrows(function() { Atomics.compareExchange(ta, 4294967295, 0, 0); }); +Atomics.compareExchange(ta, 4294967295, 0, 0); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-505007-1.js b/deps/v8/test/mjsunit/regress/regress-crbug-505007-1.js index 6012577aaa..910f4a6720 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-505007-1.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-505007-1.js @@ -4,11 +4,15 @@ // Flags: --stack-size=100 --allow-natives-syntax +var count = 0; function f() { try { f(); } catch(e) { - %GetDebugContext(); + if (count < 100) { + count++; + %GetDebugContext(); + } } } f(); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-505007-2.js b/deps/v8/test/mjsunit/regress/regress-crbug-505007-2.js index dfa34ae6ad..96014c848d 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-505007-2.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-505007-2.js @@ -5,11 +5,16 @@ // Flags: --stack-size=100 --allow-natives-syntax function g() {} + +var count = 0; function f() { try { f(); } catch(e) { - %ExecuteInDebugContext(g); + if (count < 100) { + count++; + %ExecuteInDebugContext(g); + } } } f(); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-505907.js b/deps/v8/test/mjsunit/regress/regress-crbug-505907.js new file mode 100644 index 0000000000..761261eca0 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-505907.js @@ -0,0 +1,12 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-proxies + +try { + var p = Proxy.create({ getPropertyDescriptor: function() { return [] } }); + var o = Object.create(p); + with (o) { unresolved_name() } +} catch(e) { +} diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-506549.js b/deps/v8/test/mjsunit/regress/regress-crbug-506549.js new file mode 100644 index 0000000000..40e162caf5 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-506549.js @@ -0,0 +1,10 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +if (this.Worker) { + var __v_5 = {}; + __v_5.__defineGetter__('byteLength', function() {foo();}); + var __v_8 = new Worker('onmessage = function() {};'); + assertThrows(function() { __v_8.postMessage(__v_5); }); +} diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-506956.js b/deps/v8/test/mjsunit/regress/regress-crbug-506956.js new file mode 100644 index 0000000000..5862ddb296 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-506956.js @@ -0,0 +1,12 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --harmony-proxies + +try { + var p = Proxy.create({ getPropertyDescriptor: function() { throw "boom"; } }); + var o = Object.create(p); + with (o) { delete unresolved_name; } +} catch(e) { +} diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-507070.js b/deps/v8/test/mjsunit/regress/regress-crbug-507070.js new file mode 100644 index 0000000000..0cb14b27e7 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-507070.js @@ -0,0 +1,20 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --cache=code --no-debug-code + +try { } catch(e) { } +try { try { } catch (e) { } } catch(e) { } +try { + var Debug = %GetDebugContext().Debug; + Debug.setListener(function(){}); +} catch(e) { } +(function() { + Debug.setBreakPoint(function(){}, 0, 0); +})(); + +var a = 1; +a += a; +Debug.setListener(null); +assertEquals(2, a); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-510426.js b/deps/v8/test/mjsunit/regress/regress-crbug-510426.js new file mode 100644 index 0000000000..c82dbacfa9 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-510426.js @@ -0,0 +1,7 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var s = new String('a'); +s[10000000] = 'bente'; +assertEquals(['0', '10000000'], Object.keys(s)); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-510738.js b/deps/v8/test/mjsunit/regress/regress-crbug-510738.js new file mode 100644 index 0000000000..0e154a9a94 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-510738.js @@ -0,0 +1,17 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax + +function check(f, result) { + %OptimizeFunctionOnNextCall(f); + assertEquals(result, f()); +} + +var x = 17; +function generic_load() { return x; } +check(generic_load, 17); + +function generic_store() { x = 13; return x; } +check(generic_store, 13); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-511880.js b/deps/v8/test/mjsunit/regress/regress-crbug-511880.js new file mode 100644 index 0000000000..f9b05ff7bc --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-511880.js @@ -0,0 +1,13 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +if (this.Worker) { + var __v_8 = + `var __v_9 = new Worker('postMessage(42)'); + onmessage = function(parentMsg) { + __v_9.postMessage(parentMsg); + };`; + var __v_9 = new Worker(__v_8); + __v_9.postMessage(9); +} diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-513472.js b/deps/v8/test/mjsunit/regress/regress-crbug-513472.js new file mode 100644 index 0000000000..456fe0a11d --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-513472.js @@ -0,0 +1,7 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +"use strict"; +this.__proto__ = Error(); +assertThrows(function() { NaN = 1; }); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-513507.js b/deps/v8/test/mjsunit/regress/regress-crbug-513507.js new file mode 100644 index 0000000000..dbf35c91fe --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-513507.js @@ -0,0 +1,24 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --noflush-optimized-code-cache --allow-natives-syntax + +// The following triggers a GC in SharedFunctionInfo::AddToOptimizedCodeMap. +// Flags: --gc-interval=1234 --gc-global + +function makeFun() { + function fun(osr_fuse) { + for (var i = 0; i < 3; ++i) { + if (i == osr_fuse) %OptimizeOsr(); + } + for (var i = 3; i < 6; ++i) { + if (i == osr_fuse) %OptimizeOsr(); + } + } + return fun; +} + +makeFun()(7); // Warm up. +makeFun()(4); // Optimize once. +makeFun()(1); // Optimize again. diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-514081.js b/deps/v8/test/mjsunit/regress/regress-crbug-514081.js new file mode 100644 index 0000000000..1acd8315cd --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-514081.js @@ -0,0 +1,15 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +if (this.Worker) { + var __v_7 = new Worker('onmessage = function() {};'); + try { + var ab = new ArrayBuffer(2147483648); + // If creating the ArrayBuffer succeeded, then postMessage should fail. + assertThrows(function() { __v_7.postMessage(ab); }); + } catch (e) { + // Creating the ArrayBuffer failed. + assertInstanceof(e, RangeError); + } +} diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-516592.js b/deps/v8/test/mjsunit/regress/regress-crbug-516592.js new file mode 100644 index 0000000000..1887824a6c --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-516592.js @@ -0,0 +1,18 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var i = Math.pow(2, 31); +var a = []; +a[i] = 31; +var b = []; +b[i - 2] = 33; +try { + // This is supposed to throw a RangeError. + var c = a.concat(b); + // If it didn't, ObservableSetLength will detect the problem. + Object.observe(c, function() {}); + c.length = 1; +} catch(e) { + assertTrue(e instanceof RangeError); +} diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-516775.js b/deps/v8/test/mjsunit/regress/regress-crbug-516775.js new file mode 100644 index 0000000000..25d4d0103d --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-516775.js @@ -0,0 +1,53 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --harmony-concat-spreadable + +function arguments_with_length_getter(f) { + arguments.__defineGetter__('length', f); + return arguments; +} + +var count = 0; +function increment_count_return() { count++; return "boom"; } +function increment_count_throw() { count++; throw "boom"; } + +// Do not read the length of an arguments object on the prototype chain of +// an array. +var a1 = []; +%NormalizeElements(a1); +a1.__proto__ = arguments_with_length_getter(increment_count_return); +[].concat(a1); +assertEquals(0, count); + +var a2 = []; +%NormalizeElements(a2); +a2.__proto__ = arguments_with_length_getter(increment_count_throw); +[].concat(a2); +assertEquals(0, count); + +// Do read the length of an arguments object if spreadable. +var a3 = arguments_with_length_getter(increment_count_return); +a3[Symbol.isConcatSpreadable] = true; +[].concat(a3); +assertEquals(1, count); + +var a4 = arguments_with_length_getter(increment_count_throw); +a4[Symbol.isConcatSpreadable] = true; +assertThrows(function() { [].concat(a4); }); +assertEquals(2, count); + +// Do read the length of an arguments object on the prototype chain of +// an object. +var a5 = {}; +a5.__proto__ = arguments_with_length_getter(increment_count_return); +a5[Symbol.isConcatSpreadable] = true; +[].concat(a5); +assertEquals(3, count); + +var a6 = {}; +a6.__proto__ = arguments_with_length_getter(increment_count_throw); +a6[Symbol.isConcatSpreadable] = true; +assertThrows(function() { [].concat(a6); }); +assertEquals(4, count); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-517592.js b/deps/v8/test/mjsunit/regress/regress-crbug-517592.js new file mode 100644 index 0000000000..760d892439 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-517592.js @@ -0,0 +1,36 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug --min-preparse-length=10 + +var source = + "var foo = function foo() {\n" + + " return 1;\n" + + "}\n" + + "//@ sourceURL=test"; + +Debug = debug.Debug; +Debug.setListener(listener); +var exception = null; +var break_count = 0; + +function listener(event, exec_state, event_data, data) { + if (event == Debug.DebugEvent.Break) break_count++; + if (event != Debug.DebugEvent.AfterCompile) return; + try { + var name = event_data.script().name(); + var id = event_data.script().id(); + assertEquals("test", name); + Debug.setScriptBreakPointById(id, 2); + } catch (e) { + exception = e; + } +} + +eval(source); + +assertEquals(0, break_count); +foo(); +assertEquals(1, break_count); +assertNull(exception); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-518747.js b/deps/v8/test/mjsunit/regress/regress-crbug-518747.js new file mode 100644 index 0000000000..f1787c4c4b --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-518747.js @@ -0,0 +1,9 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +if (this.Worker) { + Worker.prototype = 12; + var __v_6 = new Worker(''); + __v_6.postMessage([]); +} diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-518748.js b/deps/v8/test/mjsunit/regress/regress-crbug-518748.js new file mode 100644 index 0000000000..cccbc26c24 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-518748.js @@ -0,0 +1,14 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +if (this.Worker) { + var workersToCreate = 1000; + var workers = []; + assertThrows(function() { + for (var i = 0; i < workersToCreate; i++) { + workers.push(new Worker('')); + } + }); + print('#workers: ', workers.length); +} diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-522380.js b/deps/v8/test/mjsunit/regress/regress-crbug-522380.js new file mode 100644 index 0000000000..eba07f783f --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-522380.js @@ -0,0 +1,7 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var global = this; +global.__defineSetter__('x', function(v) { x = v; }); +assertThrows("global.x = 0", RangeError); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-522496.js b/deps/v8/test/mjsunit/regress/regress-crbug-522496.js new file mode 100644 index 0000000000..e47e0a0677 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-522496.js @@ -0,0 +1,9 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +if (this.Worker) { + var worker = new Worker("onmessage = function(){}"); + var buf = new ArrayBuffer(); + worker.postMessage(buf, [buf]); +} diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-523308.js b/deps/v8/test/mjsunit/regress/regress-crbug-523308.js new file mode 100644 index 0000000000..5715762ed6 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-523308.js @@ -0,0 +1,10 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var error; +try { reference_error(); } catch (e) { error = e; } +toString = error.toString; +error.__proto__ = []; +assertEquals("ReferenceError: reference_error is not defined", + toString.call(error)); diff --git a/deps/v8/test/mjsunit/regress/regress-debugger-redirect.js b/deps/v8/test/mjsunit/regress/regress-debugger-redirect.js new file mode 100644 index 0000000000..07c7fad7e6 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-debugger-redirect.js @@ -0,0 +1,37 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug + +function f(x) { + // This function compiles into code that only throws a redeclaration + // error. It contains no stack check and has no function body. + const x = 0; + return x; +} + +function g() { + f(0); +} + +var exception = null; +var called = false; +var Debug = debug.Debug; +Debug.setBreakOnException(); + +function listener(event, exec_state, event_data, data) { + if (event != Debug.DebugEvent.Exception) return; + try { + called = true; + Debug.setBreakPoint(f, 1); + } catch (e) { + exception = e; + } +} + +Debug.setListener(listener); + +assertThrows(g); +assertNull(exception); +assertTrue(called); diff --git a/deps/v8/test/mjsunit/regress/regress-observe-map-cache.js b/deps/v8/test/mjsunit/regress/regress-observe-map-cache.js index 4c7a7e3e97..c71759c0cc 100644 --- a/deps/v8/test/mjsunit/regress/regress-observe-map-cache.js +++ b/deps/v8/test/mjsunit/regress/regress-observe-map-cache.js @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// Flags: --harmony-object-observe // Flags: --allow-natives-syntax --enable-slow-asserts function f() { diff --git a/deps/v8/test/mjsunit/regress/regress-typedarray-length.js b/deps/v8/test/mjsunit/regress/regress-typedarray-length.js index ee85364735..cae55731f9 100644 --- a/deps/v8/test/mjsunit/regress/regress-typedarray-length.js +++ b/deps/v8/test/mjsunit/regress/regress-typedarray-length.js @@ -71,43 +71,6 @@ assertEquals(undefined, get(a)); assertEquals(undefined, get(a)); })(); -(function() { - "use strict"; - - class MyTypedArray extends Int32Array { - constructor(length) { - super(length); - } - } - - a = new MyTypedArray(1024); - - get = function(a) { - return a.length; - } - - assertEquals(1024, get(a)); - assertEquals(1024, get(a)); - assertEquals(1024, get(a)); - %OptimizeFunctionOnNextCall(get); - assertEquals(1024, get(a)); -})(); - -(function() { - "use strict"; - var a = new Uint8Array(4); - Object.defineProperty(a, "length", {get: function() { return "blah"; }}); - get = function(a) { - return a.length; - } - - assertEquals("blah", get(a)); - assertEquals("blah", get(a)); - assertEquals("blah", get(a)); - %OptimizeFunctionOnNextCall(get); - assertEquals("blah", get(a)); -})(); - // Ensure we cannot delete length, byteOffset, byteLength. assertTrue(Int32Array.prototype.hasOwnProperty("length")); assertTrue(Int32Array.prototype.hasOwnProperty("byteOffset")); diff --git a/deps/v8/test/mjsunit/regress/string-compare-memcmp.js b/deps/v8/test/mjsunit/regress/string-compare-memcmp.js index ae4b33ace9..45f47343ee 100644 --- a/deps/v8/test/mjsunit/regress/string-compare-memcmp.js +++ b/deps/v8/test/mjsunit/regress/string-compare-memcmp.js @@ -4,4 +4,4 @@ // Flags: --allow-natives-syntax -assertEquals(-1, %StringCompareRT("abc\u0102", "abc\u0201")); +assertEquals(-1, %StringCompare("abc\u0102", "abc\u0201")); diff --git a/deps/v8/test/mjsunit/samevalue.js b/deps/v8/test/mjsunit/samevalue.js index 229db0db4c..174afd2372 100644 --- a/deps/v8/test/mjsunit/samevalue.js +++ b/deps/v8/test/mjsunit/samevalue.js @@ -27,78 +27,94 @@ // Flags: --expose-natives-as natives -// Test the SameValue internal method. +// Test the SameValue and SameValueZero internal methods. var obj1 = {x: 10, y: 11, z: "test"}; var obj2 = {x: 10, y: 11, z: "test"}; var sameValue = natives.$sameValue; +var sameValueZero = natives.$sameValueZero; -assertTrue(sameValue(0, 0)); -assertTrue(sameValue(+0, +0)); -assertTrue(sameValue(-0, -0)); -assertTrue(sameValue(1, 1)); -assertTrue(sameValue(2, 2)); -assertTrue(sameValue(-1, -1)); -assertTrue(sameValue(0.5, 0.5)); -assertTrue(sameValue(true, true)); -assertTrue(sameValue(false, false)); -assertTrue(sameValue(NaN, NaN)); -assertTrue(sameValue(null, null)); -assertTrue(sameValue("foo", "foo")); -assertTrue(sameValue(obj1, obj1)); +// Calls SameValue and SameValueZero and checks that their results match. +function sameValueBoth(a, b) { + var result = sameValue(a, b); + assertTrue(result === sameValueZero(a, b)); + return result; +} + +// Calls SameValue and SameValueZero and checks that their results don't match. +function sameValueZeroOnly(a, b) { + var result = sameValueZero(a, b); + assertTrue(result && !sameValue(a, b)); + return result; +} + +assertTrue(sameValueBoth(0, 0)); +assertTrue(sameValueBoth(+0, +0)); +assertTrue(sameValueBoth(-0, -0)); +assertTrue(sameValueBoth(1, 1)); +assertTrue(sameValueBoth(2, 2)); +assertTrue(sameValueBoth(-1, -1)); +assertTrue(sameValueBoth(0.5, 0.5)); +assertTrue(sameValueBoth(true, true)); +assertTrue(sameValueBoth(false, false)); +assertTrue(sameValueBoth(NaN, NaN)); +assertTrue(sameValueBoth(null, null)); +assertTrue(sameValueBoth("foo", "foo")); +assertTrue(sameValueBoth(obj1, obj1)); // Undefined values. -assertTrue(sameValue()); -assertTrue(sameValue(undefined, undefined)); - -assertFalse(sameValue(0,1)); -assertFalse(sameValue("foo", "bar")); -assertFalse(sameValue(obj1, obj2)); -assertFalse(sameValue(true, false)); - -assertFalse(sameValue(obj1, true)); -assertFalse(sameValue(obj1, "foo")); -assertFalse(sameValue(obj1, 1)); -assertFalse(sameValue(obj1, undefined)); -assertFalse(sameValue(obj1, NaN)); - -assertFalse(sameValue(undefined, true)); -assertFalse(sameValue(undefined, "foo")); -assertFalse(sameValue(undefined, 1)); -assertFalse(sameValue(undefined, obj1)); -assertFalse(sameValue(undefined, NaN)); - -assertFalse(sameValue(NaN, true)); -assertFalse(sameValue(NaN, "foo")); -assertFalse(sameValue(NaN, 1)); -assertFalse(sameValue(NaN, obj1)); -assertFalse(sameValue(NaN, undefined)); - -assertFalse(sameValue("foo", true)); -assertFalse(sameValue("foo", 1)); -assertFalse(sameValue("foo", obj1)); -assertFalse(sameValue("foo", undefined)); -assertFalse(sameValue("foo", NaN)); - -assertFalse(sameValue(true, 1)); -assertFalse(sameValue(true, obj1)); -assertFalse(sameValue(true, undefined)); -assertFalse(sameValue(true, NaN)); -assertFalse(sameValue(true, "foo")); - -assertFalse(sameValue(1, true)); -assertFalse(sameValue(1, obj1)); -assertFalse(sameValue(1, undefined)); -assertFalse(sameValue(1, NaN)); -assertFalse(sameValue(1, "foo")); +assertTrue(sameValueBoth()); +assertTrue(sameValueBoth(undefined, undefined)); + +assertFalse(sameValueBoth(0,1)); +assertFalse(sameValueBoth("foo", "bar")); +assertFalse(sameValueBoth(obj1, obj2)); +assertFalse(sameValueBoth(true, false)); + +assertFalse(sameValueBoth(obj1, true)); +assertFalse(sameValueBoth(obj1, "foo")); +assertFalse(sameValueBoth(obj1, 1)); +assertFalse(sameValueBoth(obj1, undefined)); +assertFalse(sameValueBoth(obj1, NaN)); + +assertFalse(sameValueBoth(undefined, true)); +assertFalse(sameValueBoth(undefined, "foo")); +assertFalse(sameValueBoth(undefined, 1)); +assertFalse(sameValueBoth(undefined, obj1)); +assertFalse(sameValueBoth(undefined, NaN)); + +assertFalse(sameValueBoth(NaN, true)); +assertFalse(sameValueBoth(NaN, "foo")); +assertFalse(sameValueBoth(NaN, 1)); +assertFalse(sameValueBoth(NaN, obj1)); +assertFalse(sameValueBoth(NaN, undefined)); + +assertFalse(sameValueBoth("foo", true)); +assertFalse(sameValueBoth("foo", 1)); +assertFalse(sameValueBoth("foo", obj1)); +assertFalse(sameValueBoth("foo", undefined)); +assertFalse(sameValueBoth("foo", NaN)); + +assertFalse(sameValueBoth(true, 1)); +assertFalse(sameValueBoth(true, obj1)); +assertFalse(sameValueBoth(true, undefined)); +assertFalse(sameValueBoth(true, NaN)); +assertFalse(sameValueBoth(true, "foo")); + +assertFalse(sameValueBoth(1, true)); +assertFalse(sameValueBoth(1, obj1)); +assertFalse(sameValueBoth(1, undefined)); +assertFalse(sameValueBoth(1, NaN)); +assertFalse(sameValueBoth(1, "foo")); // Special string cases. -assertFalse(sameValue("1", 1)); -assertFalse(sameValue("true", true)); -assertFalse(sameValue("false", false)); -assertFalse(sameValue("undefined", undefined)); -assertFalse(sameValue("NaN", NaN)); - -// -0 and +0 are should be different -assertFalse(sameValue(+0, -0)); -assertFalse(sameValue(-0, +0)); +assertFalse(sameValueBoth("1", 1)); +assertFalse(sameValueBoth("true", true)); +assertFalse(sameValueBoth("false", false)); +assertFalse(sameValueBoth("undefined", undefined)); +assertFalse(sameValueBoth("NaN", NaN)); + +// SameValue considers -0 and +0 to be different; SameValueZero considers +// -0 and +0 to be the same. +assertTrue(sameValueZeroOnly(+0, -0)); +assertTrue(sameValueZeroOnly(-0, +0)); diff --git a/deps/v8/test/mjsunit/string-normalize.js b/deps/v8/test/mjsunit/string-normalize.js index f88f193a09..d8ae74d4ea 100644 --- a/deps/v8/test/mjsunit/string-normalize.js +++ b/deps/v8/test/mjsunit/string-normalize.js @@ -9,3 +9,11 @@ assertEquals('', ''.normalize()); assertThrows(function() { ''.normalize('invalid'); }, RangeError); assertTrue(delete Array.prototype.join); assertThrows(function() { ''.normalize('invalid'); }, RangeError); + +// All of these toString to an invalid form argument. +assertThrows(function() { ''.normalize(null) }, RangeError); +assertThrows(function() { ''.normalize(true) }, RangeError); +assertThrows(function() { ''.normalize(false) }, RangeError); +assertThrows(function() { ''.normalize(42) }, RangeError); +assertThrows(function() { ''.normalize({}) }, RangeError); +assertThrows(function() { ''.normalize([]) }, RangeError); diff --git a/deps/v8/test/mjsunit/strong/class-extend-null.js b/deps/v8/test/mjsunit/strong/class-extend-null.js new file mode 100644 index 0000000000..3ed7b36dbb --- /dev/null +++ b/deps/v8/test/mjsunit/strong/class-extend-null.js @@ -0,0 +1,97 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --strong-mode --allow-natives-syntax + +(function() { +"use strict"; + +let foo = null; + +function nullLiteral() { + class Class1 extends null { + constructor() { + super(); + } + } +} + +function nullVariable() { + class Class2 extends foo { + constructor() { + super(); + } + } +} + +function nullLiteralClassExpr() { + (class extends null {}); +} + +function nullVariableClassExpr() { + (class extends foo {}); +} + +assertDoesNotThrow(nullLiteral); +%OptimizeFunctionOnNextCall(nullLiteral); +assertDoesNotThrow(nullLiteral); + +assertDoesNotThrow(nullVariable); +%OptimizeFunctionOnNextCall(nullVariable); +assertDoesNotThrow(nullVariable); + +assertDoesNotThrow(nullLiteralClassExpr); +%OptimizeFunctionOnNextCall(nullLiteralClassExpr); +assertDoesNotThrow(nullLiteralClassExpr); + +assertDoesNotThrow(nullVariableClassExpr); +%OptimizeFunctionOnNextCall(nullVariableClassExpr); +assertDoesNotThrow(nullVariableClassExpr); +})(); + +(function() { +"use strong"; + +let foo = null; + +function nullLiteral() { + class Class1 extends null { + constructor() { + super(); + } + } +} + +function nullVariable() { + class Class2 extends foo { + constructor() { + super(); + } + } +} + +function nullLiteralClassExpr() { + (class extends null {}); +} + +function nullVariableClassExpr() { + (class extends foo {}); +} + +assertThrows(nullLiteral, TypeError); +%OptimizeFunctionOnNextCall(nullLiteral); +assertThrows(nullLiteral, TypeError); + +assertThrows(nullVariable, TypeError); +%OptimizeFunctionOnNextCall(nullVariable); +assertThrows(nullVariable, TypeError); + +assertThrows(nullLiteralClassExpr, TypeError); +%OptimizeFunctionOnNextCall(nullLiteralClassExpr); +assertThrows(nullLiteralClassExpr, TypeError); + +assertThrows(nullVariableClassExpr, TypeError); +%OptimizeFunctionOnNextCall(nullVariableClassExpr); +assertThrows(nullVariableClassExpr, TypeError); +})(); diff --git a/deps/v8/test/mjsunit/strong/class-object-frozen.js b/deps/v8/test/mjsunit/strong/class-object-frozen.js new file mode 100644 index 0000000000..2c442c0d51 --- /dev/null +++ b/deps/v8/test/mjsunit/strong/class-object-frozen.js @@ -0,0 +1,98 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --strong-mode + +"use strict"; + +function getClass() { + class Foo { + static get bar() { return 0 } + get bar() { return 0 } + } + return Foo; +} + +function getClassExpr() { + return (class { static get bar() { return 0 } get bar() { return 0 } }); +} + +function getClassStrong() { + "use strong"; + class Foo { + static get bar() { return 0 } + get bar() { return 0 } + } + return Foo; +} + +function getClassExprStrong() { + "use strong"; + return (class { static get bar() { return 0 } get bar() { return 0 } }); +} + +function addProperty(o) { + o.baz = 1; +} + +function convertPropertyToData(o) { + assertTrue(o.hasOwnProperty("bar")); + Object.defineProperty(o, "bar", { value: 1 }); +} + +function testWeakClass(classFunc) { + assertDoesNotThrow(function(){addProperty(classFunc())}); + assertDoesNotThrow(function(){addProperty(classFunc().prototype)}); + assertDoesNotThrow(function(){convertPropertyToData(classFunc())}); + assertDoesNotThrow(function(){convertPropertyToData(classFunc().prototype)}); +} + +function testStrongClass(classFunc) { + assertThrows(function(){addProperty(classFunc())}, TypeError); + assertThrows(function(){addProperty(classFunc().prototype)}, TypeError); + assertThrows(function(){convertPropertyToData(classFunc())}, TypeError); + assertThrows(function(){convertPropertyToData(classFunc().prototype)}, + TypeError); +} + +testWeakClass(getClass); +testWeakClass(getClassExpr); + +testStrongClass(getClassStrong); +testStrongClass(getClassExprStrong); + +// Check strong classes don't freeze their parents. +(function() { + let parent = getClass(); + + let classFunc = function() { + "use strong"; + class Foo extends parent { + static get bar() { return 0 } + get bar() { return 0 } + } + return Foo; + } + + testStrongClass(classFunc); + assertDoesNotThrow(function(){addProperty(parent)}); + assertDoesNotThrow(function(){convertPropertyToData(parent)}); +})(); + +// Check strong classes don't freeze their children. +(function() { + let parent = getClassStrong(); + + let classFunc = function() { + class Foo extends parent { + static get bar() { return 0 } + get bar() { return 0 } + } + return Foo; + } + + assertThrows(function(){addProperty(parent)}, TypeError); + assertThrows(function(){convertPropertyToData(parent)}, TypeError); + testWeakClass(classFunc); +})(); diff --git a/deps/v8/test/mjsunit/strong/declaration-after-use.js b/deps/v8/test/mjsunit/strong/declaration-after-use.js index 5f3ef2a79c..e6caccfcca 100644 --- a/deps/v8/test/mjsunit/strong/declaration-after-use.js +++ b/deps/v8/test/mjsunit/strong/declaration-after-use.js @@ -3,7 +3,6 @@ // found in the LICENSE file. // Flags: --strong-mode --harmony-rest-parameters --harmony-arrow-functions -// Flags: --harmony-computed-property-names // Note that it's essential for these tests that the reference is inside dead // code (because we already produce ReferenceErrors for run-time unresolved diff --git a/deps/v8/test/mjsunit/strong/destructuring.js b/deps/v8/test/mjsunit/strong/destructuring.js new file mode 100644 index 0000000000..67fe2ef4f1 --- /dev/null +++ b/deps/v8/test/mjsunit/strong/destructuring.js @@ -0,0 +1,25 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Flags: --harmony-destructuring +// Flags: --harmony-arrow-functions --strong-mode --allow-natives-syntax + +(function() { + function f({ x = function() { return []; } }) { "use strong"; return x(); } + var a = f({ x: undefined }); + assertTrue(%IsStrong(a)); + + // TODO(rossberg): Loading non-existent properties during destructuring should + // not throw in strong mode. + assertThrows(function() { f({}); }, TypeError); + + function weakf({ x = function() { return []; } }) { return x(); } + a = weakf({}); + assertFalse(%IsStrong(a)); + + function outerf() { return []; } + function f2({ x = outerf }) { "use strong"; return x(); } + a = f2({ x: undefined }); + assertFalse(%IsStrong(a)); +})(); diff --git a/deps/v8/test/mjsunit/strong/literals.js b/deps/v8/test/mjsunit/strong/literals.js index 73129e7a09..8c04d6e35a 100644 --- a/deps/v8/test/mjsunit/strong/literals.js +++ b/deps/v8/test/mjsunit/strong/literals.js @@ -310,8 +310,8 @@ let GeneratorPrototype = (function*(){}).__proto__; 'use strong'; function assertStrongClass(x) { assertTrue(%IsStrong(x)); - // TODO(rossberg): strongify class prototype and instance - // assertTrue(%IsStrong(x.prototype)); + assertTrue(%IsStrong(x.prototype)); + // TODO(rossberg): strongify class instance // assertTrue(%IsStrong(new x)); } class C {}; diff --git a/deps/v8/test/mjsunit/unbox-double-arrays.js b/deps/v8/test/mjsunit/unbox-double-arrays.js index 5ed404025f..8711ffdf3d 100644 --- a/deps/v8/test/mjsunit/unbox-double-arrays.js +++ b/deps/v8/test/mjsunit/unbox-double-arrays.js @@ -489,17 +489,6 @@ test_for_in(); test_for_in(); test_for_in(); -function test_get_property_names() { - names = %GetPropertyNames(large_array3); - property_name_count = 0; - for (x in names) { property_name_count++; }; - assertEquals(26, property_name_count); -} - -test_get_property_names(); -test_get_property_names(); -test_get_property_names(); - // Test elements getters. assertEquals(expected_array_value(10), large_array3[10]); assertEquals(expected_array_value(-NaN), large_array3[2]); diff --git a/deps/v8/test/preparser/testcfg.py b/deps/v8/test/preparser/testcfg.py index ddd311c201..7e51b8ef58 100644 --- a/deps/v8/test/preparser/testcfg.py +++ b/deps/v8/test/preparser/testcfg.py @@ -126,8 +126,8 @@ class PreparserTestSuite(testsuite.TestSuite): with open(testcase.flags[0]) as f: return f.read() - def VariantFlags(self, testcase, default_flags): - return [[]]; + def _VariantGeneratorFactory(self): + return testsuite.StandardVariantGenerator def GetSuite(name, root): diff --git a/deps/v8/test/promises-aplus/lib/global.js b/deps/v8/test/promises-aplus/lib/global.js index 1466d2063b..ece338ed3e 100644 --- a/deps/v8/test/promises-aplus/lib/global.js +++ b/deps/v8/test/promises-aplus/lib/global.js @@ -33,15 +33,6 @@ var clearTimeout; var timers = {}; var currentId = 0; -function PostMicrotask(fn) { - var o = {}; - Object.observe(o, function() { - fn(); - }); - // Change something to enqueue a microtask. - o.x = 'hello'; -} - setInterval = function(fn, delay) { var i = 0; var id = currentId++; @@ -52,9 +43,9 @@ setInterval = function(fn, delay) { if (i++ >= delay) { fn(); } - PostMicrotask(loop); + %EnqueueMicrotask(loop); } - PostMicrotask(loop); + %EnqueueMicrotask(loop); timers[id] = true; return id; } diff --git a/deps/v8/test/promises-aplus/lib/mocha.js b/deps/v8/test/promises-aplus/lib/mocha.js index 24d294ef8f..0a172b9d2f 100644 --- a/deps/v8/test/promises-aplus/lib/mocha.js +++ b/deps/v8/test/promises-aplus/lib/mocha.js @@ -41,15 +41,6 @@ var assert = require('assert'); (function() { var TIMEOUT = 1000; -function PostMicrotask(fn) { - var o = {}; - Object.observe(o, function() { - fn(); - }); - // Change something to enqueue a microtask. - o.x = 'hello'; -} - var context = { beingDescribed: undefined, currentSuiteIndex: 0, @@ -162,7 +153,7 @@ TestCase.prototype.Run = function(suite, postAction) { if (this.isRegular) { print('PASS: ' + suite.description + '#' + this.name); } - PostMicrotask(postAction); + %EnqueueMicrotask(postAction); }.bind(this)); }.bind(this)); }.bind(this)); @@ -194,14 +185,14 @@ function TestSuite(described) { TestSuite.prototype.Run = function() { this.hasRun = this.currentIndex === this.cases.length; if (this.hasRun) { - PostMicrotask(Run); + %EnqueueMicrotask(Run); return; } // TestCase.prototype.Run cannot throw an exception. this.cases[this.currentIndex].Run(this, function() { ++this.currentIndex; - PostMicrotask(Run); + %EnqueueMicrotask(Run); }.bind(this)); }; @@ -224,7 +215,7 @@ TestSuite.prototype.ReportError = function(testCase, e) { print('FAIL: ' + this.description + '#' + testCase.name + ': ' + e.name + ' (' + e.message + ')'); ++this.currentIndex; - PostMicrotask(Run); + %EnqueueMicrotask(Run); }; describe = function(description, fn) { diff --git a/deps/v8/test/promises-aplus/testcfg.py b/deps/v8/test/promises-aplus/testcfg.py index bd03379187..5f447c3f90 100644 --- a/deps/v8/test/promises-aplus/testcfg.py +++ b/deps/v8/test/promises-aplus/testcfg.py @@ -77,7 +77,7 @@ class PromiseAplusTestSuite(testsuite.TestSuite): if fname.endswith('.js')] def GetFlagsForTestCase(self, testcase, context): - return (testcase.flags + context.mode_flags + ['--harmony'] + + return (testcase.flags + context.mode_flags + ['--allow-natives-syntax'] + self.helper_files_pre + [os.path.join(self.test_files_root, testcase.path + '.js')] + self.helper_files_post) diff --git a/deps/v8/test/simdjs/SimdJs.json b/deps/v8/test/simdjs/SimdJs.json index b671ac4cb8..ae2a32e308 100644 --- a/deps/v8/test/simdjs/SimdJs.json +++ b/deps/v8/test/simdjs/SimdJs.json @@ -18,22 +18,17 @@ "test/simdjs/data/src/benchmarks/averageFloat32x4LoadX.js", "test/simdjs/data/src/benchmarks/averageFloat32x4LoadXY.js", "test/simdjs/data/src/benchmarks/averageFloat32x4LoadXYZ.js", - "test/simdjs/data/src/benchmarks/averageFloat64x2.js", - "test/simdjs/data/src/benchmarks/averageFloat64x2Load.js", - "test/simdjs/data/src/benchmarks/mandelbrot.js", "test/simdjs/data/src/benchmarks/matrix-multiplication.js", "test/simdjs/data/src/benchmarks/transform.js", "test/simdjs/data/src/benchmarks/shiftrows.js", "test/simdjs/data/src/benchmarks/transpose4x4.js", "test/simdjs/data/src/benchmarks/inverse4x4.js", - "test/simdjs/data/src/benchmarks/sinx4.js", "test/simdjs/data/src/benchmarks/memset.js", "test/simdjs/data/src/benchmarks/memcpy.js" ], "run_count": 5, - "run_count_android_arm": 1, - "run_count_android_arm64": 3, "run_count_arm": 3, + "run_count_arm64": 3, "tests": [ { "flags": [ @@ -133,54 +128,6 @@ }, { "flags": [ - "test/simdjs/data/src/benchmarks/averageFloat64x2.js" - ], - "main": "test/simdjs/harness-finish.js", - "name": "averageFloat64x2", - "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)", - "tests": [ - { - "name": "SIMD" - }, - { - "name": "Non-SIMD" - } - ] - }, - { - "flags": [ - "test/simdjs/data/src/benchmarks/averageFloat64x2Load.js" - ], - "main": "test/simdjs/harness-finish.js", - "name": "averageFloat64x2Load", - "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)", - "tests": [ - { - "name": "SIMD" - }, - { - "name": "Non-SIMD" - } - ] - }, - { - "flags": [ - "test/simdjs/data/src/benchmarks/mandelbrot.js" - ], - "main": "test/simdjs/harness-finish.js", - "name": "mandelbrot", - "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)", - "tests": [ - { - "name": "SIMD" - }, - { - "name": "Non-SIMD" - } - ] - }, - { - "flags": [ "test/simdjs/data/src/benchmarks/matrix-multiplication.js" ], "main": "test/simdjs/harness-finish.js", @@ -261,22 +208,6 @@ }, { "flags": [ - "test/simdjs/data/src/benchmarks/sinx4.js" - ], - "main": "test/simdjs/harness-finish.js", - "name": "sinx4", - "results_regexp": "%s\\([ ]*([0-9.]+)(ms)?\\)", - "tests": [ - { - "name": "SIMD" - }, - { - "name": "Non-SIMD" - } - ] - }, - { - "flags": [ "test/simdjs/data/src/benchmarks/memset.js" ], "main": "test/simdjs/harness-finish.js", @@ -308,8 +239,7 @@ ] } ], - "timeout_android_arm": 180, - "timeout_android_arm64": 120, - "timeout_arm": 120, + "timeout_arm": 240, + "timeout_arm64": 120, "units": "ms" }
\ No newline at end of file diff --git a/deps/v8/test/simdjs/harness-adapt.js b/deps/v8/test/simdjs/harness-adapt.js index a2ca2372c4..c90d6cc9d1 100644 --- a/deps/v8/test/simdjs/harness-adapt.js +++ b/deps/v8/test/simdjs/harness-adapt.js @@ -27,3 +27,13 @@ load('ecmascript_simd.js'); load('base.js'); })(); + +// ecmascript_simd_tests logs errors to the console. +var console = { + log: function(x) { print(x); }, +}; + + +// Disable value type tests for now. The value semantics tests are incorrect. +// TODO(bbudge): Drop when tests are fixed. +var skipValueTests = true; diff --git a/deps/v8/test/simdjs/simdjs.status b/deps/v8/test/simdjs/simdjs.status index 99ce8865e5..4ef3c9841b 100644 --- a/deps/v8/test/simdjs/simdjs.status +++ b/deps/v8/test/simdjs/simdjs.status @@ -10,8 +10,12 @@ [ [ALWAYS, { - # TODO(bradnelson): Drop when test is fixed upstream. + # TODO(bbudge): Drop when test is fixed upstream. 'benchmarks/aobench': SKIP, + 'benchmarks/averageFloat64x2': SKIP, + 'benchmarks/averageFloat64x2Load': SKIP, + 'benchmarks/mandelbrot': SKIP, + 'benchmarks/sinx4': SKIP, # TODO(bbudge): Drop this when simd implementation is faster. 'benchmarks/memcpy': SKIP, diff --git a/deps/v8/test/simdjs/testcfg.py b/deps/v8/test/simdjs/testcfg.py index c0390afd65..cbe880d149 100644 --- a/deps/v8/test/simdjs/testcfg.py +++ b/deps/v8/test/simdjs/testcfg.py @@ -14,10 +14,9 @@ from testrunner.local import testsuite from testrunner.local import utils from testrunner.objects import testcase -SIMDJS_ARCHIVE_REVISION = "07e2713e0c9ea19feb0732d5bd84770c87310d79" -SIMDJS_ARCHIVE_MD5 = "cf6bddf99f18800b68e782054268ee3c" -SIMDJS_URL = ( - "https://github.com/johnmccutchan/ecmascript_simd/archive/%s.tar.gz") +SIMDJS_ARCHIVE_REVISION = "99ef44bd4f22acd203c01e524131bc7f2a7eab68" +SIMDJS_ARCHIVE_MD5 = "1428773887924fa5a784bf0843615740" +SIMDJS_URL = ("https://github.com/tc39/ecmascript_simd/archive/%s.tar.gz") SIMDJS_SUITE_PATH = ["data", "src"] @@ -65,10 +64,44 @@ class SimdJsTestSuite(testsuite.TestSuite): def DownloadData(self): revision = SIMDJS_ARCHIVE_REVISION archive_url = SIMDJS_URL % revision + + archive_prefix = "ecmascript_simd-" archive_name = os.path.join( - self.root, "ecmascript_simd-%s.tar.gz" % revision) + self.root, "%s%s.tar.gz" % (archive_prefix, revision)) directory_name = os.path.join(self.root, "data") directory_old_name = os.path.join(self.root, "data.old") + versionfile = os.path.join(self.root, "CHECKED_OUT_VERSION") + + checked_out_version = None + checked_out_url = None + checked_out_revision = None + if os.path.exists(versionfile): + with open(versionfile) as f: + try: + (checked_out_version, + checked_out_url, + checked_out_revision) = f.read().splitlines() + except ValueError: + pass + if (checked_out_version != SIMDJS_ARCHIVE_MD5 or + checked_out_url != archive_url or + checked_out_revision != revision): + if os.path.exists(archive_name): + print "Clobbering %s because CHECK_OUT_VERSION is out of date" % ( + archive_name) + os.remove(archive_name) + + # Clobber if the test is in an outdated state, i.e. if there are any other + # archive files present. + archive_files = [f for f in os.listdir(self.root) + if f.startswith(archive_prefix)] + if (len(archive_files) > 1 or + os.path.basename(archive_name) not in archive_files): + print "Clobber outdated test archives ..." + for f in archive_files: + print "Removing %s" % f + os.remove(os.path.join(self.root, f)) + if not os.path.exists(archive_name): print "Downloading test data from %s ..." % archive_url utils.URLRetrieve(archive_url, archive_name) @@ -96,6 +129,11 @@ class SimdJsTestSuite(testsuite.TestSuite): os.rename(os.path.join(self.root, "ecmascript_simd-%s" % revision), directory_name) + with open(versionfile, "w") as f: + f.write(SIMDJS_ARCHIVE_MD5 + '\n') + f.write(archive_url + '\n') + f.write(revision + '\n') + def GetSuite(name, root): return SimdJsTestSuite(name, root) diff --git a/deps/v8/test/test262-es6/test262-es6.status b/deps/v8/test/test262-es6/test262-es6.status index 65ded6d3f5..16068bf0ca 100644 --- a/deps/v8/test/test262-es6/test262-es6.status +++ b/deps/v8/test/test262-es6/test262-es6.status @@ -34,16 +34,6 @@ 'intl402/12.2.3_b': [FAIL], # BUG(v8:4267) - 'built-ins/Object/defineProperty/15.2.3.6-4-116': [FAIL], - 'built-ins/Object/defineProperty/15.2.3.6-4-117': [FAIL], - 'built-ins/Object/defineProperty/15.2.3.6-4-168': [FAIL], - 'built-ins/Object/defineProperty/15.2.3.6-4-169': [FAIL], - 'built-ins/Object/defineProperty/15.2.3.6-4-170': [FAIL], - 'built-ins/Object/defineProperty/15.2.3.6-4-172': [FAIL], - 'built-ins/Object/defineProperty/15.2.3.6-4-173': [FAIL], - 'built-ins/Object/defineProperty/15.2.3.6-4-174': [FAIL], - 'built-ins/Object/defineProperty/15.2.3.6-4-176': [FAIL], - 'built-ins/Object/defineProperty/15.2.3.6-4-177': [FAIL], 'built-ins/Object/defineProperties/15.2.3.7-6-a-112': [FAIL], 'built-ins/Object/defineProperties/15.2.3.7-6-a-113': [FAIL], 'built-ins/Object/defineProperties/15.2.3.7-6-a-164': [FAIL], @@ -56,6 +46,16 @@ 'built-ins/Object/defineProperties/15.2.3.7-6-a-173': [FAIL], 'built-ins/Object/defineProperties/15.2.3.7-6-a-175': [FAIL], 'built-ins/Object/defineProperties/15.2.3.7-6-a-176': [FAIL], + 'built-ins/Object/defineProperty/15.2.3.6-4-116': [FAIL], + 'built-ins/Object/defineProperty/15.2.3.6-4-117': [FAIL], + 'built-ins/Object/defineProperty/15.2.3.6-4-168': [FAIL], + 'built-ins/Object/defineProperty/15.2.3.6-4-169': [FAIL], + 'built-ins/Object/defineProperty/15.2.3.6-4-170': [FAIL], + 'built-ins/Object/defineProperty/15.2.3.6-4-172': [FAIL], + 'built-ins/Object/defineProperty/15.2.3.6-4-173': [FAIL], + 'built-ins/Object/defineProperty/15.2.3.6-4-174': [FAIL], + 'built-ins/Object/defineProperty/15.2.3.6-4-176': [FAIL], + 'built-ins/Object/defineProperty/15.2.3.6-4-177': [FAIL], # Unicode canonicalization is not available with i18n turned off. 'built-ins/String/prototype/localeCompare/15.5.4.9_CE': [['no_i18n', SKIP]], @@ -63,9 +63,9 @@ ###################### NEEDS INVESTIGATION ####################### # Possibly same cause as S8.5_A2.1, below: floating-point tests. + 'built-ins/Math/cos/S15.8.2.7_A7': [PASS, FAIL_OK], 'built-ins/Math/sin/S15.8.2.16_A7': [PASS, FAIL_OK], 'built-ins/Math/tan/S15.8.2.18_A7': [PASS, FAIL_OK], - 'built-ins/Math/cos/S15.8.2.7_A7': [PASS, FAIL_OK], # This is an incompatibility between ES5 and V8 on enumerating # shadowed elements in a for..in loop. @@ -76,7 +76,6 @@ # Class, let, const in sloppy mode. # https://code.google.com/p/v8/issues/detail?id=3305 - 'built-ins/Array/prototype/concat/Array.prototype.concat_non-array': [PASS, FAIL_SLOPPY], 'language/block-scope/leave/finally-block-let-declaration-only-shadows-outer-parameter-value-1': [PASS, FAIL_SLOPPY], 'language/block-scope/leave/finally-block-let-declaration-only-shadows-outer-parameter-value-2': [PASS, FAIL_SLOPPY], 'language/block-scope/leave/for-loop-block-let-declaration-only-shadows-outer-parameter-value-1': [PASS, FAIL_SLOPPY], @@ -109,107 +108,6 @@ 'language/block-scope/syntax/redeclaration-in-block/attempt-to-redeclare-function-declaration-with-function-declaration': [PASS, FAIL_SLOPPY], 'language/block-scope/syntax/redeclaration-in-block/attempt-to-redeclare-function-declaration-with-var': [PASS, FAIL_SLOPPY], 'language/block-scope/syntax/redeclaration-in-block/attempt-to-redeclare-var-with-function-declaration': [PASS, FAIL_SLOPPY], - 'language/class/definition/ClassDeclaration_restricted-properties': [PASS, FAIL_SLOPPY], - 'language/class/definition/ClassExpression_restricted-properties': [PASS, FAIL_SLOPPY], - 'language/class/definition/ClassMethod_restricted-properties': [PASS, FAIL_SLOPPY], - 'language/class/method-definition/generator-no-yield': [PASS, FAIL_SLOPPY], - 'language/class/method-definition/generator-return': [PASS, FAIL_SLOPPY], - 'language/class/method-definition/yield-as-expression-with-rhs': [PASS, FAIL_SLOPPY], - 'language/class/method-definition/yield-as-expression-without-rhs': [PASS, FAIL_SLOPPY], - 'language/class/method-definition/yield-as-generator-method-binding-identifier': [PASS, FAIL_SLOPPY], - 'language/class/method-definition/yield-as-literal-property-name': [PASS, FAIL_SLOPPY], - 'language/class/method-definition/yield-as-property-name': [PASS, FAIL_SLOPPY], - 'language/class/method-definition/yield-as-statement': [PASS, FAIL_SLOPPY], - 'language/class/method-definition/yield-as-yield-operand': [PASS, FAIL_SLOPPY], - 'language/class/method-definition/yield-newline': [PASS, FAIL_SLOPPY], - 'language/class/method-definition/yield-star-before-newline': [PASS, FAIL_SLOPPY], - 'language/computed-property-names/class/accessor/*': [PASS, FAIL_SLOPPY], - 'language/computed-property-names/class/method/*': [PASS, FAIL_SLOPPY], - 'language/computed-property-names/class/static/generator-constructor': [PASS, FAIL_SLOPPY], - 'language/computed-property-names/class/static/generator-prototype': [PASS, FAIL_SLOPPY], - 'language/computed-property-names/class/static/getter-constructor': [PASS, FAIL_SLOPPY], - 'language/computed-property-names/class/static/getter-prototype': [PASS, FAIL_SLOPPY], - 'language/computed-property-names/class/static/method-constructor': [PASS, FAIL_SLOPPY], - 'language/computed-property-names/class/static/method-prototype': [PASS, FAIL_SLOPPY], - 'language/computed-property-names/class/static/setter-constructor': [PASS, FAIL_SLOPPY], - 'language/computed-property-names/class/static/setter-prototype': [PASS, FAIL_SLOPPY], - 'language/computed-property-names/to-name-side-effects/class': [PASS, FAIL_SLOPPY], - 'language/computed-property-names/to-name-side-effects/numbers-class': [PASS, FAIL_SLOPPY], - 'language/expressions/arrow-function/lexical-super-call-from-within-constructor':[PASS, FAIL_SLOPPY], - 'language/expressions/arrow-function/lexical-super-property-from-within-constructor': [PASS, FAIL_SLOPPY], - 'language/expressions/arrow-function/lexical-super-property': [PASS, FAIL_SLOPPY], - 'language/expressions/arrow-function/lexical-supercall-from-immediately-invoked-arrow': [PASS, FAIL_SLOPPY], - 'language/expressions/object/method-definition/generator-param-redecl-const': [PASS, FAIL_SLOPPY], - 'language/expressions/object/method-definition/generator-shadow-parameter-const': [PASS, FAIL_SLOPPY], - 'language/rest-parameters/with-new-target': [PASS, FAIL_SLOPPY], - 'language/statements/class/arguments/access': [PASS, FAIL_SLOPPY], - 'language/statements/class/arguments/default-constructor': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/accessors': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/constructable-but-no-prototype': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/constructor-property': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/constructor-strict-by-default': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/constructor': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/getters-2': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/getters': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/implicit-constructor': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/invalid-extends': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/methods-named-eval-arguments': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/methods': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/numeric-property-names': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/prototype-getter': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/prototype-property': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/prototype-setter': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/prototype-wiring': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/setters-2': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/setters': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/side-effects-in-extends': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/side-effects-in-property-define': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/this-access-restriction-2': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/this-access-restriction': [PASS, FAIL_SLOPPY], - 'language/statements/class/definition/this-check-ordering': [PASS, FAIL_SLOPPY], - 'language/statements/class/name-binding/basic': [PASS, FAIL_SLOPPY], - 'language/statements/class/name-binding/const': [PASS, FAIL_SLOPPY], - 'language/statements/class/name-binding/expression': [PASS, FAIL_SLOPPY], - 'language/statements/class/strict-mode/arguments-caller': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/binding': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/builtins': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/class-definition-evaluation-empty-constructor-heritage-present': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/class-definition-null-proto-contains-return-override': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/class-definition-null-proto-missing-return-override': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/class-definition-null-proto': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/class-definition-superclass-generator': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/default-constructor-2': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/default-constructor': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/derived-class-return-override-with-boolean': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/derived-class-return-override-with-empty': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/derived-class-return-override-with-null': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/derived-class-return-override-with-number': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/derived-class-return-override-with-object': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/derived-class-return-override-with-string': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/derived-class-return-override-with-symbol': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/derived-class-return-override-with-this': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/derived-class-return-override-with-undefined': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/superclass-prototype-setter-constructor': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/superclass-prototype-setter-method-override': [PASS, FAIL_SLOPPY], - 'language/statements/class/subclass/superclass-static-method-override': [PASS, FAIL_SLOPPY], - 'language/statements/class/super/in-constructor': [PASS, FAIL_SLOPPY], - 'language/statements/class/super/in-getter': [PASS, FAIL_SLOPPY], - 'language/statements/class/super/in-methods': [PASS, FAIL_SLOPPY], - 'language/statements/class/super/in-setter': [PASS, FAIL_SLOPPY], - 'language/statements/class/super/in-static-getter': [PASS, FAIL_SLOPPY], - 'language/statements/class/super/in-static-methods': [PASS, FAIL_SLOPPY], - 'language/statements/class/super/in-static-setter': [PASS, FAIL_SLOPPY], - 'language/statements/class/syntax/class-body-has-direct-super-class-heritage': [PASS, FAIL_SLOPPY], - 'language/statements/class/syntax/class-body-method-definition-super-property': [PASS, FAIL_SLOPPY], - 'language/statements/class/syntax/class-declaration-binding-identifier-class-element-list': [PASS, FAIL_SLOPPY], - 'language/statements/class/syntax/class-declaration-computed-method-definition': [PASS, FAIL_SLOPPY], - 'language/statements/class/syntax/class-declaration-computed-method-generator-definition': [PASS, FAIL_SLOPPY], - 'language/statements/class/syntax/class-declaration-heritage-identifier-reference-class-element-list': [PASS, FAIL_SLOPPY], - 'language/statements/class/syntax/class-expression-binding-identifier-opt-class-element-list': [PASS, FAIL_SLOPPY], - 'language/statements/class/syntax/class-expression-heritage-identifier-reference': [PASS, FAIL_SLOPPY], - 'language/statements/class/syntax/class-expression': [PASS, FAIL_SLOPPY], - 'language/statements/class/syntax/class-method-propname-constructor': [PASS, FAIL_SLOPPY], - 'language/statements/class/syntax/early-errors/class-body-constructor-empty-missing-class-heritage': [PASS, FAIL_SLOPPY], 'language/statements/const/block-local-closure-get-before-initialization': [PASS, FAIL_SLOPPY], 'language/statements/const/block-local-use-before-initialization-in-declaration-statement': [PASS, FAIL_SLOPPY], 'language/statements/const/block-local-use-before-initialization-in-prior-statement': [PASS, FAIL_SLOPPY], @@ -222,22 +120,22 @@ 'language/statements/const/syntax/block-scope-syntax-const-declarations-mixed-with-without-initialiser': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/block-scope-syntax-const-declarations-mixed-without-with-initialiser': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/block-scope-syntax-const-declarations-without-initialiser': [PASS, FAIL_SLOPPY], + 'language/statements/const/syntax/const': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/const-invalid-assignment-statement-body-for-in': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/const-invalid-assignment-statement-body-for-of': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/const-outer-inner-let-bindings': [PASS, FAIL_SLOPPY], - 'language/statements/const/syntax/const': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/with-initializer-do-statement-while-expression': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/with-initializer-for-statement': [PASS, FAIL_SLOPPY], - 'language/statements/const/syntax/with-initializer-if-expression-statement-else-statement': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/with-initializer-if-expression-statement': [PASS, FAIL_SLOPPY], + 'language/statements/const/syntax/with-initializer-if-expression-statement-else-statement': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/with-initializer-label-statement': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/with-initializer-while-expression-statement': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/without-initializer-case-expression-statement-list': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/without-initializer-default-statement-list': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/without-initializer-do-statement-while-expression': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/without-initializer-for-statement': [PASS, FAIL_SLOPPY], - 'language/statements/const/syntax/without-initializer-if-expression-statement-else-statement': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/without-initializer-if-expression-statement': [PASS, FAIL_SLOPPY], + 'language/statements/const/syntax/without-initializer-if-expression-statement-else-statement': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/without-initializer-label-statement': [PASS, FAIL_SLOPPY], 'language/statements/const/syntax/without-initializer-while-expression-statement': [PASS, FAIL_SLOPPY], 'language/statements/continue/labeled-continue': [PASS, FAIL_SLOPPY], @@ -247,19 +145,33 @@ 'language/statements/continue/no-label-continue': [PASS, FAIL_SLOPPY], 'language/statements/continue/shadowing-loop-variable-in-same-scope-as-continue': [PASS, FAIL_SLOPPY], 'language/statements/continue/simple-and-labeled': [PASS, FAIL_SLOPPY], + 'language/statements/for-in/const-bound-names-fordecl-tdz-for-in': [PASS, FAIL_SLOPPY], 'language/statements/for-in/const-fresh-binding-per-iteration-for-in': [PASS, FAIL_SLOPPY], + 'language/statements/for-in/let-bound-names-fordecl-tdz-for-in': [PASS, FAIL_SLOPPY], 'language/statements/for-in/let-fresh-binding-per-iteration-for-in': [PASS, FAIL_SLOPPY], + 'language/statements/for-of/const-bound-names-fordecl-tdz-for-of': [PASS, FAIL_SLOPPY], 'language/statements/for-of/const-fresh-binding-per-iteration-for-of': [PASS, FAIL_SLOPPY], + 'language/statements/for-of/let-bound-names-fordecl-tdz-for-of': [PASS, FAIL_SLOPPY], 'language/statements/for-of/let-fresh-binding-per-iteration-for-of': [PASS, FAIL_SLOPPY], 'language/statements/for/const-fresh-binding-per-iteration-for': [PASS, FAIL_SLOPPY], 'language/statements/for/let-fresh-binding-per-iteration-for': [PASS, FAIL_SLOPPY], + 'language/statements/let/block-local-closure-get-before-initialization': [PASS, FAIL_SLOPPY], + 'language/statements/let/block-local-closure-set-before-initialization': [PASS, FAIL_SLOPPY], + 'language/statements/let/block-local-use-before-initialization-in-declaration-statement': [PASS, FAIL_SLOPPY], + 'language/statements/let/block-local-use-before-initialization-in-prior-statement': [PASS, FAIL_SLOPPY], + 'language/statements/let/function-local-closure-get-before-initialization': [PASS, FAIL_SLOPPY], + 'language/statements/let/function-local-closure-set-before-initialization': [PASS, FAIL_SLOPPY], + 'language/statements/let/function-local-use-before-initialization-in-declaration-statement': [PASS, FAIL_SLOPPY], + 'language/statements/let/function-local-use-before-initialization-in-prior-statement': [PASS, FAIL_SLOPPY], + 'language/statements/let/global-closure-get-before-initialization': [PASS, FAIL_SLOPPY], + 'language/statements/let/global-closure-set-before-initialization': [PASS, FAIL_SLOPPY], + 'language/statements/let/syntax/let': [PASS, FAIL_SLOPPY], 'language/statements/let/syntax/let-closure-inside-condition': [PASS, FAIL_SLOPPY], 'language/statements/let/syntax/let-closure-inside-initialization': [PASS, FAIL_SLOPPY], 'language/statements/let/syntax/let-closure-inside-next-expression': [PASS, FAIL_SLOPPY], 'language/statements/let/syntax/let-iteration-variable-is-freshly-allocated-for-each-iteration-multi-let-binding': [PASS, FAIL_SLOPPY], 'language/statements/let/syntax/let-iteration-variable-is-freshly-allocated-for-each-iteration-single-let-binding': [PASS, FAIL_SLOPPY], 'language/statements/let/syntax/let-outer-inner-let-bindings': [PASS, FAIL_SLOPPY], - 'language/statements/let/syntax/let': [PASS, FAIL_SLOPPY], 'language/statements/let/syntax/with-initialisers-in-statement-positions-case-expression-statement-list': [PASS, FAIL_SLOPPY], 'language/statements/let/syntax/with-initialisers-in-statement-positions-default-statement-list': [PASS, FAIL_SLOPPY], 'language/statements/let/syntax/without-initialisers-in-statement-positions-case-expression-statement-list': [PASS, FAIL_SLOPPY], @@ -271,6 +183,12 @@ # Number/Boolean.prototype is a plain object in ES6 # https://code.google.com/p/v8/issues/detail?id=4001 + 'built-ins/Boolean/prototype/S15.6.3.1_A1': [FAIL], + 'built-ins/Boolean/prototype/S15.6.4_A1': [FAIL], + 'built-ins/Boolean/prototype/toString/S15.6.4.2_A1_T1': [FAIL], + 'built-ins/Boolean/prototype/toString/S15.6.4.2_A1_T2': [FAIL], + 'built-ins/Boolean/prototype/valueOf/S15.6.4.3_A1_T1': [FAIL], + 'built-ins/Boolean/prototype/valueOf/S15.6.4.3_A1_T2': [FAIL], 'built-ins/Number/15.7.4-1': [FAIL], 'built-ins/Number/prototype/S15.7.3.1_A2_*': [FAIL], 'built-ins/Number/prototype/S15.7.3.1_A3': [FAIL], @@ -279,15 +197,6 @@ 'built-ins/Number/prototype/toString/S15.7.4.2_A1_*': [FAIL], 'built-ins/Number/prototype/toString/S15.7.4.2_A2_*': [FAIL], 'built-ins/Number/prototype/valueOf/S15.7.4.4_A1_*': [FAIL], - 'built-ins/Boolean/prototype/S15.6.3.1_A1': [FAIL], - 'built-ins/Boolean/prototype/S15.6.4_A1': [FAIL], - 'built-ins/Boolean/prototype/toString/S15.6.4.2_A1_T1': [FAIL], - 'built-ins/Boolean/prototype/toString/S15.6.4.2_A1_T2': [FAIL], - 'built-ins/Boolean/prototype/valueOf/S15.6.4.3_A1_T1': [FAIL], - 'built-ins/Boolean/prototype/valueOf/S15.6.4.3_A1_T2': [FAIL], - - # https://code.google.com/p/v8/issues/detail?id=4118 - 'built-ins/Object/getOwnPropertyNames/15.2.3.4-4-44': [FAIL], # https://code.google.com/p/v8/issues/detail?id=3087 'built-ins/Array/prototype/every/15.4.4.16-3-12': [FAIL], @@ -362,21 +271,30 @@ 'language/expressions/object/prop-def-id-eval-error-2': [FAIL], 'language/statements/for-of/iterator-as-proxy': [FAIL], 'language/statements/for-of/iterator-next-result-type': [FAIL], + 'built-ins/Array/of/return-abrupt-from-data-property-using-proxy': [FAIL], # https://code.google.com/p/v8/issues/detail?id=4093 'built-ins/Array/symbol-species': [FAIL], + 'built-ins/Array/symbol-species-name': [FAIL], 'built-ins/ArrayBuffer/symbol-species': [FAIL], + 'built-ins/ArrayBuffer/symbol-species-name': [FAIL], 'built-ins/Map/symbol-species': [FAIL], + 'built-ins/Map/symbol-species-name': [FAIL], + 'built-ins/Promise/Symbol.species/prop-desc': [FAIL], + 'built-ins/Promise/Symbol.species/return-value': [FAIL], + 'built-ins/Promise/all/species-get-error': [FAIL], + 'built-ins/Promise/prototype/then/ctor-custom': [FAIL], + 'built-ins/Promise/race/species-get-error': [FAIL], 'built-ins/Promise/symbol-species': [FAIL], + 'built-ins/Promise/symbol-species-name': [FAIL], 'built-ins/RegExp/symbol-species': [FAIL], + 'built-ins/RegExp/symbol-species-name': [FAIL], 'built-ins/Set/symbol-species': [FAIL], + 'built-ins/Set/symbol-species-name': [FAIL], 'built-ins/Symbol/species/basic': [FAIL], 'built-ins/Symbol/species/builtin-getter-name': [FAIL], 'built-ins/Symbol/species/subclassing': [FAIL], - # https://code.google.com/p/v8/issues/detail?id=4242 - 'built-ins/Date/15.9.1.15-1': [FAIL], - # https://code.google.com/p/v8/issues/detail?id=4004 'built-ins/Date/prototype/setFullYear/15.9.5.40_1': [FAIL], @@ -387,7 +305,18 @@ 'built-ins/GeneratorPrototype/next/context-constructor-invocation': [FAIL], # https://code.google.com/p/v8/issues/detail?id=3566 + 'built-ins/Array/from/iter-map-fn-err': [FAIL], + 'built-ins/Array/from/iter-set-elem-prop-err': [FAIL], + 'built-ins/Map/iterator-close-after-set-failure': [FAIL], + 'built-ins/Map/iterator-item-first-entry-returns-abrupt': [FAIL], + 'built-ins/Map/iterator-item-second-entry-returns-abrupt': [FAIL], + 'built-ins/Map/iterator-items-are-not-object-close-iterator': [FAIL], + 'built-ins/Promise/all/iter-close': [FAIL], 'built-ins/Set/set-iterator-close-after-add-failure': [FAIL], + 'built-ins/WeakMap/iterator-close-after-set-failure': [FAIL], + 'built-ins/WeakMap/iterator-item-first-entry-returns-abrupt': [FAIL], + 'built-ins/WeakMap/iterator-item-second-entry-returns-abrupt': [FAIL], + 'built-ins/WeakMap/iterator-items-are-not-object-close-iterator': [FAIL], 'built-ins/WeakSet/iterator-close-after-add-failure': [FAIL], # https://code.google.com/p/v8/issues/detail?id=3715 @@ -414,6 +343,9 @@ 'built-ins/Promise/race/S25.4.4.3_A3.1_T2': [FAIL], 'built-ins/Promise/reject/S25.4.4.4_A3.1_T1': [FAIL], + # https://code.google.com/p/v8/issues/detail?id=4341 + 'built-ins/Promise/resolve/arg-uniq-ctor': [FAIL], + # https://code.google.com/p/v8/issues/detail?id=4119 'built-ins/RegExp/15.10.4.1-1': [FAIL], 'built-ins/RegExp/S15.10.3.1_A2_T1': [FAIL], @@ -426,6 +358,7 @@ # https://code.google.com/p/v8/issues/detail?id=4244 'built-ins/RegExp/prototype/exec/S15.10.6.2_A5_T3': [FAIL], + 'built-ins/RegExp/prototype/test/S15.10.6.3_A1_T22': [FAIL], # https://code.google.com/p/v8/issues/detail?id=4006 'built-ins/String/prototype/S15.5.4_A1': [FAIL], @@ -436,8 +369,8 @@ # https://code.google.com/p/v8/issues/detail?id=4245 'built-ins/String/prototype/split/S15.5.4.14_A2_T37': [FAIL], - # https://code.google.com/p/v8/issues/detail?id=3088 - 'built-ins/Symbol/auto-boxing-strict': [FAIL], + # https://code.google.com/p/v8/issues/detail?id=4348 + 'built-ins/String/prototype/Symbol.iterator/this-val-non-obj-coercible': [FAIL], # The order of adding the name property is wrong # https://code.google.com/p/v8/issues/detail?id=4199 @@ -445,10 +378,8 @@ 'language/computed-property-names/class/static/method-symbol': [FAIL, FAIL_SLOPPY], 'language/computed-property-names/class/static/method-string': [FAIL, FAIL_SLOPPY], - # new.target - # https://code.google.com/p/v8/issues/detail?id=3887 - 'language/expressions/arrow-function/lexical-new.target': [FAIL], - 'language/expressions/arrow-function/lexical-new.target-closure-returned': [FAIL], + # This should work as soon as rest parameters are re-implemented via desaguring. + 'language/expressions/arrow-function/syntax/early-errors/arrowparameters-cover-no-duplicates-rest': [PASS, FAIL], # https://code.google.com/p/v8/issues/detail?id=2160 'language/expressions/arrow-function/syntax/arrowparameters-cover-initialize-1': [FAIL], @@ -479,6 +410,13 @@ # We do not expose Array.prototype.values # https://code.google.com/p/v8/issues/detail?id=4247 'built-ins/Array/prototype/Symbol.iterator': [FAIL], + 'built-ins/Array/prototype/values/returns-iterator': [FAIL], + 'built-ins/Array/prototype/values/returns-iterator-from-object': [FAIL], + 'built-ins/Array/prototype/values/prop-desc': [FAIL], + 'built-ins/Array/prototype/values/name': [FAIL], + 'built-ins/Array/prototype/values/length': [FAIL], + 'built-ins/Array/prototype/values/iteration': [FAIL], + 'built-ins/Array/prototype/values/iteration-mutable': [FAIL], #https://code.google.com/p/v8/issues/detail?id=3983 'language/expressions/generators/yield-as-function-expression-binding-identifier': [FAIL], @@ -505,132 +443,8 @@ 'built-ins/GeneratorPrototype/return/try-finally-within-finally': [FAIL], 'built-ins/GeneratorPrototype/return/try-finally-within-try': [FAIL], - # https://code.google.com/p/v8/issues/detail?id=4177 - 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-2': [FAIL], - 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-3': [FAIL], - 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-4': [FAIL], - 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-2': [FAIL], - 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-3': [FAIL], - 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-delete-4': [FAIL], - 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-3': [FAIL], - 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-4': [FAIL], - 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-nonwritable-5': [FAIL], - 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-2': [FAIL], - 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-3': [FAIL], - 'language/arguments-object/mapped/mapped-arguments-nonconfigurable-strict-delete-4': [FAIL], - # https://code.google.com/p/v8/issues/detail?id=811 - 'language/expressions/assignment/destructuring/array-elem-elision': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-init-assignment': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-init-evaluation': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-init-in': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-init-let': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-init-order': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-init-simple-no-strict': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-init-yield-expr': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-init-yield-ident-valid': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-array': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-array-null': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-array-undefined': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-array-undefined-hole': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-array-undefined-own': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-array-yield-expr': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-array-yield-ident-valid': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-obj': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-obj-null': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-obj-undefined': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-obj-undefined-hole': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-obj-undefined-own': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-obj-yield-expr': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-nested-obj-yield-ident-valid': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-put-const': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-put-let': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-put-prop-ref': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-put-prop-ref-no-get': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-put-prop-ref-user-err': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-put-unresolvable-no-strict': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-put-unresolvable-strict': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-target-identifier': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-target-simple-no-strict': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-target-yield-expr': [FAIL], - 'language/expressions/assignment/destructuring/array-elem-target-yield-valid': [FAIL], - 'language/expressions/assignment/destructuring/array-empty': [FAIL], - 'language/expressions/assignment/destructuring/array-iteration': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-after-element': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-after-elision': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-elision': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-iteration': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-array': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-array-null': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-array-undefined': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-array-undefined-hole': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-array-undefined-own': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-array-yield-expr': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-array-yield-ident-valid': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-obj': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-obj-null': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-obj-undefined': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-obj-undefined-hole': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-obj-undefined-own': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-obj-yield-expr': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-nested-obj-yield-ident-valid': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-put-const': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-put-let': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-put-prop-ref': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-put-prop-ref-no-get': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-put-prop-ref-user-err': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-put-unresolvable-no-strict': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-put-unresolvable-strict': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-yield-expr': [FAIL], - 'language/expressions/assignment/destructuring/array-rest-yield-ident-valid': [FAIL], - 'language/expressions/assignment/destructuring/array-sparse': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-identifier-resolution': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-identifier-yield-ident-valid': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-init-assignment': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-init-evaluation': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-init-in': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-init-let': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-init-order': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-init-simple-no-strict': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-init-yield-expr': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-init-yield-ident-valid': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-put-const': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-put-let': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-put-unresolvable-no-strict': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-put-unresolvable-strict': [FAIL], - 'language/expressions/assignment/destructuring/obj-id-simple-no-strict': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-elem-init-assignment': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-elem-init-evaluation': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-elem-init-in': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-elem-init-let': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-elem-init-yield-expr': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-elem-init-yield-ident-valid': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-elem-target-yield-expr': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-elem-target-yield-ident-valid': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-identifier-resolution': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-name-evaluation': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-name-evaluation-error': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-nested-array': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-nested-array-null': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-nested-array-undefined': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-nested-array-undefined-own': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-nested-array-yield-expr': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-nested-array-yield-ident-valid': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-nested-obj': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-nested-obj-null': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-nested-obj-undefined': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-nested-obj-undefined-own': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-nested-obj-yield-expr': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-nested-obj-yield-ident-valid': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-put-const': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-put-let': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-put-order': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-put-prop-ref': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-put-prop-ref-no-get': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-put-prop-ref-user-err': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-put-unresolvable-no-strict': [FAIL], - 'language/expressions/assignment/destructuring/obj-prop-put-unresolvable-strict': [FAIL], - 'language/expressions/assignment/destructuring/object-empty': [FAIL], + 'language/expressions/assignment/destructuring/*': [SKIP], # https://code.google.com/p/v8/issues/detail?id=4248 'language/expressions/compound-assignment/S11.13.2_A5.*': [FAIL], @@ -661,8 +475,55 @@ 'language/expressions/assignment/S11.13.1_A6*': [FAIL], # https://code.google.com/p/v8/issues/detail?id=3699 + 'built-ins/Function/instance-name': [FAIL], + 'built-ins/GeneratorFunction/instance-name': [FAIL], + 'language/expressions/assignment/fn-name-arrow': [FAIL], + 'language/expressions/assignment/fn-name-class': [FAIL], + 'language/expressions/assignment/fn-name-cover': [FAIL], + 'language/expressions/assignment/fn-name-fn': [FAIL], + 'language/expressions/assignment/fn-name-gen': [FAIL], + 'language/expressions/assignment/fn-name-lhs-cover': [FAIL], + 'language/expressions/assignment/fn-name-lhs-member': [FAIL], + 'language/expressions/class/name': [FAIL], + 'language/expressions/function/name': [FAIL], 'language/expressions/generators/implicit-name': [FAIL], + 'language/expressions/generators/name': [FAIL], 'language/expressions/generators/name-property-descriptor': [FAIL], + 'language/expressions/object/fn-name-accessor-get': [FAIL], + 'language/expressions/object/fn-name-accessor-set': [FAIL], + 'language/expressions/object/fn-name-arrow': [FAIL], + 'language/expressions/object/fn-name-class': [FAIL], + 'language/expressions/object/fn-name-cover': [FAIL], + 'language/expressions/object/fn-name-fn': [FAIL], + 'language/expressions/object/fn-name-gen': [FAIL], + 'language/expressions/object/fn-name-lhs-cover': [FAIL], + 'language/expressions/object/fn-name-lhs-member': [FAIL], + 'language/expressions/object/method-definition/fn-name-accessor-get': [FAIL], + 'language/expressions/object/method-definition/fn-name-accessor-set': [FAIL], + 'language/expressions/object/method-definition/fn-name-arrow': [FAIL], + 'language/expressions/object/method-definition/fn-name-class': [FAIL], + 'language/expressions/object/method-definition/fn-name-cover': [FAIL], + 'language/expressions/object/method-definition/fn-name-fn': [FAIL], + 'language/expressions/object/method-definition/fn-name-gen': [FAIL], + 'language/statements/class/definition/fn-name-accessor-get': [FAIL], + 'language/statements/class/definition/fn-name-accessor-set': [FAIL], + 'language/statements/class/definition/fn-name-gen-method': [FAIL], + 'language/statements/class/definition/fn-name-method': [FAIL], + 'language/statements/const/fn-name-arrow': [FAIL], + 'language/statements/const/fn-name-class': [FAIL], + 'language/statements/const/fn-name-cover': [FAIL], + 'language/statements/const/fn-name-fn': [FAIL], + 'language/statements/const/fn-name-gen': [FAIL], + 'language/statements/let/fn-name-arrow': [FAIL], + 'language/statements/let/fn-name-class': [FAIL], + 'language/statements/let/fn-name-cover': [FAIL], + 'language/statements/let/fn-name-fn': [FAIL], + 'language/statements/let/fn-name-gen': [FAIL], + 'language/statements/variable/fn-name-arrow': [FAIL], + 'language/statements/variable/fn-name-class': [FAIL], + 'language/statements/variable/fn-name-cover': [FAIL], + 'language/statements/variable/fn-name-fn': [FAIL], + 'language/statements/variable/fn-name-gen': [FAIL], # https://code.google.com/p/v8/issues/detail?id=4251 'language/expressions/postfix-increment/S11.3.1_A5_T1': [FAIL], @@ -681,58 +542,191 @@ 'language/expressions/object/method-definition/generator-name-prop-symbol': [FAIL], 'language/expressions/object/method-definition/name-name-prop-symbol': [FAIL], + # https://code.google.com/p/v8/issues/detail?id=4317 + 'built-ins/Array/prototype/concat/is-concat-spreadable-val-falsey': [FAIL], + + # https://code.google.com/p/v8/issues/detail?id=2952 + 'built-ins/RegExp/prototype/exec/u-lastindex-adv': [FAIL], + 'built-ins/RegExp/prototype/exec/u-captured-value': [FAIL], + 'built-ins/RegExp/prototype/exec/u-lastindex-value': [FAIL], + 'built-ins/RegExp/prototype/test/u-captured-value': [FAIL], + 'built-ins/RegExp/prototype/test/u-lastindex-adv': [FAIL], + 'built-ins/RegExp/prototype/test/u-lastindex-value': [FAIL], + 'built-ins/RegExp/prototype/unicode/length': [FAIL], + 'built-ins/RegExp/prototype/unicode/name': [FAIL], + 'built-ins/RegExp/prototype/unicode/prop-desc': [FAIL], + 'built-ins/RegExp/prototype/unicode/this-invald-obj': [FAIL], + 'built-ins/RegExp/prototype/unicode/this-non-obj': [FAIL], + 'built-ins/RegExp/prototype/unicode/this-regexp': [FAIL], + 'built-ins/RegExp/unicode_identity_escape': [FAIL], + 'language/literals/regexp/u-unicode-esc': [FAIL], + 'language/literals/regexp/u-surrogate-pairs': [FAIL], + 'language/literals/regexp/u-case-mapping': [FAIL], + 'language/literals/regexp/u-astral': [FAIL], + + # https://code.google.com/p/v8/issues/detail?id=4342 + 'built-ins/RegExp/prototype/exec/get-sticky-coerce': [FAIL], + 'built-ins/RegExp/prototype/exec/get-sticky-err': [FAIL], + 'built-ins/RegExp/prototype/exec/y-fail-lastindex': [FAIL], + 'built-ins/RegExp/prototype/exec/y-fail-lastindex-no-write': [FAIL], + 'built-ins/RegExp/prototype/exec/y-fail-return': [FAIL], + 'built-ins/RegExp/prototype/exec/y-fail-lastindex': [FAIL], + 'built-ins/RegExp/prototype/exec/y-init-lastindex': [FAIL], + 'built-ins/RegExp/prototype/exec/y-set-lastindex': [FAIL], + 'built-ins/RegExp/prototype/sticky/prop-desc': [FAIL], + 'built-ins/RegExp/prototype/sticky/this-invalid-obj': [FAIL], + 'built-ins/RegExp/prototype/sticky/this-non-obj': [FAIL], + 'built-ins/RegExp/prototype/sticky/this-regexp': [FAIL], + 'built-ins/RegExp/prototype/test/get-sticky-coerce': [FAIL], + 'built-ins/RegExp/prototype/test/get-sticky-err': [FAIL], + 'built-ins/RegExp/prototype/test/y-fail-lastindex-no-write': [FAIL], + 'built-ins/RegExp/prototype/test/y-fail-return': [FAIL], + 'built-ins/RegExp/prototype/test/y-fail-lastindex': [FAIL], + 'built-ins/RegExp/prototype/test/y-init-lastindex': [FAIL], + 'built-ins/RegExp/prototype/test/y-set-lastindex': [FAIL], + 'built-ins/RegExp/valid-flags-y': [FAIL], + + # https://code.google.com/p/v8/issues/detail?id=4305 + 'built-ins/RegExp/prototype/Symbol.match/*': [FAIL], + 'built-ins/String/prototype/endsWith/return-abrupt-from-searchstring-regexp-test': [FAIL], + 'built-ins/String/prototype/includes/return-abrupt-from-searchstring-regexp-test': [FAIL], + 'built-ins/String/prototype/startsWith/return-abrupt-from-searchstring-regexp-test': [FAIL], + + # https://code.google.com/p/v8/issues/detail?id=4343 + 'built-ins/RegExp/prototype/Symbol.replace/*': [FAIL], + + # https://code.google.com/p/v8/issues/detail?id=4344 + 'built-ins/RegExp/prototype/Symbol.search/*': [FAIL], + + # https://code.google.com/p/v8/issues/detail?id=4345 + 'built-ins/RegExp/prototype/Symbol.split/*': [FAIL], + + # https://code.google.com/p/v8/issues/detail?id=4346 + 'built-ins/RegExp/prototype/flags/*': [FAIL], + + # https://code.google.com/p/v8/issues/detail?id=4347 + 'built-ins/RegExp/prototype/global/name': [FAIL], + 'built-ins/RegExp/prototype/ignoreCase/name': [FAIL], + 'built-ins/RegExp/prototype/multiline/name': [FAIL], + 'built-ins/RegExp/prototype/source/name': [FAIL], + 'built-ins/RegExp/prototype/sticky/name': [FAIL], + + # https://code.google.com/p/v8/issues/detail?id=4360 + 'intl402/Collator/10.1.1_1': [FAIL], + 'intl402/DateTimeFormat/12.1.1_1': [FAIL], + 'intl402/NumberFormat/11.1.1_1': [FAIL], + + # https://code.google.com/p/v8/issues/detail?id=4361 + 'intl402/Collator/10.1.1_a': [FAIL], + + # https://code.google.com/p/v8/issues/detail?id=1972 + 'language/identifiers/val-break-via-escape-hex': [FAIL], + 'language/identifiers/val-break-via-escape-hex4': [FAIL], + 'language/identifiers/val-case-via-escape-hex': [FAIL], + 'language/identifiers/val-case-via-escape-hex4': [FAIL], + 'language/identifiers/val-catch-via-escape-hex': [FAIL], + 'language/identifiers/val-catch-via-escape-hex4': [FAIL], + 'language/identifiers/val-class-via-escape-hex': [FAIL], + 'language/identifiers/val-class-via-escape-hex4': [FAIL], + 'language/identifiers/val-const-via-escape-hex': [FAIL], + 'language/identifiers/val-const-via-escape-hex4': [FAIL], + 'language/identifiers/val-continue-via-escape-hex': [FAIL], + 'language/identifiers/val-continue-via-escape-hex4': [FAIL], + 'language/identifiers/val-debugger-via-escape-hex': [FAIL], + 'language/identifiers/val-debugger-via-escape-hex4': [FAIL], + 'language/identifiers/val-default-via-escape-hex': [FAIL], + 'language/identifiers/val-default-via-escape-hex4': [FAIL], + 'language/identifiers/val-delete-via-escape-hex': [FAIL], + 'language/identifiers/val-delete-via-escape-hex4': [FAIL], + 'language/identifiers/val-do-via-escape-hex': [FAIL], + 'language/identifiers/val-do-via-escape-hex4': [FAIL], + 'language/identifiers/val-else-via-escape-hex': [FAIL], + 'language/identifiers/val-else-via-escape-hex4': [FAIL], + 'language/identifiers/val-enum-via-escape-hex': [FAIL], + 'language/identifiers/val-enum-via-escape-hex4': [FAIL], + 'language/identifiers/val-export-via-escape-hex': [FAIL], + 'language/identifiers/val-export-via-escape-hex4': [FAIL], + 'language/identifiers/val-extends-via-escape-hex': [FAIL], + 'language/identifiers/val-extends-via-escape-hex4': [FAIL], + 'language/identifiers/val-false-via-escape-hex': [FAIL], + 'language/identifiers/val-false-via-escape-hex4': [FAIL], + 'language/identifiers/val-finally-via-escape-hex': [FAIL], + 'language/identifiers/val-finally-via-escape-hex4': [FAIL], + 'language/identifiers/val-for-via-escape-hex': [FAIL], + 'language/identifiers/val-for-via-escape-hex4': [FAIL], + 'language/identifiers/val-function-via-escape-hex': [FAIL], + 'language/identifiers/val-function-via-escape-hex4': [FAIL], + 'language/identifiers/val-if-via-escape-hex': [FAIL], + 'language/identifiers/val-if-via-escape-hex4': [FAIL], + 'language/identifiers/val-import-via-escape-hex': [FAIL], + 'language/identifiers/val-import-via-escape-hex4': [FAIL], + 'language/identifiers/val-in-via-escape-hex': [FAIL], + 'language/identifiers/val-in-via-escape-hex4': [FAIL], + 'language/identifiers/val-instanceof-via-escape-hex': [FAIL], + 'language/identifiers/val-instanceof-via-escape-hex4': [FAIL], + 'language/identifiers/val-new-via-escape-hex': [FAIL], + 'language/identifiers/val-new-via-escape-hex4': [FAIL], + 'language/identifiers/val-null-via-escape-hex': [FAIL], + 'language/identifiers/val-null-via-escape-hex4': [FAIL], + 'language/identifiers/val-return-via-escape-hex': [FAIL], + 'language/identifiers/val-return-via-escape-hex4': [FAIL], + 'language/identifiers/val-super-via-escape-hex': [FAIL], + 'language/identifiers/val-super-via-escape-hex4': [FAIL], + 'language/identifiers/val-switch-via-escape-hex': [FAIL], + 'language/identifiers/val-switch-via-escape-hex4': [FAIL], + 'language/identifiers/val-throw-via-escape-hex': [FAIL], + 'language/identifiers/val-throw-via-escape-hex4': [FAIL], + 'language/identifiers/val-true-via-escape-hex': [FAIL], + 'language/identifiers/val-true-via-escape-hex4': [FAIL], + 'language/identifiers/val-try-via-escape-hex': [FAIL], + 'language/identifiers/val-try-via-escape-hex4': [FAIL], + 'language/identifiers/val-typeof-via-escape-hex': [FAIL], + 'language/identifiers/val-typeof-via-escape-hex4': [FAIL], + 'language/identifiers/val-var-via-escape-hex': [FAIL], + 'language/identifiers/val-var-via-escape-hex4': [FAIL], + 'language/identifiers/val-void-via-escape-hex': [FAIL], + 'language/identifiers/val-void-via-escape-hex4': [FAIL], + 'language/identifiers/val-while-via-escape-hex': [FAIL], + 'language/identifiers/val-while-via-escape-hex4': [FAIL], + 'language/identifiers/val-with-via-escape-hex': [FAIL], + 'language/identifiers/val-with-via-escape-hex4': [FAIL], + + # https://code.google.com/p/v8/issues/detail?id=4362 + 'built-ins/String/prototype/repeat/empty-string-returns-empty': [PASS, FAIL], + ######################## NEEDS INVESTIGATION ########################### # These test failures are specific to the intl402 suite and need investigation # to be either marked as bugs with issues filed for them or as deliberate # incompatibilities if the test cases turn out to be broken or ambiguous. + # Some of these are related to v8:4361 in being visible side effects from Intl. 'intl402/6.2.3': [FAIL], 'intl402/9.2.1_2': [FAIL], 'intl402/9.2.6_2': [FAIL], - 'intl402/10.1.1_a': [FAIL], - 'intl402/10.1.2.1_4': [FAIL], - 'intl402/10.1.2_a': [PASS, FAIL], - 'intl402/10.2.3_b': [PASS, FAIL], - 'intl402/10.3.2_1_c': [PASS, FAIL], - 'intl402/10.3.2_CS_b_NN': [PASS, FAIL], - 'intl402/10.3.2_CS_c_NN': [PASS, FAIL], - 'intl402/10.3.2_CS_d_NN': [PASS, FAIL], - 'intl402/10.3_a': [FAIL], - 'intl402/11.1.1_20_c': [FAIL], - 'intl402/11.1.1_a': [FAIL], - 'intl402/11.1.2': [PASS, FAIL], - 'intl402/11.1.2.1_4': [FAIL], - 'intl402/11.3_a': [FAIL], - 'intl402/12.1.1_a': [FAIL], - 'intl402/12.1.2': [PASS, FAIL], - 'intl402/12.1.2.1_4': [FAIL], - 'intl402/12.3.2_FDT_7_a_iv': [FAIL], - 'intl402/12.3.3': [FAIL], - 'intl402/12.3_a': [FAIL], - 'intl402/13.1.1_7': [PASS, FAIL], - 'intl402/13.2.1_5': [PASS, FAIL], - 'intl402/13.3.0_7': [PASS, FAIL], - - # These tests fail in nosnap in strict mode - # https://code.google.com/p/v8/issues/detail?id=4198 - 'built-ins/String/S15.5.1.1_A1_T6': [PASS, FAIL_OK], - 'built-ins/eval/S15.1.2.1_A1.1_T1': [PASS, FAIL_OK], - 'built-ins/eval/S15.1.2.1_A1.1_T2': [PASS, FAIL_OK], - 'built-ins/eval/S15.1.2.1_A4.3': [PASS, FAIL_OK], - 'built-ins/eval/S15.1.2.1_A4.4': [PASS, FAIL_OK], - 'language/eval-code/10.4.2-1-1': [PASS, FAIL_OK], - 'language/eval-code/10.4.2-1-2': [PASS, FAIL_OK], - 'language/eval-code/10.4.2-1-3': [PASS, FAIL_OK], - 'language/eval-code/10.4.2-1-5': [PASS, FAIL_OK], - 'language/eval-code/S10.4.2.1_A1': [PASS, FAIL_OK], - 'language/function-code/10.4.3-1-19-s': [PASS, FAIL_OK], - 'language/function-code/10.4.3-1-19gs': [PASS, FAIL_OK], - 'language/function-code/10.4.3-1-20-s': [PASS, FAIL_OK], - 'language/function-code/10.4.3-1-20gs': [PASS, FAIL_OK], - 'language/statements/variable/12.2.1-10-s': [PASS, FAIL_OK], - 'language/statements/variable/12.2.1-20-s': [PASS, FAIL_OK], - 'language/statements/variable/12.2.1-21-s': [PASS, FAIL_OK], - 'language/statements/variable/12.2.1-9-s': [PASS, FAIL_OK], + 'intl402/Collator/10.1.2.1_4': [FAIL], + 'intl402/Collator/10.1.2_a': [PASS, FAIL], + 'intl402/Collator/10.2.3_b': [PASS, FAIL], + 'intl402/Collator/prototype/10.3_a': [FAIL], + 'intl402/Date/prototype/13.3.0_7': [FAIL], + 'intl402/DateTimeFormat/12.1.1': [FAIL], + 'intl402/DateTimeFormat/12.1.1_a': [FAIL], + 'intl402/DateTimeFormat/12.1.1_1': [FAIL], + 'intl402/DateTimeFormat/12.1.2': [PASS, FAIL], + 'intl402/DateTimeFormat/12.1.2.1_4': [FAIL], + 'intl402/DateTimeFormat/12.2.3_b': [FAIL], + 'intl402/DateTimeFormat/prototype/12.3.2_FDT_7_a_iv': [FAIL], + 'intl402/DateTimeFormat/prototype/12.3.3': [FAIL], + 'intl402/DateTimeFormat/prototype/12.3_a': [FAIL], + 'intl402/DateTimeFormat/prototype/format/12.3.2_FDT_7_a_iv': [FAIL], + 'intl402/Number/prototype/toLocaleString/13.2.1_5': [PASS, FAIL], + 'intl402/NumberFormat/11.1.1_20_c': [FAIL], + 'intl402/NumberFormat/11.1.1_a': [FAIL], + 'intl402/NumberFormat/11.1.1': [FAIL], + 'intl402/NumberFormat/11.1.2': [PASS, FAIL], + 'intl402/NumberFormat/11.1.2.1_4': [FAIL], + 'intl402/NumberFormat/11.2.3_b': [FAIL], + 'intl402/NumberFormat/prototype/11.3_a': [FAIL], + 'intl402/String/prototype/localeCompare/13.1.1_7': [PASS, FAIL], ##################### DELIBERATE INCOMPATIBILITIES ##################### @@ -767,6 +761,13 @@ 'built-ins/Object/keys/15.2.3.14-1-2': [PASS, FAIL_OK], 'built-ins/Object/keys/15.2.3.14-1-3': [PASS, FAIL_OK], + # Test bug https://github.com/tc39/test262/issues/405 + 'intl402/Collator/prototype/compare/10.3.2_1_c': [PASS, FAIL_OK], + 'intl402/Collator/prototype/compare/10.3.2_CS_b_NN': [PASS, FAIL_OK], + 'intl402/Collator/prototype/compare/10.3.2_CS_c_NN': [PASS, FAIL_OK], + 'intl402/Collator/prototype/compare/10.3.2_CS_d_NN': [PASS, FAIL_OK], + 'intl402/Date/prototype/13.3.0_7': [PASS, FAIL_OK], + ############################ SKIPPED TESTS ############################# # These tests take a looong time to run. diff --git a/deps/v8/test/test262-es6/testcfg.py b/deps/v8/test/test262-es6/testcfg.py index 91491b3907..88f4ad1297 100644 --- a/deps/v8/test/test262-es6/testcfg.py +++ b/deps/v8/test/test262-es6/testcfg.py @@ -39,8 +39,8 @@ from testrunner.local import utils from testrunner.objects import testcase # The revision hash needs to be 7 characters? -TEST_262_ARCHIVE_REVISION = "c6ac390" # This is the 2015-07-06 revision. -TEST_262_ARCHIVE_MD5 = "e1393ef330f38e9cb1bfa4e3eada5ba8" +TEST_262_ARCHIVE_REVISION = "258d212" # This is the 2015-07-31 revision. +TEST_262_ARCHIVE_MD5 = "a9b26e19ce582492642af973c8cee826" TEST_262_URL = "https://github.com/tc39/test262/tarball/%s" TEST_262_HARNESS_FILES = ["sta.js", "assert.js"] @@ -48,6 +48,55 @@ TEST_262_SUITE_PATH = ["data", "test"] TEST_262_HARNESS_PATH = ["data", "harness"] TEST_262_TOOLS_PATH = ["data", "tools", "packaging"] +ALL_VARIANT_FLAGS_STRICT = dict( + (v, [flags + ["--use-strict"] for flags in flag_sets]) + for v, flag_sets in testsuite.ALL_VARIANT_FLAGS.iteritems() +) + +FAST_VARIANT_FLAGS_STRICT = dict( + (v, [flags + ["--use-strict"] for flags in flag_sets]) + for v, flag_sets in testsuite.FAST_VARIANT_FLAGS.iteritems() +) + +ALL_VARIANT_FLAGS_BOTH = dict( + (v, [flags for flags in testsuite.ALL_VARIANT_FLAGS[v] + + ALL_VARIANT_FLAGS_STRICT[v]]) + for v in testsuite.ALL_VARIANT_FLAGS +) + +FAST_VARIANT_FLAGS_BOTH = dict( + (v, [flags for flags in testsuite.FAST_VARIANT_FLAGS[v] + + FAST_VARIANT_FLAGS_STRICT[v]]) + for v in testsuite.FAST_VARIANT_FLAGS +) + +ALL_VARIANTS = { + 'nostrict': testsuite.ALL_VARIANT_FLAGS, + 'strict': ALL_VARIANT_FLAGS_STRICT, + 'both': ALL_VARIANT_FLAGS_BOTH, +} + +FAST_VARIANTS = { + 'nostrict': testsuite.FAST_VARIANT_FLAGS, + 'strict': FAST_VARIANT_FLAGS_STRICT, + 'both': FAST_VARIANT_FLAGS_BOTH, +} + +class Test262VariantGenerator(testsuite.VariantGenerator): + def GetFlagSets(self, testcase, variant): + if testcase.outcomes and statusfile.OnlyFastVariants(testcase.outcomes): + variant_flags = FAST_VARIANTS + else: + variant_flags = ALL_VARIANTS + + test_record = self.suite.GetTestRecord(testcase) + if "noStrict" in test_record: + return variant_flags["nostrict"][variant] + if "onlyStrict" in test_record: + return variant_flags["strict"][variant] + return variant_flags["both"][variant] + + class Test262TestSuite(testsuite.TestSuite): def __init__(self, name, root): @@ -81,15 +130,8 @@ class Test262TestSuite(testsuite.TestSuite): self.GetIncludesForTest(testcase) + ["--harmony"] + [os.path.join(self.testroot, testcase.path + ".js")]) - def VariantFlags(self, testcase, default_flags): - flags = super(Test262TestSuite, self).VariantFlags(testcase, default_flags) - test_record = self.GetTestRecord(testcase) - if "noStrict" in test_record: - return flags - strict_flags = [f + ["--use-strict"] for f in flags] - if "onlyStrict" in test_record: - return strict_flags - return flags + strict_flags + def _VariantGeneratorFactory(self): + return Test262VariantGenerator def LoadParseTestRecord(self): if not self.ParseTestRecord: diff --git a/deps/v8/test/test262/test262.status b/deps/v8/test/test262/test262.status index feed1a3206..b9ef3c68f4 100644 --- a/deps/v8/test/test262/test262.status +++ b/deps/v8/test/test262/test262.status @@ -281,6 +281,9 @@ '15.2.3.13-1-3': [FAIL], '15.2.3.13-1-4': [FAIL], + # ES6 says for dates to default to the local timezone if none is specified + '15.9.1.15-1': [FAIL], + ######################## NEEDS INVESTIGATION ########################### # These test failures are specific to the intl402 suite and need investigation diff --git a/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc b/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc index 7e67b31616..71c2d44d2f 100644 --- a/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc +++ b/deps/v8/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc @@ -2421,6 +2421,40 @@ TEST_F(InstructionSelectorTest, Word32EqualWithSignedExtendHalfword) { } +TEST_F(InstructionSelectorTest, Word32EqualZeroWithWord32Equal) { + { + StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + m.Return(m.Word32Equal(m.Word32Equal(p0, p1), m.Int32Constant(0))); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); + EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); + EXPECT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(kFlags_set, s[0]->flags_mode()); + EXPECT_EQ(kNotEqual, s[0]->flags_condition()); + } + { + StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); + Node* const p0 = m.Parameter(0); + Node* const p1 = m.Parameter(1); + m.Return(m.Word32Equal(m.Int32Constant(0), m.Word32Equal(p0, p1))); + Stream s = m.Build(); + ASSERT_EQ(1U, s.size()); + EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); + ASSERT_EQ(2U, s[0]->InputCount()); + EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); + EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); + EXPECT_EQ(1U, s[0]->OutputCount()); + EXPECT_EQ(kFlags_set, s[0]->flags_mode()); + EXPECT_EQ(kNotEqual, s[0]->flags_condition()); + } +} + + // ----------------------------------------------------------------------------- // Miscellaneous diff --git a/deps/v8/test/unittests/compiler/coalesced-live-ranges-unittest.cc b/deps/v8/test/unittests/compiler/coalesced-live-ranges-unittest.cc new file mode 100644 index 0000000000..ea9ebdb20b --- /dev/null +++ b/deps/v8/test/unittests/compiler/coalesced-live-ranges-unittest.cc @@ -0,0 +1,309 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/compiler/coalesced-live-ranges.h" +#include "test/unittests/test-utils.h" + +namespace v8 { +namespace internal { +namespace compiler { + + +// Utility offering shorthand syntax for building up a range by providing its ID +// and pairs (start, end) specifying intervals. Circumvents current incomplete +// support for C++ features such as instantiation lists, on OS X and Android. +class TestRangeBuilder { + public: + explicit TestRangeBuilder(Zone* zone) : id_(-1), pairs_(), zone_(zone) {} + + TestRangeBuilder& Id(int id) { + id_ = id; + return *this; + } + TestRangeBuilder& Add(int start, int end) { + pairs_.push_back({start, end}); + return *this; + } + + LiveRange* Build(int start, int end) { return Add(start, end).Build(); } + + LiveRange* Build() { + LiveRange* range = new (zone_) LiveRange(id_, MachineType::kRepTagged); + // Traverse the provided interval specifications backwards, because that is + // what LiveRange expects. + for (int i = static_cast<int>(pairs_.size()) - 1; i >= 0; --i) { + Interval pair = pairs_[i]; + LifetimePosition start = LifetimePosition::FromInt(pair.first); + LifetimePosition end = LifetimePosition::FromInt(pair.second); + CHECK(start < end); + range->AddUseInterval(start, end, zone_); + } + + pairs_.clear(); + return range; + } + + private: + typedef std::pair<int, int> Interval; + typedef std::vector<Interval> IntervalList; + int id_; + IntervalList pairs_; + Zone* zone_; +}; + + +class CoalescedLiveRangesTest : public TestWithZone { + public: + CoalescedLiveRangesTest() : TestWithZone(), ranges_(zone()) {} + bool HasNoConflicts(const LiveRange* range); + bool ConflictsPreciselyWith(const LiveRange* range, int id); + bool ConflictsPreciselyWith(const LiveRange* range, int id1, int id2); + + CoalescedLiveRanges& ranges() { return ranges_; } + const CoalescedLiveRanges& ranges() const { return ranges_; } + bool AllocationsAreValid() const; + void RemoveConflicts(LiveRange* range); + + private: + typedef ZoneSet<int> LiveRangeIDs; + bool IsRangeConflictingWith(const LiveRange* range, const LiveRangeIDs& ids); + CoalescedLiveRanges ranges_; +}; + + +bool CoalescedLiveRangesTest::ConflictsPreciselyWith(const LiveRange* range, + int id) { + LiveRangeIDs set(zone()); + set.insert(id); + return IsRangeConflictingWith(range, set); +} + + +bool CoalescedLiveRangesTest::ConflictsPreciselyWith(const LiveRange* range, + int id1, int id2) { + LiveRangeIDs set(zone()); + set.insert(id1); + set.insert(id2); + return IsRangeConflictingWith(range, set); +} + + +bool CoalescedLiveRangesTest::HasNoConflicts(const LiveRange* range) { + LiveRangeIDs set(zone()); + return IsRangeConflictingWith(range, set); +} + + +void CoalescedLiveRangesTest::RemoveConflicts(LiveRange* range) { + auto conflicts = ranges().GetConflicts(range); + LiveRangeIDs seen(zone()); + for (auto c = conflicts.Current(); c != nullptr; + c = conflicts.RemoveCurrentAndGetNext()) { + EXPECT_FALSE(seen.count(c->id()) > 0); + seen.insert(c->id()); + } +} + + +bool CoalescedLiveRangesTest::AllocationsAreValid() const { + return ranges().VerifyAllocationsAreValidForTesting(); +} + + +bool CoalescedLiveRangesTest::IsRangeConflictingWith(const LiveRange* range, + const LiveRangeIDs& ids) { + LiveRangeIDs found_ids(zone()); + + auto conflicts = ranges().GetConflicts(range); + for (auto conflict = conflicts.Current(); conflict != nullptr; + conflict = conflicts.GetNext()) { + found_ids.insert(conflict->id()); + } + return found_ids == ids; +} + + +TEST_F(CoalescedLiveRangesTest, VisitEmptyAllocations) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5); + ASSERT_TRUE(ranges().empty()); + ASSERT_TRUE(AllocationsAreValid()); + ASSERT_TRUE(HasNoConflicts(range)); +} + + +TEST_F(CoalescedLiveRangesTest, CandidateBeforeAfterAllocations) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(5, 6); + ranges().AllocateRange(range); + ASSERT_FALSE(ranges().empty()); + ASSERT_TRUE(AllocationsAreValid()); + LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(1, 2); + ASSERT_TRUE(HasNoConflicts(query)); + query = TestRangeBuilder(zone()).Id(3).Build(1, 5); + ASSERT_TRUE(HasNoConflicts(query)); +} + + +TEST_F(CoalescedLiveRangesTest, CandidateBeforeAfterManyAllocations) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(5, 7).Add(10, 12).Build(); + ranges().AllocateRange(range); + ASSERT_FALSE(ranges().empty()); + ASSERT_TRUE(AllocationsAreValid()); + LiveRange* query = + TestRangeBuilder(zone()).Id(2).Add(1, 2).Add(13, 15).Build(); + ASSERT_TRUE(HasNoConflicts(query)); + query = TestRangeBuilder(zone()).Id(3).Add(1, 5).Add(12, 15).Build(); + ASSERT_TRUE(HasNoConflicts(query)); +} + + +TEST_F(CoalescedLiveRangesTest, SelfConflictsPreciselyWithSelf) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5); + ranges().AllocateRange(range); + ASSERT_FALSE(ranges().empty()); + ASSERT_TRUE(AllocationsAreValid()); + ASSERT_TRUE(ConflictsPreciselyWith(range, 1)); + range = TestRangeBuilder(zone()).Id(2).Build(8, 10); + ranges().AllocateRange(range); + ASSERT_TRUE(ConflictsPreciselyWith(range, 2)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryStartsBeforeConflict) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(2, 5); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(1, 3); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1)); + range = TestRangeBuilder(zone()).Id(3).Build(8, 10); + ranges().AllocateRange(range); + query = TestRangeBuilder(zone()).Id(4).Build(6, 9); + ASSERT_TRUE(ConflictsPreciselyWith(query, 3)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryStartsInConflict) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(2, 5); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(3, 6); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1)); + range = TestRangeBuilder(zone()).Id(3).Build(8, 10); + ranges().AllocateRange(range); + query = TestRangeBuilder(zone()).Id(4).Build(9, 11); + ASSERT_TRUE(ConflictsPreciselyWith(query, 3)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryContainedInConflict) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(2, 3); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryContainsConflict) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(2, 3); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(1, 5); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryCoversManyIntervalsSameRange) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(7, 9).Add(20, 25).Build(); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(2).Build(2, 8); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryCoversManyIntervalsDifferentRanges) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(20, 25).Build(); + ranges().AllocateRange(range); + range = TestRangeBuilder(zone()).Id(2).Build(7, 10); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(2, 22); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1, 2)); +} + + +TEST_F(CoalescedLiveRangesTest, QueryFitsInGaps) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(10, 15).Add(20, 25).Build(); + ranges().AllocateRange(range); + LiveRange* query = + TestRangeBuilder(zone()).Id(3).Add(5, 10).Add(16, 19).Add(27, 30).Build(); + ASSERT_TRUE(HasNoConflicts(query)); +} + + +TEST_F(CoalescedLiveRangesTest, DeleteConflictBefore) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Add(1, 4).Add(5, 6).Build(); + ranges().AllocateRange(range); + range = TestRangeBuilder(zone()).Id(2).Build(40, 50); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(3, 7); + RemoveConflicts(query); + query = TestRangeBuilder(zone()).Id(4).Build(0, 60); + ASSERT_TRUE(ConflictsPreciselyWith(query, 2)); +} + + +TEST_F(CoalescedLiveRangesTest, DeleteConflictAfter) { + LiveRange* range = TestRangeBuilder(zone()).Id(1).Build(1, 5); + ranges().AllocateRange(range); + range = TestRangeBuilder(zone()).Id(2).Add(40, 50).Add(60, 70).Build(); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(45, 60); + RemoveConflicts(query); + query = TestRangeBuilder(zone()).Id(4).Build(0, 60); + ASSERT_TRUE(ConflictsPreciselyWith(query, 1)); +} + + +TEST_F(CoalescedLiveRangesTest, DeleteConflictStraddle) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(10, 20).Build(); + ranges().AllocateRange(range); + range = TestRangeBuilder(zone()).Id(2).Build(40, 50); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(4, 15); + RemoveConflicts(query); + query = TestRangeBuilder(zone()).Id(4).Build(0, 60); + ASSERT_TRUE(ConflictsPreciselyWith(query, 2)); +} + + +TEST_F(CoalescedLiveRangesTest, DeleteConflictManyOverlapsBefore) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(6, 10).Add(10, 20).Build(); + ranges().AllocateRange(range); + range = TestRangeBuilder(zone()).Id(2).Build(40, 50); + ranges().AllocateRange(range); + LiveRange* query = TestRangeBuilder(zone()).Id(3).Build(4, 15); + RemoveConflicts(query); + query = TestRangeBuilder(zone()).Id(4).Build(0, 60); + ASSERT_TRUE(ConflictsPreciselyWith(query, 2)); +} + + +TEST_F(CoalescedLiveRangesTest, DeleteWhenConflictRepeatsAfterNonConflict) { + LiveRange* range = + TestRangeBuilder(zone()).Id(1).Add(1, 5).Add(6, 10).Add(20, 30).Build(); + ranges().AllocateRange(range); + range = TestRangeBuilder(zone()).Id(2).Build(12, 15); + ranges().AllocateRange(range); + LiveRange* query = + TestRangeBuilder(zone()).Id(3).Add(1, 8).Add(22, 25).Build(); + RemoveConflicts(query); + query = TestRangeBuilder(zone()).Id(4).Build(0, 60); + ASSERT_TRUE(ConflictsPreciselyWith(query, 2)); +} + + +} // namespace compiler +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/compiler/compiler-test-utils.h b/deps/v8/test/unittests/compiler/compiler-test-utils.h index 6ce28f9f94..7873c961b1 100644 --- a/deps/v8/test/unittests/compiler/compiler-test-utils.h +++ b/deps/v8/test/unittests/compiler/compiler-test-utils.h @@ -14,41 +14,25 @@ namespace compiler { // The TARGET_TEST(Case, Name) macro works just like // TEST(Case, Name), except that the test is disabled // if the platform is not a supported TurboFan target. -#if V8_TURBOFAN_TARGET #define TARGET_TEST(Case, Name) TEST(Case, Name) -#else -#define TARGET_TEST(Case, Name) TEST(Case, DISABLED_##Name) -#endif // The TARGET_TEST_F(Case, Name) macro works just like // TEST_F(Case, Name), except that the test is disabled // if the platform is not a supported TurboFan target. -#if V8_TURBOFAN_TARGET #define TARGET_TEST_F(Case, Name) TEST_F(Case, Name) -#else -#define TARGET_TEST_F(Case, Name) TEST_F(Case, DISABLED_##Name) -#endif // The TARGET_TEST_P(Case, Name) macro works just like // TEST_P(Case, Name), except that the test is disabled // if the platform is not a supported TurboFan target. -#if V8_TURBOFAN_TARGET #define TARGET_TEST_P(Case, Name) TEST_P(Case, Name) -#else -#define TARGET_TEST_P(Case, Name) TEST_P(Case, DISABLED_##Name) -#endif // The TARGET_TYPED_TEST(Case, Name) macro works just like // TYPED_TEST(Case, Name), except that the test is disabled // if the platform is not a supported TurboFan target. -#if V8_TURBOFAN_TARGET #define TARGET_TYPED_TEST(Case, Name) TYPED_TEST(Case, Name) -#else -#define TARGET_TYPED_TEST(Case, Name) TYPED_TEST(Case, DISABLED_##Name) -#endif } // namespace compiler } // namespace internal diff --git a/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc b/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc index acab91b009..1636b7ee5b 100644 --- a/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc +++ b/deps/v8/test/unittests/compiler/instruction-selector-unittest.cc @@ -153,7 +153,7 @@ InstructionSelectorTest::StreamBuilder::GetFrameStateFunctionInfo( int parameter_count, int local_count) { return common()->CreateFrameStateFunctionInfo( FrameStateType::kJavaScriptFunction, parameter_count, local_count, - Handle<SharedFunctionInfo>()); + Handle<SharedFunctionInfo>(), CALL_MAINTAINS_NATIVE_CONTEXT); } diff --git a/deps/v8/test/unittests/compiler/instruction-selector-unittest.h b/deps/v8/test/unittests/compiler/instruction-selector-unittest.h index 15d3b2005f..574864edf5 100644 --- a/deps/v8/test/unittests/compiler/instruction-selector-unittest.h +++ b/deps/v8/test/unittests/compiler/instruction-selector-unittest.h @@ -39,22 +39,22 @@ class InstructionSelectorTest : public TestWithContext, StreamBuilder(InstructionSelectorTest* test, MachineType return_type) : RawMachineAssembler( test->isolate(), new (test->zone()) Graph(test->zone()), - MakeMachineSignature(test->zone(), return_type), kMachPtr, + MakeCallDescriptor(test->zone(), return_type), kMachPtr, MachineOperatorBuilder::kAllOptionalOps), test_(test) {} StreamBuilder(InstructionSelectorTest* test, MachineType return_type, MachineType parameter0_type) : RawMachineAssembler( test->isolate(), new (test->zone()) Graph(test->zone()), - MakeMachineSignature(test->zone(), return_type, parameter0_type), + MakeCallDescriptor(test->zone(), return_type, parameter0_type), kMachPtr, MachineOperatorBuilder::kAllOptionalOps), test_(test) {} StreamBuilder(InstructionSelectorTest* test, MachineType return_type, MachineType parameter0_type, MachineType parameter1_type) : RawMachineAssembler( test->isolate(), new (test->zone()) Graph(test->zone()), - MakeMachineSignature(test->zone(), return_type, parameter0_type, - parameter1_type), + MakeCallDescriptor(test->zone(), return_type, parameter0_type, + parameter1_type), kMachPtr, MachineOperatorBuilder::kAllOptionalOps), test_(test) {} StreamBuilder(InstructionSelectorTest* test, MachineType return_type, @@ -62,8 +62,8 @@ class InstructionSelectorTest : public TestWithContext, MachineType parameter2_type) : RawMachineAssembler( test->isolate(), new (test->zone()) Graph(test->zone()), - MakeMachineSignature(test->zone(), return_type, parameter0_type, - parameter1_type, parameter2_type), + MakeCallDescriptor(test->zone(), return_type, parameter0_type, + parameter1_type, parameter2_type), kMachPtr, MachineOperatorBuilder::kAllOptionalOps), test_(test) {} @@ -85,41 +85,40 @@ class InstructionSelectorTest : public TestWithContext, int local_count); private: - MachineSignature* MakeMachineSignature(Zone* zone, - MachineType return_type) { + CallDescriptor* MakeCallDescriptor(Zone* zone, MachineType return_type) { MachineSignature::Builder builder(zone, 1, 0); builder.AddReturn(return_type); - return builder.Build(); + return Linkage::GetSimplifiedCDescriptor(zone, builder.Build()); } - MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type, - MachineType parameter0_type) { + CallDescriptor* MakeCallDescriptor(Zone* zone, MachineType return_type, + MachineType parameter0_type) { MachineSignature::Builder builder(zone, 1, 1); builder.AddReturn(return_type); builder.AddParam(parameter0_type); - return builder.Build(); + return Linkage::GetSimplifiedCDescriptor(zone, builder.Build()); } - MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type, - MachineType parameter0_type, - MachineType parameter1_type) { + CallDescriptor* MakeCallDescriptor(Zone* zone, MachineType return_type, + MachineType parameter0_type, + MachineType parameter1_type) { MachineSignature::Builder builder(zone, 1, 2); builder.AddReturn(return_type); builder.AddParam(parameter0_type); builder.AddParam(parameter1_type); - return builder.Build(); + return Linkage::GetSimplifiedCDescriptor(zone, builder.Build()); } - MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type, - MachineType parameter0_type, - MachineType parameter1_type, - MachineType parameter2_type) { + CallDescriptor* MakeCallDescriptor(Zone* zone, MachineType return_type, + MachineType parameter0_type, + MachineType parameter1_type, + MachineType parameter2_type) { MachineSignature::Builder builder(zone, 1, 3); builder.AddReturn(return_type); builder.AddParam(parameter0_type); builder.AddParam(parameter1_type); builder.AddParam(parameter2_type); - return builder.Build(); + return Linkage::GetSimplifiedCDescriptor(zone, builder.Build()); } private: diff --git a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc index 1ff441f746..65a7f299c5 100644 --- a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc +++ b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.cc @@ -93,9 +93,9 @@ void InstructionSequenceTest::EndLoop() { } -void InstructionSequenceTest::StartBlock() { +void InstructionSequenceTest::StartBlock(bool deferred) { block_returns_ = false; - NewBlock(); + NewBlock(deferred); } @@ -408,7 +408,7 @@ InstructionOperand InstructionSequenceTest::ConvertOutputOp(VReg vreg, } -InstructionBlock* InstructionSequenceTest::NewBlock() { +InstructionBlock* InstructionSequenceTest::NewBlock(bool deferred) { CHECK(current_block_ == nullptr); Rpo rpo = Rpo::FromInt(static_cast<int>(instruction_blocks_.size())); Rpo loop_header = Rpo::Invalid(); @@ -430,7 +430,7 @@ InstructionBlock* InstructionSequenceTest::NewBlock() { } // Construct instruction block. auto instruction_block = new (zone()) - InstructionBlock(zone(), rpo, loop_header, loop_end, false, false); + InstructionBlock(zone(), rpo, loop_header, loop_end, deferred, false); instruction_blocks_.push_back(instruction_block); current_block_ = instruction_block; sequence()->StartBlock(rpo); diff --git a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h index 2d75da7e47..54317ede21 100644 --- a/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h +++ b/deps/v8/test/unittests/compiler/instruction-sequence-unittest.h @@ -126,7 +126,7 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { void StartLoop(int loop_blocks); void EndLoop(); - void StartBlock(); + void StartBlock(bool deferred = false); Instruction* EndBlock(BlockCompletion completion = FallThrough()); TestOperand Imm(int32_t imm = 0); @@ -203,7 +203,7 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { InstructionOperand* ConvertInputs(size_t input_size, TestOperand* inputs); InstructionOperand ConvertInputOp(TestOperand op); InstructionOperand ConvertOutputOp(VReg vreg, TestOperand op); - InstructionBlock* NewBlock(); + InstructionBlock* NewBlock(bool deferred = false); void WireBlock(size_t block_offset, int jump_offset); Instruction* Emit(InstructionCode code, size_t outputs_size = 0, @@ -223,7 +223,7 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { typedef std::map<int, const Instruction*> Instructions; typedef std::vector<BlockCompletion> Completions; - SmartPointer<RegisterConfiguration> config_; + base::SmartPointer<RegisterConfiguration> config_; InstructionSequence* sequence_; int num_general_registers_; int num_double_registers_; diff --git a/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc new file mode 100644 index 0000000000..a869f7ebb1 --- /dev/null +++ b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.cc @@ -0,0 +1,262 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "test/unittests/compiler/interpreter-assembler-unittest.h" + +#include "src/compiler/graph.h" +#include "src/compiler/node.h" +#include "src/unique.h" +#include "test/unittests/compiler/compiler-test-utils.h" +#include "test/unittests/compiler/node-test-utils.h" + +using ::testing::_; + +namespace v8 { +namespace internal { +namespace compiler { + +const interpreter::Bytecode kBytecodes[] = { +#define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name, + BYTECODE_LIST(DEFINE_BYTECODE) +#undef DEFINE_BYTECODE +}; + + +Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher) { + return kPointerSize == 8 ? IsInt64Add(lhs_matcher, rhs_matcher) + : IsInt32Add(lhs_matcher, rhs_matcher); +} + + +Matcher<Node*> IsIntPtrSub(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher) { + return kPointerSize == 8 ? IsInt64Sub(lhs_matcher, rhs_matcher) + : IsInt32Sub(lhs_matcher, rhs_matcher); +} + + +Matcher<Node*> IsWordShl(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher) { + return kPointerSize == 8 ? IsWord64Shl(lhs_matcher, rhs_matcher) + : IsWord32Shl(lhs_matcher, rhs_matcher); +} + + +Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher) { + return kPointerSize == 8 ? IsWord64Sar(lhs_matcher, rhs_matcher) + : IsWord32Sar(lhs_matcher, rhs_matcher); +} + + +Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsLoad( + const Matcher<LoadRepresentation>& rep_matcher, + const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher) { + return ::i::compiler::IsLoad(rep_matcher, base_matcher, index_matcher, + graph()->start(), graph()->start()); +} + + +Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore( + const Matcher<StoreRepresentation>& rep_matcher, + const Matcher<Node*>& base_matcher, const Matcher<Node*>& index_matcher, + const Matcher<Node*>& value_matcher) { + return ::i::compiler::IsStore(rep_matcher, base_matcher, index_matcher, + value_matcher, graph()->start(), + graph()->start()); +} + + +Matcher<Node*> +InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperand( + int operand) { + return IsLoad( + kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), + IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), + IsInt32Constant(1 + operand))); +} + + +Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: + IsBytecodeOperandSignExtended(int operand) { + Matcher<Node*> load_matcher = IsLoad( + kMachInt8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), + IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), + IsInt32Constant(1 + operand))); + if (kPointerSize == 8) { + load_matcher = IsChangeInt32ToInt64(load_matcher); + } + return load_matcher; +} + + +Graph* +InterpreterAssemblerTest::InterpreterAssemblerForTest::GetCompletedGraph() { + End(); + return graph(); +} + + +TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + m.Dispatch(); + Graph* graph = m.GetCompletedGraph(); + + Node* end = graph->end(); + EXPECT_EQ(1, end->InputCount()); + Node* tail_call_node = end->InputAt(0); + + Matcher<Node*> next_bytecode_offset_matcher = + IsIntPtrAdd(IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), + IsInt32Constant(interpreter::Bytecodes::Size(bytecode))); + Matcher<Node*> target_bytecode_matcher = m.IsLoad( + kMachUint8, IsParameter(Linkage::kInterpreterBytecodeArrayParameter), + next_bytecode_offset_matcher); + Matcher<Node*> code_target_matcher = m.IsLoad( + kMachPtr, IsParameter(Linkage::kInterpreterDispatchTableParameter), + IsWord32Shl(target_bytecode_matcher, + IsInt32Constant(kPointerSizeLog2))); + + EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind()); + EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots); + EXPECT_THAT( + tail_call_node, + IsTailCall(m.call_descriptor(), code_target_matcher, + IsParameter(Linkage::kInterpreterAccumulatorParameter), + IsParameter(Linkage::kInterpreterRegisterFileParameter), + next_bytecode_offset_matcher, + IsParameter(Linkage::kInterpreterBytecodeArrayParameter), + IsParameter(Linkage::kInterpreterDispatchTableParameter), + graph->start(), graph->start())); + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, Return) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + m.Return(); + Graph* graph = m.GetCompletedGraph(); + + Node* end = graph->end(); + EXPECT_EQ(1, end->InputCount()); + Node* tail_call_node = end->InputAt(0); + + EXPECT_EQ(CallDescriptor::kCallCodeObject, m.call_descriptor()->kind()); + EXPECT_TRUE(m.call_descriptor()->flags() & CallDescriptor::kCanUseRoots); + Matcher<Unique<HeapObject>> exit_trampoline( + Unique<HeapObject>::CreateImmovable( + isolate()->builtins()->InterpreterExitTrampoline())); + EXPECT_THAT( + tail_call_node, + IsTailCall(m.call_descriptor(), IsHeapConstant(exit_trampoline), + IsParameter(Linkage::kInterpreterAccumulatorParameter), + IsParameter(Linkage::kInterpreterRegisterFileParameter), + IsParameter(Linkage::kInterpreterBytecodeOffsetParameter), + IsParameter(Linkage::kInterpreterBytecodeArrayParameter), + IsParameter(Linkage::kInterpreterDispatchTableParameter), + graph->start(), graph->start())); + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode); + for (int i = 0; i < number_of_operands; i++) { + switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) { + case interpreter::OperandType::kImm8: + EXPECT_THAT(m.BytecodeOperandImm8(i), + m.IsBytecodeOperandSignExtended(i)); + break; + case interpreter::OperandType::kReg: + EXPECT_THAT(m.BytecodeOperandReg(i), + m.IsBytecodeOperandSignExtended(i)); + break; + case interpreter::OperandType::kNone: + UNREACHABLE(); + break; + } + } + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + // Should be incoming accumulator if not set. + EXPECT_THAT(m.GetAccumulator(), + IsParameter(Linkage::kInterpreterAccumulatorParameter)); + + // Should be set by SedtAccumulator. + Node* accumulator_value_1 = m.Int32Constant(0xdeadbeef); + m.SetAccumulator(accumulator_value_1); + EXPECT_THAT(m.GetAccumulator(), accumulator_value_1); + Node* accumulator_value_2 = m.Int32Constant(42); + m.SetAccumulator(accumulator_value_2); + EXPECT_THAT(m.GetAccumulator(), accumulator_value_2); + + // Should be passed to next bytecode handler on dispatch. + m.Dispatch(); + Graph* graph = m.GetCompletedGraph(); + + Node* end = graph->end(); + EXPECT_EQ(1, end->InputCount()); + Node* tail_call_node = end->InputAt(0); + + EXPECT_THAT(tail_call_node, + IsTailCall(m.call_descriptor(), _, accumulator_value_2, _, _, _, + _, graph->start(), graph->start())); + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + Node* reg_index_node = m.Int32Constant(44); + Node* load_reg_node = m.LoadRegister(reg_index_node); + EXPECT_THAT( + load_reg_node, + m.IsLoad(kMachPtr, + IsParameter(Linkage::kInterpreterRegisterFileParameter), + IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)))); + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + Node* store_value = m.Int32Constant(0xdeadbeef); + Node* reg_index_node = m.Int32Constant(44); + Node* store_reg_node = m.StoreRegister(store_value, reg_index_node); + EXPECT_THAT( + store_reg_node, + m.IsStore(StoreRepresentation(kMachPtr, kNoWriteBarrier), + IsParameter(Linkage::kInterpreterRegisterFileParameter), + IsWordShl(reg_index_node, IsInt32Constant(kPointerSizeLog2)), + store_value)); + } +} + + +TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) { + TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { + InterpreterAssemblerForTest m(this, bytecode); + Node* value = m.Int32Constant(44); + EXPECT_THAT(m.SmiTag(value), + IsWordShl(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize))); + EXPECT_THAT(m.SmiUntag(value), + IsWordSar(value, IsInt32Constant(kSmiShiftSize + kSmiTagSize))); + } +} + +} // namespace compiler +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h new file mode 100644 index 0000000000..64353ae128 --- /dev/null +++ b/deps/v8/test/unittests/compiler/interpreter-assembler-unittest.h @@ -0,0 +1,56 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_UNITTESTS_COMPILER_INTERPRETER_ASSEMBLER_UNITTEST_H_ +#define V8_UNITTESTS_COMPILER_INTERPRETER_ASSEMBLER_UNITTEST_H_ + +#include "src/compiler/interpreter-assembler.h" +#include "src/compiler/linkage.h" +#include "src/compiler/machine-operator.h" +#include "test/unittests/test-utils.h" +#include "testing/gmock-support.h" + +namespace v8 { +namespace internal { +namespace compiler { + +using ::testing::Matcher; + +class InterpreterAssemblerTest : public TestWithIsolateAndZone { + public: + InterpreterAssemblerTest() {} + ~InterpreterAssemblerTest() override {} + + class InterpreterAssemblerForTest final : public InterpreterAssembler { + public: + InterpreterAssemblerForTest(InterpreterAssemblerTest* test, + interpreter::Bytecode bytecode) + : InterpreterAssembler(test->isolate(), test->zone(), bytecode) {} + ~InterpreterAssemblerForTest() override {} + + Graph* GetCompletedGraph(); + + Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher, + const Matcher<Node*>& base_matcher, + const Matcher<Node*>& index_matcher); + Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher, + const Matcher<Node*>& base_matcher, + const Matcher<Node*>& index_matcher, + const Matcher<Node*>& value_matcher); + Matcher<Node*> IsBytecodeOperand(int operand); + Matcher<Node*> IsBytecodeOperandSignExtended(int operand); + + using InterpreterAssembler::call_descriptor; + using InterpreterAssembler::graph; + + private: + DISALLOW_COPY_AND_ASSIGN(InterpreterAssemblerForTest); + }; +}; + +} // namespace compiler +} // namespace internal +} // namespace v8 + +#endif // V8_UNITTESTS_COMPILER_INTERPRETER_ASSEMBLER_UNITTEST_H_ diff --git a/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc b/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc new file mode 100644 index 0000000000..b52417de2f --- /dev/null +++ b/deps/v8/test/unittests/compiler/js-context-relaxation-unittest.cc @@ -0,0 +1,306 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/compiler/js-context-relaxation.h" +#include "src/compiler/js-graph.h" +#include "test/unittests/compiler/graph-unittest.h" +#include "test/unittests/compiler/node-test-utils.h" + +namespace v8 { +namespace internal { +namespace compiler { + +class JSContextRelaxationTest : public GraphTest { + public: + JSContextRelaxationTest() : GraphTest(3), javascript_(zone()) {} + ~JSContextRelaxationTest() override {} + + protected: + Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags = + MachineOperatorBuilder::kNoFlags) { + MachineOperatorBuilder machine(zone(), kMachPtr, flags); + JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); + // TODO(titzer): mock the GraphReducer here for better unit testing. + GraphReducer graph_reducer(zone(), graph()); + JSContextRelaxation reducer; + return reducer.Reduce(node); + } + + Node* EmptyFrameState() { + MachineOperatorBuilder machine(zone()); + JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); + return jsgraph.EmptyFrameState(); + } + + Node* ShallowFrameStateChain(Node* outer_context, + ContextCallingMode context_calling_mode) { + const FrameStateFunctionInfo* const frame_state_function_info = + common()->CreateFrameStateFunctionInfo( + FrameStateType::kJavaScriptFunction, 3, 0, + Handle<SharedFunctionInfo>(), context_calling_mode); + const Operator* op = common()->FrameState(BailoutId::None(), + OutputFrameStateCombine::Ignore(), + frame_state_function_info); + return graph()->NewNode(op, graph()->start(), graph()->start(), + graph()->start(), outer_context, graph()->start(), + graph()->start()); + } + + Node* DeepFrameStateChain(Node* outer_context, + ContextCallingMode context_calling_mode) { + const FrameStateFunctionInfo* const frame_state_function_info = + common()->CreateFrameStateFunctionInfo( + FrameStateType::kJavaScriptFunction, 3, 0, + Handle<SharedFunctionInfo>(), context_calling_mode); + const Operator* op = common()->FrameState(BailoutId::None(), + OutputFrameStateCombine::Ignore(), + frame_state_function_info); + Node* shallow_frame_state = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + return graph()->NewNode(op, graph()->start(), graph()->start(), + graph()->start(), graph()->start(), + graph()->start(), shallow_frame_state); + } + + JSOperatorBuilder* javascript() { return &javascript_; } + + private: + JSOperatorBuilder javascript_; +}; + + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionShallowFrameStateChainNoCrossCtx) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + Node* const frame_state = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); +} + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionShallowFrameStateChainCrossCtx) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + Node* const frame_state = + ShallowFrameStateChain(outer_context, CALL_CHANGES_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state, effect, control); + Reduction const r = Reduce(node); + EXPECT_FALSE(r.Changed()); + EXPECT_EQ(context, NodeProperties::GetContextInput(node)); +} + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepFrameStateChainNoCrossCtx) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + Node* const frame_state = + DeepFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); +} + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepFrameStateChainCrossCtx) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + Node* const frame_state = + DeepFrameStateChain(outer_context, CALL_CHANGES_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state, effect, control); + Reduction const r = Reduce(node); + EXPECT_FALSE(r.Changed()); + EXPECT_EQ(context, NodeProperties::GetContextInput(node)); +} + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepContextChainFullRelaxForCatch) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + const Operator* op = javascript()->CreateCatchContext(Unique<String>()); + Node* const frame_state_1 = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* nested_context = + graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, + frame_state_1, effect, control); + Node* const frame_state_2 = + ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state_2, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); +} + + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepContextChainFullRelaxForWith) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + const Operator* op = javascript()->CreateWithContext(); + Node* const frame_state_1 = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* nested_context = + graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, + frame_state_1, effect, control); + Node* const frame_state_2 = + ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state_2, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); +} + + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepContextChainFullRelaxForBlock) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + const Operator* op = javascript()->CreateBlockContext(); + Node* const frame_state_1 = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* nested_context = + graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, + frame_state_1, effect, control); + Node* const frame_state_2 = + ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state_2, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); +} + + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepContextChainPartialRelaxForScript) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + const Operator* op = javascript()->CreateScriptContext(); + Node* const frame_state_1 = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* nested_context = + graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, + frame_state_1, effect, control); + Node* const frame_state_2 = + ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state_2, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node)); +} + + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepContextChainPartialRelaxForModule) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + const Operator* op = javascript()->CreateModuleContext(); + Node* const frame_state_1 = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* nested_context = + graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, + frame_state_1, effect, control); + Node* const frame_state_2 = + ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state_2, effect, control); + Reduction const r = Reduce(node); + EXPECT_TRUE(r.Changed()); + EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node)); +} + + +TEST_F(JSContextRelaxationTest, + RelaxJSCallFunctionDeepContextChainPartialNoRelax) { + Node* const input0 = Parameter(0); + Node* const input1 = Parameter(1); + Node* const context = Parameter(2); + Node* const outer_context = Parameter(3); + const Operator* op = javascript()->CreateFunctionContext(); + Node* const frame_state_1 = + ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + Node* nested_context = + graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, + frame_state_1, effect, control); + Node* const frame_state_2 = + ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); + Node* node = + graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, + STRICT, VectorSlotPair()), + input0, input1, context, frame_state_2, effect, control); + Reduction const r = Reduce(node); + EXPECT_FALSE(r.Changed()); + EXPECT_EQ(context, NodeProperties::GetContextInput(node)); +} + +} // namespace compiler +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc b/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc index d52242ec7d..251293ddcf 100644 --- a/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc +++ b/deps/v8/test/unittests/compiler/js-type-feedback-unittest.cc @@ -85,7 +85,7 @@ class JSTypeFeedbackTest : public TypedGraphTest { Unique<Name> name = Unique<Name>::CreateUninitialized( isolate()->factory()->InternalizeUtf8String(string)); const Operator* op = javascript()->LoadGlobal(name, feedback); - Node* load = graph()->NewNode(op, global, vector, context); + Node* load = graph()->NewNode(op, context, global, vector, context); if (mode == JSTypeFeedbackSpecializer::kDeoptimizationEnabled) { for (int i = 0; i < OperatorProperties::GetFrameStateInputCount(op); i++) { diff --git a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc index a12d79f02b..9d6cca3dbc 100644 --- a/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc +++ b/deps/v8/test/unittests/compiler/js-typed-lowering-unittest.cc @@ -874,7 +874,11 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) { } -TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) { +// ----------------------------------------------------------------------------- +// JSLoadGlobal + + +TEST_F(JSTypedLoweringTest, JSLoadGlobalConstants) { Handle<String> names[] = { Handle<String>(isolate()->heap()->undefined_string(), isolate()), Handle<String>(isolate()->heap()->infinity_string(), isolate()), @@ -897,8 +901,8 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) { for (size_t i = 0; i < arraysize(names); i++) { Unique<Name> name = Unique<Name>::CreateImmovable(names[i]); Reduction r = Reduce(graph()->NewNode( - javascript()->LoadGlobal(name, feedback), global, vector, context, - EmptyFrameState(), EmptyFrameState(), effect, control)); + javascript()->LoadGlobal(name, feedback), context, global, vector, + context, EmptyFrameState(), EmptyFrameState(), effect, control)); ASSERT_TRUE(r.Changed()); EXPECT_THAT(r.replacement(), matches[i]); @@ -907,6 +911,31 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) { // ----------------------------------------------------------------------------- +// JSLoadNamed + + +TEST_F(JSTypedLoweringTest, JSLoadNamedStringLength) { + VectorSlotPair feedback; + Unique<Name> name = Unique<Name>::CreateImmovable(factory()->length_string()); + Node* const receiver = Parameter(Type::String(), 0); + Node* const vector = Parameter(Type::Internal(), 1); + Node* const context = UndefinedConstant(); + Node* const effect = graph()->start(); + Node* const control = graph()->start(); + TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { + Reduction const r = Reduce( + graph()->NewNode(javascript()->LoadNamed(name, feedback, language_mode), + receiver, vector, context, EmptyFrameState(), + EmptyFrameState(), effect, control)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), + IsLoadField(AccessBuilder::ForStringLength(zone()), receiver, + effect, control)); + } +} + + +// ----------------------------------------------------------------------------- // JSLoadDynamicGlobal @@ -921,7 +950,8 @@ TEST_F(JSTypedLoweringTest, JSLoadDynamicGlobal) { for (int i = 0; i < DynamicGlobalAccess::kMaxCheckDepth; ++i) { uint32_t bitset = 1 << i; // Only single check. Reduction r = Reduce(graph()->NewNode( - javascript()->LoadDynamicGlobal(name, bitset, feedback, NOT_CONTEXTUAL), + javascript()->LoadDynamicGlobal(name, bitset, feedback, + NOT_INSIDE_TYPEOF), vector, context, context, frame_state, frame_state, effect, control)); ASSERT_TRUE(r.Changed()); EXPECT_THAT( @@ -974,7 +1004,6 @@ TEST_F(JSTypedLoweringTest, JSLoadDynamicContext) { } } -#if V8_TURBOFAN_TARGET // ----------------------------------------------------------------------------- // JSAdd @@ -1074,8 +1103,6 @@ TEST_F(JSTypedLoweringTest, JSCreateLiteralObject) { input0, input1, input2, _, context, frame_state, effect, control)); } -#endif // V8_TURBOFAN_TARGET - // ----------------------------------------------------------------------------- // JSCreateWithContext diff --git a/deps/v8/test/unittests/compiler/linkage-tail-call-unittest.cc b/deps/v8/test/unittests/compiler/linkage-tail-call-unittest.cc new file mode 100644 index 0000000000..5d24a3bd1d --- /dev/null +++ b/deps/v8/test/unittests/compiler/linkage-tail-call-unittest.cc @@ -0,0 +1,324 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/compiler/common-operator.h" +#include "src/compiler/graph.h" +#include "src/compiler/linkage.h" +#include "src/compiler/node.h" +#include "test/unittests/test-utils.h" + +namespace v8 { +namespace internal { +namespace compiler { + +namespace { + +MachineType kMachineTypes[] = {kMachAnyTagged, kMachAnyTagged, kMachAnyTagged, + kMachAnyTagged, kMachAnyTagged, kMachAnyTagged, + kMachAnyTagged, kMachAnyTagged}; +} + +class LinkageTailCall : public TestWithZone { + protected: + CallDescriptor* NewStandardCallDescriptor(LocationSignature* locations) { + DCHECK(arraysize(kMachineTypes) >= + locations->return_count() + locations->parameter_count()); + MachineSignature* types = new (zone()) MachineSignature( + locations->return_count(), locations->parameter_count(), kMachineTypes); + return new (zone()) + CallDescriptor(CallDescriptor::kCallCodeObject, kMachAnyTagged, + LinkageLocation::ForAnyRegister(), + types, // machine_sig + locations, // location_sig + 0, // js_parameter_count + Operator::kNoProperties, // properties + 0, // callee-saved + 0, // callee-saved fp + CallDescriptor::kNoFlags, // flags, + ""); + } + + LinkageLocation StackLocation(int loc) { + return LinkageLocation::ForCallerFrameSlot(-loc); + } + + LinkageLocation RegisterLocation(int loc) { + return LinkageLocation::ForRegister(loc); + } +}; + + +TEST_F(LinkageTailCall, EmptyToEmpty) { + LocationSignature locations(0, 0, nullptr); + CallDescriptor* desc = NewStandardCallDescriptor(&locations); + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_TRUE(desc->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, SameReturn) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0)}; + LocationSignature locations1(1, 0, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Callee + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1); + + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc2); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_TRUE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, DifferingReturn) { + // Caller + LinkageLocation location_array1[] = {RegisterLocation(0)}; + LocationSignature locations1(1, 0, location_array1); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Callee + LinkageLocation location_array2[] = {RegisterLocation(1)}; + LocationSignature locations2(1, 0, location_array2); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc2); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_FALSE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MoreRegisterParametersCallee) { + // Caller + LinkageLocation location_array1[] = {RegisterLocation(0)}; + LocationSignature locations1(1, 0, location_array1); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Callee + LinkageLocation location_array2[] = {RegisterLocation(0), + RegisterLocation(0)}; + LocationSignature locations2(1, 1, location_array2); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc2); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_TRUE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MoreRegisterParametersCaller) { + // Caller + LinkageLocation location_array1[] = {RegisterLocation(0), + RegisterLocation(0)}; + LocationSignature locations1(1, 1, location_array1); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Callee + LinkageLocation location_array2[] = {RegisterLocation(0)}; + LocationSignature locations2(1, 0, location_array2); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc2); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_TRUE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MoreRegisterAndStackParametersCallee) { + // Caller + LinkageLocation location_array1[] = {RegisterLocation(0)}; + LocationSignature locations1(1, 0, location_array1); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Callee + LinkageLocation location_array2[] = {RegisterLocation(0), RegisterLocation(0), + RegisterLocation(1), StackLocation(1)}; + LocationSignature locations2(1, 3, location_array2); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc2); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_FALSE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MoreRegisterAndStackParametersCaller) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), RegisterLocation(0), + RegisterLocation(1), StackLocation(1)}; + LocationSignature locations1(1, 3, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Callee + LinkageLocation location_array2[] = {RegisterLocation(0)}; + LocationSignature locations2(1, 0, location_array2); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + const Operator* op = common.Call(desc2); + Node* const node = Node::New(zone(), 1, op, 0, nullptr, false); + EXPECT_FALSE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MatchingStackParameters) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3), + StackLocation(2), StackLocation(1)}; + LocationSignature locations1(1, 3, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Caller + LocationSignature locations2(1, 3, location_array); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1); + + CommonOperatorBuilder common(zone()); + Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false); + Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false); + Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false); + Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false); + Node* parameters[] = {p0, p1, p2, p3}; + const Operator* op = common.Call(desc2); + Node* const node = + Node::New(zone(), 1, op, arraysize(parameters), parameters, false); + EXPECT_TRUE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, NonMatchingStackParameters) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3), + StackLocation(2), StackLocation(1)}; + LocationSignature locations1(1, 3, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Caller + LocationSignature locations2(1, 3, location_array); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1); + + CommonOperatorBuilder common(zone()); + Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false); + Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false); + Node* p2 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false); + Node* p3 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false); + Node* parameters[] = {p0, p1, p2, p3}; + const Operator* op = common.Call(desc2); + Node* const node = + Node::New(zone(), 1, op, arraysize(parameters), parameters, false); + EXPECT_FALSE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MatchingStackParametersExtraCallerRegisters) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3), + StackLocation(2), StackLocation(1), + RegisterLocation(0), RegisterLocation(1)}; + LocationSignature locations1(1, 5, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Caller + LocationSignature locations2(1, 3, location_array); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1); + + CommonOperatorBuilder common(zone()); + Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false); + Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false); + Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false); + Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false); + Node* parameters[] = {p0, p1, p2, p3}; + const Operator* op = common.Call(desc2); + Node* const node = + Node::New(zone(), 1, op, arraysize(parameters), parameters, false); + EXPECT_TRUE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MatchingStackParametersExtraCalleeRegisters) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3), + StackLocation(2), StackLocation(1), + RegisterLocation(0), RegisterLocation(1)}; + LocationSignature locations1(1, 3, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Caller + LocationSignature locations2(1, 5, location_array); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations1); + + CommonOperatorBuilder common(zone()); + Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false); + Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false); + Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false); + Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false); + Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false); + Node* parameters[] = {p0, p1, p2, p3, p4}; + const Operator* op = common.Call(desc2); + Node* const node = + Node::New(zone(), 1, op, arraysize(parameters), parameters, false); + EXPECT_TRUE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MatchingStackParametersExtraCallerRegistersAndStack) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3), + StackLocation(2), StackLocation(1), + RegisterLocation(0), StackLocation(4)}; + LocationSignature locations1(1, 5, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Caller + LocationSignature locations2(1, 3, location_array); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false); + Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false); + Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false); + Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false); + Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false); + Node* parameters[] = {p0, p1, p2, p3, p4}; + const Operator* op = common.Call(desc2); + Node* const node = + Node::New(zone(), 1, op, arraysize(parameters), parameters, false); + EXPECT_FALSE(desc1->CanTailCall(node)); +} + + +TEST_F(LinkageTailCall, MatchingStackParametersExtraCalleeRegistersAndStack) { + // Caller + LinkageLocation location_array[] = {RegisterLocation(0), StackLocation(3), + StackLocation(2), RegisterLocation(0), + RegisterLocation(1), StackLocation(4)}; + LocationSignature locations1(1, 3, location_array); + CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1); + + // Caller + LocationSignature locations2(1, 5, location_array); + CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2); + + CommonOperatorBuilder common(zone()); + Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false); + Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false); + Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false); + Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false); + Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false); + Node* parameters[] = {p0, p1, p2, p3, p4}; + const Operator* op = common.Call(desc2); + Node* const node = + Node::New(zone(), 1, op, arraysize(parameters), parameters, false); + EXPECT_FALSE(desc1->CanTailCall(node)); +} + +} // namespace compiler +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc b/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc index 1e142550d5..3c94c25887 100644 --- a/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc +++ b/deps/v8/test/unittests/compiler/liveness-analyzer-unittest.cc @@ -60,7 +60,7 @@ class LivenessAnalysisTest : public GraphTest { const FrameStateFunctionInfo* state_info = common()->CreateFrameStateFunctionInfo( FrameStateType::kJavaScriptFunction, 0, locals_count_, - Handle<SharedFunctionInfo>()); + Handle<SharedFunctionInfo>(), CALL_MAINTAINS_NATIVE_CONTEXT); const Operator* op = common()->FrameState( BailoutId(ast_num), OutputFrameStateCombine::Ignore(), state_info); diff --git a/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc b/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc index ce11fdef81..b14e9d392d 100644 --- a/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc +++ b/deps/v8/test/unittests/compiler/machine-operator-reducer-unittest.cc @@ -1438,6 +1438,55 @@ TEST_F(MachineOperatorReducerTest, Float64InsertHighWord32WithConstant) { // ----------------------------------------------------------------------------- +// Float64Equal + + +TEST_F(MachineOperatorReducerTest, Float64EqualWithFloat32Conversions) { + Node* const p0 = Parameter(0); + Node* const p1 = Parameter(1); + Reduction const r = Reduce(graph()->NewNode( + machine()->Float64Equal(), + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0), + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1))); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsFloat32Equal(p0, p1)); +} + + +// ----------------------------------------------------------------------------- +// Float64LessThan + + +TEST_F(MachineOperatorReducerTest, Float64LessThanWithFloat32Conversions) { + Node* const p0 = Parameter(0); + Node* const p1 = Parameter(1); + Reduction const r = Reduce(graph()->NewNode( + machine()->Float64LessThan(), + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0), + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1))); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsFloat32LessThan(p0, p1)); +} + + +// ----------------------------------------------------------------------------- +// Float64LessThanOrEqual + + +TEST_F(MachineOperatorReducerTest, + Float64LessThanOrEqualWithFloat32Conversions) { + Node* const p0 = Parameter(0); + Node* const p1 = Parameter(1); + Reduction const r = Reduce(graph()->NewNode( + machine()->Float64LessThanOrEqual(), + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p0), + graph()->NewNode(machine()->ChangeFloat32ToFloat64(), p1))); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsFloat32LessThanOrEqual(p0, p1)); +} + + +// ----------------------------------------------------------------------------- // Store diff --git a/deps/v8/test/unittests/compiler/node-test-utils.cc b/deps/v8/test/unittests/compiler/node-test-utils.cc index 520ce0159e..d097ee4b66 100644 --- a/deps/v8/test/unittests/compiler/node-test-utils.cc +++ b/deps/v8/test/unittests/compiler/node-test-utils.cc @@ -7,6 +7,7 @@ #include <vector> #include "src/assembler.h" +#include "src/compiler/common-operator.h" #include "src/compiler/js-operator.h" #include "src/compiler/node-properties.h" #include "src/compiler/simplified-operator.h" @@ -1375,6 +1376,27 @@ class IsUnopMatcher final : public NodeMatcher { const Matcher<Node*> input_matcher_; }; +class IsParameterMatcher final : public NodeMatcher { + public: + explicit IsParameterMatcher(const Matcher<int>& index_matcher) + : NodeMatcher(IrOpcode::kParameter), index_matcher_(index_matcher) {} + + void DescribeTo(std::ostream* os) const override { + *os << "is a Parameter node with index("; + index_matcher_.DescribeTo(os); + *os << ")"; + } + + bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { + return (NodeMatcher::MatchAndExplain(node, listener) && + PrintMatchAndExplain(ParameterIndexOf(node->op()), "index", + index_matcher_, listener)); + } + + private: + const Matcher<int> index_matcher_; +}; + } // namespace @@ -1678,6 +1700,72 @@ Matcher<Node*> IsTailCall( } +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher) { + std::vector<Matcher<Node*>> value_matchers; + value_matchers.push_back(value0_matcher); + value_matchers.push_back(value1_matcher); + value_matchers.push_back(value2_matcher); + return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, + effect_matcher, control_matcher)); +} + + +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, + const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher) { + std::vector<Matcher<Node*>> value_matchers; + value_matchers.push_back(value0_matcher); + value_matchers.push_back(value1_matcher); + value_matchers.push_back(value2_matcher); + value_matchers.push_back(value3_matcher); + return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, + effect_matcher, control_matcher)); +} + + +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, + const Matcher<Node*>& value4_matcher, const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher) { + std::vector<Matcher<Node*>> value_matchers; + value_matchers.push_back(value0_matcher); + value_matchers.push_back(value1_matcher); + value_matchers.push_back(value2_matcher); + value_matchers.push_back(value3_matcher); + value_matchers.push_back(value4_matcher); + return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, + effect_matcher, control_matcher)); +} + + +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, + const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher, + const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher) { + std::vector<Matcher<Node*>> value_matchers; + value_matchers.push_back(value0_matcher); + value_matchers.push_back(value1_matcher); + value_matchers.push_back(value2_matcher); + value_matchers.push_back(value3_matcher); + value_matchers.push_back(value4_matcher); + value_matchers.push_back(value5_matcher); + return MakeMatcher(new IsTailCallMatcher(descriptor_matcher, value_matchers, + effect_matcher, control_matcher)); +} + + Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher, const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher) { @@ -1799,6 +1887,16 @@ Matcher<Node*> IsLoadContext(const Matcher<ContextAccess>& access_matcher, } +Matcher<Node*> IsParameter(const Matcher<int> index_matcher) { + return MakeMatcher(new IsParameterMatcher(index_matcher)); +} + + +Matcher<Node*> IsLoadFramePointer() { + return MakeMatcher(new NodeMatcher(IrOpcode::kLoadFramePointer)); +} + + #define IS_BINOP_MATCHER(Name) \ Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher, \ const Matcher<Node*>& rhs_matcher) { \ @@ -1830,8 +1928,13 @@ IS_BINOP_MATCHER(Int32MulHigh) IS_BINOP_MATCHER(Int32LessThan) IS_BINOP_MATCHER(Uint32LessThan) IS_BINOP_MATCHER(Uint32LessThanOrEqual) +IS_BINOP_MATCHER(Int64Add) +IS_BINOP_MATCHER(Int64Sub) IS_BINOP_MATCHER(Float32Max) IS_BINOP_MATCHER(Float32Min) +IS_BINOP_MATCHER(Float32Equal) +IS_BINOP_MATCHER(Float32LessThan) +IS_BINOP_MATCHER(Float32LessThanOrEqual) IS_BINOP_MATCHER(Float64Max) IS_BINOP_MATCHER(Float64Min) IS_BINOP_MATCHER(Float64Sub) diff --git a/deps/v8/test/unittests/compiler/node-test-utils.h b/deps/v8/test/unittests/compiler/node-test-utils.h index a64d9f009a..149dcfc439 100644 --- a/deps/v8/test/unittests/compiler/node-test-utils.h +++ b/deps/v8/test/unittests/compiler/node-test-utils.h @@ -134,6 +134,31 @@ Matcher<Node*> IsTailCall( const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, const Matcher<Node*>& effect_matcher, const Matcher<Node*>& control_matcher); +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher); +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, + const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher); +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, + const Matcher<Node*>& value4_matcher, const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher); +Matcher<Node*> IsTailCall( + const Matcher<CallDescriptor const*>& descriptor_matcher, + const Matcher<Node*>& value0_matcher, const Matcher<Node*>& value1_matcher, + const Matcher<Node*>& value2_matcher, const Matcher<Node*>& value3_matcher, + const Matcher<Node*>& value4_matcher, const Matcher<Node*>& value5_matcher, + const Matcher<Node*>& effect_matcher, + const Matcher<Node*>& control_matcher); + Matcher<Node*> IsBooleanNot(const Matcher<Node*>& value_matcher); Matcher<Node*> IsReferenceEqual(const Matcher<Type*>& type_matcher, @@ -240,6 +265,10 @@ Matcher<Node*> IsUint32LessThan(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsUint32LessThanOrEqual(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); +Matcher<Node*> IsInt64Add(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); +Matcher<Node*> IsInt64Sub(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsChangeFloat64ToInt32(const Matcher<Node*>& input_matcher); Matcher<Node*> IsChangeFloat64ToUint32(const Matcher<Node*>& input_matcher); Matcher<Node*> IsChangeInt32ToFloat64(const Matcher<Node*>& input_matcher); @@ -254,6 +283,12 @@ Matcher<Node*> IsFloat32Max(const Matcher<Node*>& lhs_matcher, Matcher<Node*> IsFloat32Min(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsFloat32Abs(const Matcher<Node*>& input_matcher); +Matcher<Node*> IsFloat32Equal(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); +Matcher<Node*> IsFloat32LessThan(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); +Matcher<Node*> IsFloat32LessThanOrEqual(const Matcher<Node*>& lhs_matcher, + const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsFloat64Max(const Matcher<Node*>& lhs_matcher, const Matcher<Node*>& rhs_matcher); Matcher<Node*> IsFloat64Min(const Matcher<Node*>& lhs_matcher, @@ -279,6 +314,8 @@ Matcher<Node*> IsLoadContext(const Matcher<ContextAccess>& access_matcher, const Matcher<Node*>& context_matcher); Matcher<Node*> IsNumberToInt32(const Matcher<Node*>& input_matcher); Matcher<Node*> IsNumberToUint32(const Matcher<Node*>& input_matcher); +Matcher<Node*> IsParameter(const Matcher<int> index_matcher); +Matcher<Node*> IsLoadFramePointer(); } // namespace compiler } // namespace internal diff --git a/deps/v8/test/unittests/compiler/ppc/OWNERS b/deps/v8/test/unittests/compiler/ppc/OWNERS index a04d29a94f..eb007cb908 100644 --- a/deps/v8/test/unittests/compiler/ppc/OWNERS +++ b/deps/v8/test/unittests/compiler/ppc/OWNERS @@ -1,3 +1,4 @@ +jyan@ca.ibm.com dstence@us.ibm.com joransiu@ca.ibm.com mbrandy@us.ibm.com diff --git a/deps/v8/test/unittests/compiler/register-allocator-unittest.cc b/deps/v8/test/unittests/compiler/register-allocator-unittest.cc index 873b4ecd2a..23a118b6ad 100644 --- a/deps/v8/test/unittests/compiler/register-allocator-unittest.cc +++ b/deps/v8/test/unittests/compiler/register-allocator-unittest.cc @@ -9,6 +9,75 @@ namespace v8 { namespace internal { namespace compiler { + +namespace { + +// We can't just use the size of the moves collection, because of +// redundant moves which need to be discounted. +int GetMoveCount(const ParallelMove& moves) { + int move_count = 0; + for (auto move : moves) { + if (move->IsEliminated() || move->IsRedundant()) continue; + ++move_count; + } + return move_count; +} + + +bool AreOperandsOfSameType( + const AllocatedOperand& op, + const InstructionSequenceTest::TestOperand& test_op) { + bool test_op_is_reg = + (test_op.type_ == + InstructionSequenceTest::TestOperandType::kFixedRegister || + test_op.type_ == InstructionSequenceTest::TestOperandType::kRegister); + + return (op.IsRegister() && test_op_is_reg) || + (op.IsStackSlot() && !test_op_is_reg); +} + + +bool AllocatedOperandMatches( + const AllocatedOperand& op, + const InstructionSequenceTest::TestOperand& test_op) { + return AreOperandsOfSameType(op, test_op) && + (op.index() == test_op.value_ || + test_op.value_ == InstructionSequenceTest::kNoValue); +} + + +int GetParallelMoveCount(int instr_index, Instruction::GapPosition gap_pos, + const InstructionSequence* sequence) { + const ParallelMove* moves = + sequence->InstructionAt(instr_index)->GetParallelMove(gap_pos); + if (moves == nullptr) return 0; + return GetMoveCount(*moves); +} + + +bool IsParallelMovePresent(int instr_index, Instruction::GapPosition gap_pos, + const InstructionSequence* sequence, + const InstructionSequenceTest::TestOperand& src, + const InstructionSequenceTest::TestOperand& dest) { + const ParallelMove* moves = + sequence->InstructionAt(instr_index)->GetParallelMove(gap_pos); + EXPECT_NE(nullptr, moves); + + bool found_match = false; + for (auto move : *moves) { + if (move->IsEliminated() || move->IsRedundant()) continue; + if (AllocatedOperandMatches(AllocatedOperand::cast(move->source()), src) && + AllocatedOperandMatches(AllocatedOperand::cast(move->destination()), + dest)) { + found_match = true; + break; + } + } + return found_match; +} +} + + class RegisterAllocatorTest : public InstructionSequenceTest { public: void Allocate() { @@ -492,6 +561,144 @@ TEST_F(RegisterAllocatorTest, RegressionLoadConstantBeforeSpill) { } +TEST_F(RegisterAllocatorTest, DiamondWithCallFirstBlock) { + StartBlock(); + auto x = EmitOI(Reg(0)); + EndBlock(Branch(Reg(x), 1, 2)); + + StartBlock(); + EmitCall(Slot(-1)); + auto occupy = EmitOI(Reg(0)); + EndBlock(Jump(2)); + + StartBlock(); + EndBlock(FallThrough()); + + StartBlock(); + Use(occupy); + Return(Reg(x)); + EndBlock(); + Allocate(); +} + + +TEST_F(RegisterAllocatorTest, DiamondWithCallSecondBlock) { + StartBlock(); + auto x = EmitOI(Reg(0)); + EndBlock(Branch(Reg(x), 1, 2)); + + StartBlock(); + EndBlock(Jump(2)); + + StartBlock(); + EmitCall(Slot(-1)); + auto occupy = EmitOI(Reg(0)); + EndBlock(FallThrough()); + + StartBlock(); + Use(occupy); + Return(Reg(x)); + EndBlock(); + Allocate(); +} + + +TEST_F(RegisterAllocatorTest, SingleDeferredBlockSpill) { + StartBlock(); // B0 + auto var = EmitOI(Reg(0)); + EndBlock(Branch(Reg(var), 1, 2)); + + StartBlock(); // B1 + EndBlock(Jump(2)); + + StartBlock(true); // B2 + EmitCall(Slot(-1), Slot(var)); + EndBlock(); + + StartBlock(); // B3 + EmitNop(); + EndBlock(); + + StartBlock(); // B4 + Return(Reg(var, 0)); + EndBlock(); + + Allocate(); + + const int var_def_index = 1; + const int call_index = 3; + int expect_no_moves = + FLAG_turbo_preprocess_ranges ? var_def_index : call_index; + int expect_spill_move = + FLAG_turbo_preprocess_ranges ? call_index : var_def_index; + + // We should have no parallel moves at the "expect_no_moves" position. + EXPECT_EQ( + 0, GetParallelMoveCount(expect_no_moves, Instruction::START, sequence())); + + // The spill should be performed at the position expect_spill_move. + EXPECT_TRUE(IsParallelMovePresent(expect_spill_move, Instruction::START, + sequence(), Reg(0), Slot(0))); +} + + +TEST_F(RegisterAllocatorTest, MultipleDeferredBlockSpills) { + if (!FLAG_turbo_preprocess_ranges) return; + + StartBlock(); // B0 + auto var1 = EmitOI(Reg(0)); + auto var2 = EmitOI(Reg(1)); + auto var3 = EmitOI(Reg(2)); + EndBlock(Branch(Reg(var1, 0), 1, 2)); + + StartBlock(true); // B1 + EmitCall(Slot(-2), Slot(var1)); + EndBlock(Jump(2)); + + StartBlock(true); // B2 + EmitCall(Slot(-1), Slot(var2)); + EndBlock(); + + StartBlock(); // B3 + EmitNop(); + EndBlock(); + + StartBlock(); // B4 + Return(Reg(var3, 2)); + EndBlock(); + + const int def_of_v2 = 3; + const int call_in_b1 = 4; + const int call_in_b2 = 6; + const int end_of_b1 = 5; + const int end_of_b2 = 7; + const int start_of_b3 = 8; + + Allocate(); + // TODO(mtrofin): at the moment, the linear allocator spills var1 and var2, + // so only var3 is spilled in deferred blocks. Greedy avoids spilling 1&2. + // Expand the test once greedy is back online with this facility. + const int var3_reg = 2; + const int var3_slot = 2; + + EXPECT_FALSE(IsParallelMovePresent(def_of_v2, Instruction::START, sequence(), + Reg(var3_reg), Slot())); + EXPECT_TRUE(IsParallelMovePresent(call_in_b1, Instruction::START, sequence(), + Reg(var3_reg), Slot(var3_slot))); + EXPECT_TRUE(IsParallelMovePresent(end_of_b1, Instruction::START, sequence(), + Slot(var3_slot), Reg())); + + EXPECT_TRUE(IsParallelMovePresent(call_in_b2, Instruction::START, sequence(), + Reg(var3_reg), Slot(var3_slot))); + EXPECT_TRUE(IsParallelMovePresent(end_of_b2, Instruction::START, sequence(), + Slot(var3_slot), Reg())); + + + EXPECT_EQ(0, + GetParallelMoveCount(start_of_b3, Instruction::START, sequence())); +} + + namespace { enum class ParameterType { kFixedSlot, kSlot, kRegister, kFixedRegister }; diff --git a/deps/v8/test/unittests/compiler/scheduler-unittest.cc b/deps/v8/test/unittests/compiler/scheduler-unittest.cc index 45c636b27a..954541b721 100644 --- a/deps/v8/test/unittests/compiler/scheduler-unittest.cc +++ b/deps/v8/test/unittests/compiler/scheduler-unittest.cc @@ -215,7 +215,7 @@ TEST_F(SchedulerRPOTest, EntryLoop) { TEST_F(SchedulerRPOTest, EndLoop) { Schedule schedule(zone()); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); schedule.AddSuccessorForTesting(schedule.start(), loop1->header()); BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); CheckRPONumbers(order, 3, true); @@ -225,7 +225,7 @@ TEST_F(SchedulerRPOTest, EndLoop) { TEST_F(SchedulerRPOTest, EndLoopNested) { Schedule schedule(zone()); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2)); schedule.AddSuccessorForTesting(schedule.start(), loop1->header()); schedule.AddSuccessorForTesting(loop1->last(), schedule.start()); BasicBlockVector* order = Scheduler::ComputeSpecialRPO(zone(), &schedule); @@ -406,8 +406,8 @@ TEST_F(SchedulerRPOTest, LoopNest2) { TEST_F(SchedulerRPOTest, LoopFollow1) { Schedule schedule(zone()); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); - SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); + base::SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); BasicBlock* A = schedule.start(); BasicBlock* E = schedule.end(); @@ -427,8 +427,8 @@ TEST_F(SchedulerRPOTest, LoopFollow1) { TEST_F(SchedulerRPOTest, LoopFollow2) { Schedule schedule(zone()); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); - SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); + base::SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); BasicBlock* A = schedule.start(); BasicBlock* S = schedule.NewBasicBlock(); @@ -451,8 +451,8 @@ TEST_F(SchedulerRPOTest, LoopFollowN) { for (int size = 1; size < 5; size++) { for (int exit = 0; exit < size; exit++) { Schedule schedule(zone()); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); - SmartPointer<TestLoop> loop2(CreateLoop(&schedule, size)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); + base::SmartPointer<TestLoop> loop2(CreateLoop(&schedule, size)); BasicBlock* A = schedule.start(); BasicBlock* E = schedule.end(); @@ -472,8 +472,8 @@ TEST_F(SchedulerRPOTest, LoopFollowN) { TEST_F(SchedulerRPOTest, NestedLoopFollow1) { Schedule schedule(zone()); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); - SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 1)); + base::SmartPointer<TestLoop> loop2(CreateLoop(&schedule, 1)); BasicBlock* A = schedule.start(); BasicBlock* B = schedule.NewBasicBlock(); @@ -506,7 +506,7 @@ TEST_F(SchedulerRPOTest, LoopBackedges1) { BasicBlock* A = schedule.start(); BasicBlock* E = schedule.end(); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); schedule.AddSuccessorForTesting(A, loop1->header()); schedule.AddSuccessorForTesting(loop1->last(), E); @@ -530,7 +530,7 @@ TEST_F(SchedulerRPOTest, LoopOutedges1) { BasicBlock* D = schedule.NewBasicBlock(); BasicBlock* E = schedule.end(); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); schedule.AddSuccessorForTesting(A, loop1->header()); schedule.AddSuccessorForTesting(loop1->last(), E); @@ -553,7 +553,7 @@ TEST_F(SchedulerRPOTest, LoopOutedges2) { BasicBlock* A = schedule.start(); BasicBlock* E = schedule.end(); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); schedule.AddSuccessorForTesting(A, loop1->header()); schedule.AddSuccessorForTesting(loop1->last(), E); @@ -576,7 +576,7 @@ TEST_F(SchedulerRPOTest, LoopOutloops1) { Schedule schedule(zone()); BasicBlock* A = schedule.start(); BasicBlock* E = schedule.end(); - SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); + base::SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size)); schedule.AddSuccessorForTesting(A, loop1->header()); schedule.AddSuccessorForTesting(loop1->last(), E); diff --git a/deps/v8/test/unittests/compiler/tail-call-optimization-unittest.cc b/deps/v8/test/unittests/compiler/tail-call-optimization-unittest.cc index 449299bb1d..7257cc9802 100644 --- a/deps/v8/test/unittests/compiler/tail-call-optimization-unittest.cc +++ b/deps/v8/test/unittests/compiler/tail-call-optimization-unittest.cc @@ -27,10 +27,11 @@ class TailCallOptimizationTest : public GraphTest { TEST_F(TailCallOptimizationTest, CallCodeObject0) { MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged}; - LinkageLocation kLocationSignature[] = {LinkageLocation(0), - LinkageLocation(1)}; + LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0), + LinkageLocation::ForRegister(1)}; const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor( - CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0), + CallDescriptor::kCallCodeObject, kMachAnyTagged, + LinkageLocation::ForRegister(0), new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) LocationSignature(1, 1, kLocationSignature), 0, Operator::kNoProperties, 0, 0, CallDescriptor::kNoFlags); @@ -47,10 +48,11 @@ TEST_F(TailCallOptimizationTest, CallCodeObject0) { TEST_F(TailCallOptimizationTest, CallCodeObject1) { MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged}; - LinkageLocation kLocationSignature[] = {LinkageLocation(0), - LinkageLocation(1)}; + LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0), + LinkageLocation::ForRegister(1)}; const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor( - CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0), + CallDescriptor::kCallCodeObject, kMachAnyTagged, + LinkageLocation::ForRegister(0), new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) LocationSignature(1, 1, kLocationSignature), 0, Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls); @@ -71,10 +73,11 @@ TEST_F(TailCallOptimizationTest, CallCodeObject1) { TEST_F(TailCallOptimizationTest, CallCodeObject2) { MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged}; - LinkageLocation kLocationSignature[] = {LinkageLocation(0), - LinkageLocation(1)}; + LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0), + LinkageLocation::ForRegister(1)}; const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor( - CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0), + CallDescriptor::kCallCodeObject, kMachAnyTagged, + LinkageLocation::ForRegister(0), new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) LocationSignature(1, 1, kLocationSignature), 0, Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls); @@ -93,10 +96,11 @@ TEST_F(TailCallOptimizationTest, CallCodeObject2) { TEST_F(TailCallOptimizationTest, CallJSFunction0) { MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged}; - LinkageLocation kLocationSignature[] = {LinkageLocation(0), - LinkageLocation(1)}; + LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0), + LinkageLocation::ForRegister(1)}; const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor( - CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0), + CallDescriptor::kCallJSFunction, kMachAnyTagged, + LinkageLocation::ForRegister(0), new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) LocationSignature(1, 1, kLocationSignature), 0, Operator::kNoProperties, 0, 0, CallDescriptor::kNoFlags); @@ -113,10 +117,11 @@ TEST_F(TailCallOptimizationTest, CallJSFunction0) { TEST_F(TailCallOptimizationTest, CallJSFunction1) { MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged}; - LinkageLocation kLocationSignature[] = {LinkageLocation(0), - LinkageLocation(1)}; + LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0), + LinkageLocation::ForRegister(1)}; const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor( - CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0), + CallDescriptor::kCallJSFunction, kMachAnyTagged, + LinkageLocation::ForRegister(0), new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) LocationSignature(1, 1, kLocationSignature), 0, Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls); @@ -137,10 +142,11 @@ TEST_F(TailCallOptimizationTest, CallJSFunction1) { TEST_F(TailCallOptimizationTest, CallJSFunction2) { MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged}; - LinkageLocation kLocationSignature[] = {LinkageLocation(0), - LinkageLocation(1)}; + LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0), + LinkageLocation::ForRegister(1)}; const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor( - CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0), + CallDescriptor::kCallJSFunction, kMachAnyTagged, + LinkageLocation::ForRegister(0), new (zone()) MachineSignature(1, 1, kMachineSignature), new (zone()) LocationSignature(1, 1, kLocationSignature), 0, Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls); diff --git a/deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc b/deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc index c75fde492e..e74152a5fd 100644 --- a/deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc +++ b/deps/v8/test/unittests/heap/gc-idle-time-handler-unittest.cc @@ -156,6 +156,19 @@ TEST_F(GCIdleTimeHandlerTest, DoScavengeLowScavengeSpeed) { } +TEST_F(GCIdleTimeHandlerTest, DoScavengeLowAllocationRate) { + GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); + heap_state.used_new_space_size = kNewSpaceCapacity; + heap_state.new_space_allocation_throughput_in_bytes_per_ms = + GCIdleTimeHandler::kLowAllocationThroughput - 1; + int idle_time_ms = 16; + EXPECT_TRUE(GCIdleTimeHandler::ShouldDoScavenge( + idle_time_ms, heap_state.new_space_capacity, + heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms, + heap_state.new_space_allocation_throughput_in_bytes_per_ms)); +} + + TEST_F(GCIdleTimeHandlerTest, DoScavengeHighScavengeSpeed) { GCIdleTimeHandler::HeapState heap_state = DefaultHeapState(); heap_state.used_new_space_size = kNewSpaceCapacity; diff --git a/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc b/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc new file mode 100644 index 0000000000..aead34770c --- /dev/null +++ b/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc @@ -0,0 +1,137 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/v8.h" + +#include "src/interpreter/bytecode-array-builder.h" +#include "test/unittests/test-utils.h" + +namespace v8 { +namespace internal { +namespace interpreter { + +class BytecodeArrayBuilderTest : public TestWithIsolate { + public: + BytecodeArrayBuilderTest() {} + ~BytecodeArrayBuilderTest() override {} +}; + + +TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { + BytecodeArrayBuilder builder(isolate()); + + builder.set_locals_count(1); + CHECK_EQ(builder.locals_count(), 1); + + // Emit constant loads. + builder.LoadLiteral(Smi::FromInt(0)) + .LoadLiteral(Smi::FromInt(8)) + .LoadUndefined() + .LoadNull() + .LoadTheHole() + .LoadTrue() + .LoadFalse(); + + // Emit accumulator transfers. + Register reg(0); + builder.LoadAccumulatorWithRegister(reg).StoreAccumulatorInRegister(reg); + + // Emit binary operators invocations. + builder.BinaryOperation(Token::Value::ADD, reg) + .BinaryOperation(Token::Value::SUB, reg) + .BinaryOperation(Token::Value::MUL, reg) + .BinaryOperation(Token::Value::DIV, reg); + + // Emit control flow. Return must be the last instruction. + builder.Return(); + + // Generate BytecodeArray. + Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); + CHECK_EQ(the_array->frame_size(), builder.locals_count() * kPointerSize); + + // Build scorecard of bytecodes encountered in the BytecodeArray. + std::vector<int> scorecard(Bytecodes::ToByte(Bytecode::kLast) + 1); + Bytecode final_bytecode = Bytecode::kLdaZero; + for (int i = 0; i < the_array->length(); i++) { + uint8_t code = the_array->get(i); + scorecard[code] += 1; + int operands = Bytecodes::NumberOfOperands(Bytecodes::FromByte(code)); + CHECK_LE(operands, Bytecodes::MaximumNumberOfOperands()); + final_bytecode = Bytecodes::FromByte(code); + i += operands; + } + + // Check return occurs at the end and only once in the BytecodeArray. + CHECK_EQ(final_bytecode, Bytecode::kReturn); + CHECK_EQ(scorecard[Bytecodes::ToByte(final_bytecode)], 1); + +#define CHECK_BYTECODE_PRESENT(Name, ...) \ + /* Check Bytecode is marked in scorecard */ \ + CHECK_GE(scorecard[Bytecodes::ToByte(Bytecode::k##Name)], 1); + BYTECODE_LIST(CHECK_BYTECODE_PRESENT) +#undef CHECK_BYTECODE_PRESENT +} + + +TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) { + for (int locals = 0; locals < 5; locals++) { + for (int temps = 0; temps < 3; temps++) { + BytecodeArrayBuilder builder(isolate()); + builder.set_locals_count(locals); + builder.Return(); + + TemporaryRegisterScope temporaries(&builder); + for (int i = 0; i < temps; i++) { + temporaries.NewRegister(); + } + + Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); + int total_registers = locals + temps; + CHECK_EQ(the_array->frame_size(), total_registers * kPointerSize); + } + } +} + + +TEST_F(BytecodeArrayBuilderTest, TemporariesRecycled) { + BytecodeArrayBuilder builder(isolate()); + builder.set_locals_count(0); + builder.Return(); + + int first; + { + TemporaryRegisterScope temporaries(&builder); + first = temporaries.NewRegister().index(); + temporaries.NewRegister(); + temporaries.NewRegister(); + temporaries.NewRegister(); + } + + int second; + { + TemporaryRegisterScope temporaries(&builder); + second = temporaries.NewRegister().index(); + } + + CHECK_EQ(first, second); +} + + +TEST_F(BytecodeArrayBuilderTest, RegisterValues) { + int index = 1; + uint8_t operand = static_cast<uint8_t>(-index); + + Register the_register(index); + CHECK_EQ(the_register.index(), index); + + int actual_operand = the_register.ToOperand(); + CHECK_EQ(actual_operand, operand); + + int actual_index = Register::FromOperand(actual_operand).index(); + CHECK_EQ(actual_index, index); +} + +} // namespace interpreter +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/unittests/test-utils.cc b/deps/v8/test/unittests/test-utils.cc index fd52a4b21d..7d04215143 100644 --- a/deps/v8/test/unittests/test-utils.cc +++ b/deps/v8/test/unittests/test-utils.cc @@ -4,10 +4,12 @@ #include "test/unittests/test-utils.h" +#include "include/libplatform/libplatform.h" #include "src/base/platform/time.h" -#include "src/debug.h" +#include "src/debug/debug.h" #include "src/flags.h" #include "src/isolate.h" +#include "src/v8.h" namespace v8 { @@ -51,6 +53,9 @@ void TestWithIsolate::SetUpTestCase() { // static void TestWithIsolate::TearDownTestCase() { ASSERT_TRUE(isolate_ != NULL); + v8::Platform* platform = internal::V8::GetCurrentPlatform(); + ASSERT_TRUE(platform != NULL); + while (platform::PumpMessageLoop(platform, isolate_)) continue; isolate_->Dispose(); isolate_ = NULL; delete array_buffer_allocator_; @@ -75,7 +80,7 @@ inline int64_t GetRandomSeedFromFlag(int random_seed) { } // namespace TestWithRandomNumberGenerator::TestWithRandomNumberGenerator() - : rng_(GetRandomSeedFromFlag(internal::FLAG_random_seed)) {} + : rng_(GetRandomSeedFromFlag(::v8::internal::FLAG_random_seed)) {} TestWithRandomNumberGenerator::~TestWithRandomNumberGenerator() {} diff --git a/deps/v8/test/unittests/unittests.gyp b/deps/v8/test/unittests/unittests.gyp index 9698fb760d..60a5dea888 100644 --- a/deps/v8/test/unittests/unittests.gyp +++ b/deps/v8/test/unittests/unittests.gyp @@ -22,6 +22,10 @@ 'include_dirs': [ '../..', ], + 'defines': [ + # TODO(jochen): Remove again after this is globally turned on. + 'V8_IMMINENT_DEPRECATION_WARNINGS', + ], 'sources': [ ### gcmole(all) ### 'base/bits-unittest.cc', 'base/cpu-unittest.cc', @@ -39,6 +43,7 @@ 'base/utils/random-number-generator-unittest.cc', 'char-predicates-unittest.cc', 'compiler/change-lowering-unittest.cc', + 'compiler/coalesced-live-ranges-unittest.cc', 'compiler/common-operator-reducer-unittest.cc', 'compiler/common-operator-unittest.cc', 'compiler/compiler-test-utils.h', @@ -55,11 +60,15 @@ 'compiler/instruction-selector-unittest.h', 'compiler/instruction-sequence-unittest.cc', 'compiler/instruction-sequence-unittest.h', + 'compiler/interpreter-assembler-unittest.cc', + 'compiler/interpreter-assembler-unittest.h', 'compiler/js-builtin-reducer-unittest.cc', + 'compiler/js-context-relaxation-unittest.cc', 'compiler/js-intrinsic-lowering-unittest.cc', 'compiler/js-operator-unittest.cc', 'compiler/js-typed-lowering-unittest.cc', 'compiler/js-type-feedback-unittest.cc', + 'compiler/linkage-tail-call-unittest.cc', 'compiler/liveness-analyzer-unittest.cc', 'compiler/load-elimination-unittest.cc', 'compiler/loop-peeling-unittest.cc', @@ -85,6 +94,7 @@ 'compiler/value-numbering-reducer-unittest.cc', 'compiler/zone-pool-unittest.cc', 'counters-unittest.cc', + 'interpreter/bytecode-array-builder-unittest.cc', 'libplatform/default-platform-unittest.cc', 'libplatform/task-queue-unittest.cc', 'libplatform/worker-thread-unittest.cc', @@ -153,6 +163,11 @@ ], }, }], + ['v8_wasm!=0', { + 'dependencies': [ + '../../third_party/wasm/test/unittests/wasm/wasm.gyp:wasm_unittests', + ], + }], ], }, ], diff --git a/deps/v8/test/webkit/class-syntax-name-expected.txt b/deps/v8/test/webkit/class-syntax-name-expected.txt index 10f38ff2c2..ed49be3309 100644 --- a/deps/v8/test/webkit/class-syntax-name-expected.txt +++ b/deps/v8/test/webkit/class-syntax-name-expected.txt @@ -108,7 +108,7 @@ PASS 'use strict'; var VarA = class A { constructor() {} }; var VarB = class B e Class statement binding in other circumstances PASS var result = A; result threw exception ReferenceError: A is not defined. PASS 'use strict'; var result = A; result threw exception ReferenceError: A is not defined. -FAIL var result = A; class A {}; result should throw an exception. Was undefined. +PASS var result = A; class A {}; result threw exception ReferenceError: A is not defined. PASS 'use strict'; var result = A; class A {}; result threw exception ReferenceError: A is not defined. PASS class A { constructor() { A = 1; } }; new A threw exception TypeError: Assignment to constant variable.. PASS 'use strict'; class A { constructor() { A = 1; } }; new A threw exception TypeError: Assignment to constant variable.. @@ -118,7 +118,7 @@ PASS class A {}; var result = A; result did not throw exception. PASS 'use strict'; class A {}; var result = A; result did not throw exception. PASS eval('var Foo = 10'); Foo is 10 PASS 'use strict'; eval('var Foo = 10'); Foo threw exception ReferenceError: Foo is not defined. -PASS eval('class Bar { constructor() {} }'); Bar.toString() is 'class Bar { constructor() {} }' +PASS eval('class Bar { constructor() {} }; Bar.toString()') is 'class Bar { constructor() {} }' PASS 'use strict'; eval('class Bar { constructor() {} }'); Bar.toString() threw exception ReferenceError: Bar is not defined. PASS successfullyParsed is true diff --git a/deps/v8/test/webkit/class-syntax-name.js b/deps/v8/test/webkit/class-syntax-name.js index 09faa3a54a..16045651ef 100644 --- a/deps/v8/test/webkit/class-syntax-name.js +++ b/deps/v8/test/webkit/class-syntax-name.js @@ -111,5 +111,5 @@ runTestShouldBe("class A { constructor() { } }; A = 1; A", "1"); runTestShouldNotThrow("class A {}; var result = A; result"); shouldBe("eval('var Foo = 10'); Foo", "10"); shouldThrow("'use strict'; eval('var Foo = 10'); Foo"); -shouldBe("eval('class Bar { constructor() {} }'); Bar.toString()", "'class Bar { constructor() {} }'"); +shouldBe("eval('class Bar { constructor() {} }; Bar.toString()')", "'class Bar { constructor() {} }'"); shouldThrow("'use strict'; eval('class Bar { constructor() {} }'); Bar.toString()"); diff --git a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt deleted file mode 100644 index 7731a98671..0000000000 --- a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright 2014 the V8 project authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -Test to ensure correct behaviour of Object.getOwnPropertyNames - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS getSortedOwnPropertyNames({}) is [] -PASS getSortedOwnPropertyNames({a:null}) is ['a'] -PASS getSortedOwnPropertyNames({a:null, b:null}) is ['a', 'b'] -PASS getSortedOwnPropertyNames({b:null, a:null}) is ['a', 'b'] -PASS getSortedOwnPropertyNames({__proto__:{a:null}}) is [] -PASS getSortedOwnPropertyNames({__proto__:[1,2,3]}) is [] -PASS getSortedOwnPropertyNames(Object.create({}, { 'a': { 'value': 1, 'enumerable': false } })) is ['a'] -PASS getSortedOwnPropertyNames(Object.create([1,2,3], { 'a': { 'value': 1, 'enumerable': false } })) is ['a'] -PASS getSortedOwnPropertyNames(new Function()) is ['arguments', 'caller', 'length', 'name', 'prototype'] -PASS getSortedOwnPropertyNames((function(){var x=new Function();x.__proto__=[1,2,3];return x;})()) is ['arguments', 'caller', 'length', 'name', 'prototype'] -PASS getSortedOwnPropertyNames(new String('')) is ['length'] -PASS getSortedOwnPropertyNames(new String('a')) is ['0', 'length'] -PASS getSortedOwnPropertyNames(new String('abc')) is ['0', '1', '2', 'length'] -PASS getSortedOwnPropertyNames((function(){var x=new String('');x.__proto__=[1,2,3];return x;})()) is ['length'] -PASS getSortedOwnPropertyNames([]) is ['length'] -PASS getSortedOwnPropertyNames([null]) is ['0', 'length'] -PASS getSortedOwnPropertyNames([null,null]) is ['0','1', 'length'] -PASS getSortedOwnPropertyNames([null,null,,,,null]) is ['0','1','5', 'length'] -PASS getSortedOwnPropertyNames((function(){var x=[];x.__proto__=[1,2,3];return x;})()) is ['length'] -PASS getSortedOwnPropertyNames(new Date()) is [] -PASS getSortedOwnPropertyNames((function(){var x=new Date();x.__proto__=[1,2,3];return x;})()) is [] -PASS getSortedOwnPropertyNames(new RegExp('foo')) is ['global', 'ignoreCase', 'lastIndex', 'multiline', 'source'] -PASS getSortedOwnPropertyNames((function(){var x=new RegExp();x.__proto__=[1,2,3];return x;})()) is ['global', 'ignoreCase', 'lastIndex', 'multiline', 'source'] -PASS getSortedOwnPropertyNames(argumentsObject()) is ['callee', 'length'] -PASS getSortedOwnPropertyNames(argumentsObject(1)) is ['0', 'callee', 'length'] -PASS getSortedOwnPropertyNames(argumentsObject(1,2,3)) is ['0', '1', '2', 'callee', 'length'] -PASS getSortedOwnPropertyNames((function(){arguments.__proto__=[1,2,3];return arguments;})()) is ['callee', 'length'] -PASS getSortedOwnPropertyNames(parseInt) is ['arguments', 'caller', 'length', 'name'] -PASS getSortedOwnPropertyNames(parseFloat) is ['arguments', 'caller', 'length', 'name'] -PASS getSortedOwnPropertyNames(isNaN) is ['arguments', 'caller', 'length', 'name'] -PASS getSortedOwnPropertyNames(isFinite) is ['arguments', 'caller', 'length', 'name'] -PASS getSortedOwnPropertyNames(escape) is ['length', 'name'] -PASS getSortedOwnPropertyNames(unescape) is ['length', 'name'] -PASS getSortedOwnPropertyNames(decodeURI) is ['length', 'name'] -PASS getSortedOwnPropertyNames(decodeURIComponent) is ['length', 'name'] -PASS getSortedOwnPropertyNames(encodeURI) is ['length', 'name'] -PASS getSortedOwnPropertyNames(encodeURIComponent) is ['length', 'name'] -PASS getSortedOwnPropertyNames(Object) is ['arguments', 'assign', 'caller', 'create', 'defineProperties', 'defineProperty', 'deliverChangeRecords', 'freeze', 'getNotifier', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'observe', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf', 'unobserve'] -PASS getSortedOwnPropertyNames(Object.prototype) is ['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf'] -PASS getSortedOwnPropertyNames(Function) is ['arguments', 'caller', 'length', 'name', 'prototype'] -PASS getSortedOwnPropertyNames(Function.prototype) is ['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toString'] -PASS getSortedOwnPropertyNames(Array) is ['arguments', 'caller', 'from', 'isArray', 'length', 'name', 'observe', 'of', 'prototype', 'unobserve'] -PASS getSortedOwnPropertyNames(Array.prototype) is ['concat', 'constructor', 'copyWithin', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift'] -PASS getSortedOwnPropertyNames(String) is ['arguments', 'caller', 'fromCharCode', 'fromCodePoint', 'length', 'name', 'prototype', 'raw'] -PASS getSortedOwnPropertyNames(String.prototype) is ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'codePointAt', 'concat', 'constructor', 'endsWith', 'fixed', 'fontcolor', 'fontsize', 'includes', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'repeat', 'replace', 'search', 'slice', 'small', 'split', 'startsWith', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf'] -PASS getSortedOwnPropertyNames(Boolean) is ['arguments', 'caller', 'length', 'name', 'prototype'] -PASS getSortedOwnPropertyNames(Boolean.prototype) is ['constructor', 'toString', 'valueOf'] -PASS getSortedOwnPropertyNames(Number) is ['EPSILON', 'MAX_SAFE_INTEGER', 'MAX_VALUE', 'MIN_SAFE_INTEGER', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'arguments', 'caller', 'isFinite', 'isInteger', 'isNaN', 'isSafeInteger', 'length', 'name', 'parseFloat', 'parseInt', 'prototype'] -PASS getSortedOwnPropertyNames(Number.prototype) is ['constructor', 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 'valueOf'] -PASS getSortedOwnPropertyNames(Date) is ['UTC', 'arguments', 'caller', 'length', 'name', 'now', 'parse', 'prototype'] -PASS getSortedOwnPropertyNames(Date.prototype) is ['constructor', 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'toDateString', 'toGMTString', 'toISOString', 'toJSON', 'toLocaleDateString', 'toLocaleString', 'toLocaleTimeString', 'toString', 'toTimeString', 'toUTCString', 'valueOf'] -PASS getSortedOwnPropertyNames(RegExp) is ['$&', "$'", '$*', '$+', '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$_', '$`', 'arguments', 'caller', 'input', 'lastMatch', 'lastParen', 'leftContext', 'length', 'multiline', 'name', 'prototype', 'rightContext'] -PASS getSortedOwnPropertyNames(RegExp.prototype) is ['compile', 'constructor', 'exec', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'test', 'toString'] -PASS getSortedOwnPropertyNames(Error) is ['arguments', 'caller', 'captureStackTrace', 'length', 'name', 'prototype', 'stackTraceLimit'] -PASS getSortedOwnPropertyNames(Error.prototype) is ['constructor', 'message', 'name', 'toString'] -PASS getSortedOwnPropertyNames(Math) is ['E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2', 'abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'cbrt', 'ceil', 'clz32', 'cos', 'cosh', 'exp', 'expm1', 'floor', 'fround', 'hypot', 'imul', 'log', 'log10', 'log1p', 'log2', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc'] -PASS getSortedOwnPropertyNames(JSON) is ['parse', 'stringify'] -PASS globalPropertyNames.indexOf('NaN') != -1 is true -PASS globalPropertyNames.indexOf('Infinity') != -1 is true -PASS globalPropertyNames.indexOf('undefined') != -1 is true -PASS globalPropertyNames.indexOf('parseInt') != -1 is true -PASS globalPropertyNames.indexOf('parseFloat') != -1 is true -PASS globalPropertyNames.indexOf('isNaN') != -1 is true -PASS globalPropertyNames.indexOf('isFinite') != -1 is true -PASS globalPropertyNames.indexOf('escape') != -1 is true -PASS globalPropertyNames.indexOf('unescape') != -1 is true -PASS globalPropertyNames.indexOf('decodeURI') != -1 is true -PASS globalPropertyNames.indexOf('decodeURIComponent') != -1 is true -PASS globalPropertyNames.indexOf('encodeURI') != -1 is true -PASS globalPropertyNames.indexOf('encodeURIComponent') != -1 is true -PASS globalPropertyNames.indexOf('Object') != -1 is true -PASS globalPropertyNames.indexOf('Function') != -1 is true -PASS globalPropertyNames.indexOf('Array') != -1 is true -PASS globalPropertyNames.indexOf('String') != -1 is true -PASS globalPropertyNames.indexOf('Boolean') != -1 is true -PASS globalPropertyNames.indexOf('Number') != -1 is true -PASS globalPropertyNames.indexOf('Date') != -1 is true -PASS globalPropertyNames.indexOf('RegExp') != -1 is true -PASS globalPropertyNames.indexOf('Error') != -1 is true -PASS globalPropertyNames.indexOf('Math') != -1 is true -PASS globalPropertyNames.indexOf('JSON') != -1 is true -PASS successfullyParsed is true - -TEST COMPLETE - diff --git a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js b/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js deleted file mode 100644 index e34562f5ba..0000000000 --- a/deps/v8/test/webkit/fast/js/Object-getOwnPropertyNames.js +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2013 the V8 project authors. All rights reserved. -// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -description("Test to ensure correct behaviour of Object.getOwnPropertyNames"); - -function argumentsObject() { return arguments; }; - -var expectedPropertyNamesSet = { - "{}": "[]", - "{a:null}": "['a']", - "{a:null, b:null}": "['a', 'b']", - "{b:null, a:null}": "['a', 'b']", - "{__proto__:{a:null}}": "[]", - "{__proto__:[1,2,3]}": "[]", - "Object.create({}, { 'a': { 'value': 1, 'enumerable': false } })": "['a']", - "Object.create([1,2,3], { 'a': { 'value': 1, 'enumerable': false } })": "['a']", -// Function objects - "new Function()": "['arguments', 'caller', 'length', 'name', 'prototype']", - "(function(){var x=new Function();x.__proto__=[1,2,3];return x;})()": "['arguments', 'caller', 'length', 'name', 'prototype']", -// String objects - "new String('')": "['length']", - "new String('a')": "['0', 'length']", - "new String('abc')": "['0', '1', '2', 'length']", - "(function(){var x=new String('');x.__proto__=[1,2,3];return x;})()": "['length']", -// Array objects - "[]": "['length']", - "[null]": "['0', 'length']", - "[null,null]": "['0','1', 'length']", - "[null,null,,,,null]": "['0','1','5', 'length']", - "(function(){var x=[];x.__proto__=[1,2,3];return x;})()": "['length']", -// Date objects - "new Date()": "[]", - "(function(){var x=new Date();x.__proto__=[1,2,3];return x;})()": "[]", -// RegExp objects - "new RegExp('foo')": "['global', 'ignoreCase', 'lastIndex', 'multiline', 'source']", - "(function(){var x=new RegExp();x.__proto__=[1,2,3];return x;})()": "['global', 'ignoreCase', 'lastIndex', 'multiline', 'source']", -// Arguments objects - "argumentsObject()": "['callee', 'length']", - "argumentsObject(1)": "['0', 'callee', 'length']", - "argumentsObject(1,2,3)": "['0', '1', '2', 'callee', 'length']", - "(function(){arguments.__proto__=[1,2,3];return arguments;})()": "['callee', 'length']", -// Built-in ECMA functions - "parseInt": "['arguments', 'caller', 'length', 'name']", - "parseFloat": "['arguments', 'caller', 'length', 'name']", - "isNaN": "['arguments', 'caller', 'length', 'name']", - "isFinite": "['arguments', 'caller', 'length', 'name']", - "escape": "['length', 'name']", - "unescape": "['length', 'name']", - "decodeURI": "['length', 'name']", - "decodeURIComponent": "['length', 'name']", - "encodeURI": "['length', 'name']", - "encodeURIComponent": "['length', 'name']", -// Built-in ECMA objects - "Object": "['arguments', 'assign', 'caller', 'create', 'defineProperties', 'defineProperty', 'deliverChangeRecords', 'freeze', 'getNotifier', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'getOwnPropertySymbols', 'getPrototypeOf', 'is', 'isExtensible', 'isFrozen', 'isSealed', 'keys', 'length', 'name', 'observe', 'preventExtensions', 'prototype', 'seal', 'setPrototypeOf', 'unobserve']", - "Object.prototype": "['__defineGetter__', '__defineSetter__', '__lookupGetter__', '__lookupSetter__', '__proto__', 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf']", - "Function": "['arguments', 'caller', 'length', 'name', 'prototype']", - "Function.prototype": "['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toString']", - "Array": "['arguments', 'caller', 'from', 'isArray', 'length', 'name', 'observe', 'of', 'prototype', 'unobserve']", - "Array.prototype": "['concat', 'constructor', 'copyWithin', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']", - "String": "['arguments', 'caller', 'fromCharCode', 'fromCodePoint', 'length', 'name', 'prototype', 'raw']", - "String.prototype": "['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'codePointAt', 'concat', 'constructor', 'endsWith', 'fixed', 'fontcolor', 'fontsize', 'includes', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'repeat', 'replace', 'search', 'slice', 'small', 'split', 'startsWith', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']", - "Boolean": "['arguments', 'caller', 'length', 'name', 'prototype']", - "Boolean.prototype": "['constructor', 'toString', 'valueOf']", - "Number": "['EPSILON', 'MAX_SAFE_INTEGER', 'MAX_VALUE', 'MIN_SAFE_INTEGER', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'arguments', 'caller', 'isFinite', 'isInteger', 'isNaN', 'isSafeInteger', 'length', 'name', 'parseFloat', 'parseInt', 'prototype']", - "Number.prototype": "['constructor', 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision', 'toString', 'valueOf']", - "Date": "['UTC', 'arguments', 'caller', 'length', 'name', 'now', 'parse', 'prototype']", - "Date.prototype": "['constructor', 'getDate', 'getDay', 'getFullYear', 'getHours', 'getMilliseconds', 'getMinutes', 'getMonth', 'getSeconds', 'getTime', 'getTimezoneOffset', 'getUTCDate', 'getUTCDay', 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds', 'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear', 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setYear', 'toDateString', 'toGMTString', 'toISOString', 'toJSON', 'toLocaleDateString', 'toLocaleString', 'toLocaleTimeString', 'toString', 'toTimeString', 'toUTCString', 'valueOf']", - "RegExp": "['$&', \"$'\", '$*', '$+', '$1', '$2', '$3', '$4', '$5', '$6', '$7', '$8', '$9', '$_', '$`', 'arguments', 'caller', 'input', 'lastMatch', 'lastParen', 'leftContext', 'length', 'multiline', 'name', 'prototype', 'rightContext']", - "RegExp.prototype": "['compile', 'constructor', 'exec', 'global', 'ignoreCase', 'lastIndex', 'multiline', 'source', 'test', 'toString']", - "Error": "['arguments', 'caller', 'captureStackTrace', 'length', 'name', 'prototype', 'stackTraceLimit']", - "Error.prototype": "['constructor', 'message', 'name', 'toString']", - "Math": "['E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2', 'abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'cbrt', 'ceil', 'clz32', 'cos', 'cosh', 'exp', 'expm1', 'floor', 'fround', 'hypot', 'imul', 'log', 'log10', 'log1p', 'log2', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']", - "JSON": "['parse', 'stringify']" -}; - -function getSortedOwnPropertyNames(obj) -{ - return Object.getOwnPropertyNames(obj).sort(); -} - -for (var expr in expectedPropertyNamesSet) - shouldBe("getSortedOwnPropertyNames(" + expr + ")", expectedPropertyNamesSet[expr]); - -// Global Object -// Only check for ECMA properties here -var globalPropertyNames = Object.getOwnPropertyNames(this); -var expectedGlobalPropertyNames = [ - "NaN", - "Infinity", - "undefined", - "parseInt", - "parseFloat", - "isNaN", - "isFinite", - "escape", - "unescape", - "decodeURI", - "decodeURIComponent", - "encodeURI", - "encodeURIComponent", - "Object", - "Function", - "Array", - "String", - "Boolean", - "Number", - "Date", - "RegExp", - "Error", - "Math", - "JSON" -]; - -for (var i = 0; i < expectedGlobalPropertyNames.length; ++i) - shouldBeTrue("globalPropertyNames.indexOf('" + expectedGlobalPropertyNames[i] + "') != -1"); diff --git a/deps/v8/test/webkit/fast/js/basic-strict-mode-expected.txt b/deps/v8/test/webkit/fast/js/basic-strict-mode-expected.txt index 1fcf0c1acb..d5fdeded68 100644 --- a/deps/v8/test/webkit/fast/js/basic-strict-mode-expected.txt +++ b/deps/v8/test/webkit/fast/js/basic-strict-mode-expected.txt @@ -69,8 +69,8 @@ PASS (function (){'use strict'; try{}catch(eval){}}) threw exception SyntaxError PASS (function(){(function (){'use strict'; try{}catch(eval){}})}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. PASS (function (){'use strict'; try{}catch(arguments){}}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. PASS (function(){(function (){'use strict'; try{}catch(arguments){}})}) threw exception SyntaxError: Unexpected eval or arguments in strict mode. -PASS (function (a, a){'use strict';}) threw exception SyntaxError: Strict mode function may not have duplicate parameter names. -PASS (function(){(function (a, a){'use strict';})}) threw exception SyntaxError: Strict mode function may not have duplicate parameter names. +PASS (function (a, a){'use strict';}) threw exception SyntaxError: Duplicate parameter name not allowed in this context. +PASS (function(){(function (a, a){'use strict';})}) threw exception SyntaxError: Duplicate parameter name not allowed in this context. PASS (function (a){'use strict'; delete a;})() threw exception SyntaxError: Delete of an unqualified identifier in strict mode.. PASS (function(){(function (a){'use strict'; delete a;})()}) threw exception SyntaxError: Delete of an unqualified identifier in strict mode.. PASS (function (){'use strict'; var a; delete a;})() threw exception SyntaxError: Delete of an unqualified identifier in strict mode.. diff --git a/deps/v8/test/webkit/fast/js/excessive-comma-usage-expected.txt b/deps/v8/test/webkit/fast/js/excessive-comma-usage-expected.txt index 2460768e4a..a86a1e87b1 100644 --- a/deps/v8/test/webkit/fast/js/excessive-comma-usage-expected.txt +++ b/deps/v8/test/webkit/fast/js/excessive-comma-usage-expected.txt @@ -28,7 +28,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE PASS new Function(initializerTestString)() is true PASS new Function(declarationTestString)() is true -FAIL new Function(commaExpressionTestString)() should be true. Threw exception RangeError: Maximum call stack size exceeded +PASS new Function(commaExpressionTestString)() is true PASS successfullyParsed is true TEST COMPLETE diff --git a/deps/v8/test/webkit/fast/js/excessive-comma-usage.js b/deps/v8/test/webkit/fast/js/excessive-comma-usage.js index d30ff6d0f8..414b29b7ef 100644 --- a/deps/v8/test/webkit/fast/js/excessive-comma-usage.js +++ b/deps/v8/test/webkit/fast/js/excessive-comma-usage.js @@ -24,17 +24,17 @@ description("Test that we can handle excessively large initializer lists"); var initializerTestString = "var a=0"; -for (var i = 0; i < 50000; i++) +for (var i = 0; i < 5000; i++) initializerTestString += ",a"+i+"="+i; initializerTestString += ";return true;"; var declarationTestString = "var a"; -for (var i = 0; i < 50000; i++) +for (var i = 0; i < 5000; i++) declarationTestString += ",a"+i; declarationTestString += ";return true;"; var commaExpressionTestString = "1"; -for (var i = 0; i < 50000; i++) +for (var i = 0; i < 5000; i++) commaExpressionTestString += ",1"; commaExpressionTestString += ";return true;"; diff --git a/deps/v8/test/webkit/fast/js/parser-syntax-check-expected.txt b/deps/v8/test/webkit/fast/js/parser-syntax-check-expected.txt index 503bec9687..0f4c4cf9a0 100644 --- a/deps/v8/test/webkit/fast/js/parser-syntax-check-expected.txt +++ b/deps/v8/test/webkit/fast/js/parser-syntax-check-expected.txt @@ -422,36 +422,36 @@ PASS Valid: "for (a() in b) break" PASS Valid: "function f() { for (a() in b) break }" PASS Valid: "for (a().l[4] in b) break" PASS Valid: "function f() { for (a().l[4] in b) break }" -PASS Valid: "for (new a in b in c in d) break" -PASS Valid: "function f() { for (new a in b in c in d) break }" -PASS Valid: "for (new new new a in b) break" -PASS Valid: "function f() { for (new new new a in b) break }" -FAIL Invalid: "for (delete new a() in b) break" should throw undefined -FAIL Invalid: "function f() { for (delete new a() in b) break }" should throw undefined -FAIL Invalid: "for (a * a in b) break" should throw undefined -FAIL Invalid: "function f() { for (a * a in b) break }" should throw undefined -PASS Valid: "for ((a * a) in b) break" -PASS Valid: "function f() { for ((a * a) in b) break }" -FAIL Invalid: "for (a++ in b) break" should throw undefined -FAIL Invalid: "function f() { for (a++ in b) break }" should throw undefined -PASS Valid: "for ((a++) in b) break" -PASS Valid: "function f() { for ((a++) in b) break }" -FAIL Invalid: "for (++a in b) break" should throw undefined -FAIL Invalid: "function f() { for (++a in b) break }" should throw undefined -PASS Valid: "for ((++a) in b) break" -PASS Valid: "function f() { for ((++a) in b) break }" -FAIL Invalid: "for (a, b in c) break" should throw undefined -FAIL Invalid: "function f() { for (a, b in c) break }" should throw undefined -FAIL Invalid: "for (a,b in c ;;) break" should throw undefined -FAIL Invalid: "function f() { for (a,b in c ;;) break }" should throw undefined +PASS Invalid: "for (new a in b in c in d) break" +PASS Invalid: "function f() { for (new a in b in c in d) break }" +PASS Invalid: "for (new new new a in b) break" +PASS Invalid: "function f() { for (new new new a in b) break }" +PASS Invalid: "for (delete new a() in b) break" +PASS Invalid: "function f() { for (delete new a() in b) break }" +PASS Invalid: "for (a * a in b) break" +PASS Invalid: "function f() { for (a * a in b) break }" +PASS Invalid: "for ((a * a) in b) break" +PASS Invalid: "function f() { for ((a * a) in b) break }" +PASS Invalid: "for (a++ in b) break" +PASS Invalid: "function f() { for (a++ in b) break }" +PASS Invalid: "for ((a++) in b) break" +PASS Invalid: "function f() { for ((a++) in b) break }" +PASS Invalid: "for (++a in b) break" +PASS Invalid: "function f() { for (++a in b) break }" +PASS Invalid: "for ((++a) in b) break" +PASS Invalid: "function f() { for ((++a) in b) break }" +PASS Invalid: "for (a, b in c) break" +PASS Invalid: "function f() { for (a, b in c) break }" +PASS Invalid: "for (a,b in c ;;) break" +PASS Invalid: "function f() { for (a,b in c ;;) break }" PASS Valid: "for (a,(b in c) ;;) break" PASS Valid: "function f() { for (a,(b in c) ;;) break }" -PASS Valid: "for ((a, b) in c) break" -PASS Valid: "function f() { for ((a, b) in c) break }" -FAIL Invalid: "for (a ? b : c in c) break" should throw undefined -FAIL Invalid: "function f() { for (a ? b : c in c) break }" should throw undefined -PASS Valid: "for ((a ? b : c) in c) break" -PASS Valid: "function f() { for ((a ? b : c) in c) break }" +PASS Invalid: "for ((a, b) in c) break" +PASS Invalid: "function f() { for ((a, b) in c) break }" +PASS Invalid: "for (a ? b : c in c) break" +PASS Invalid: "function f() { for (a ? b : c in c) break }" +PASS Invalid: "for ((a ? b : c) in c) break" +PASS Invalid: "function f() { for ((a ? b : c) in c) break }" PASS Valid: "for (var a in b in c) break" PASS Valid: "function f() { for (var a in b in c) break }" PASS Valid: "for (var a = 5 += 6 in b) break" diff --git a/deps/v8/test/webkit/fast/js/parser-syntax-check.js b/deps/v8/test/webkit/fast/js/parser-syntax-check.js index a1b0e924d7..a3fef13474 100644 --- a/deps/v8/test/webkit/fast/js/parser-syntax-check.js +++ b/deps/v8/test/webkit/fast/js/parser-syntax-check.js @@ -291,21 +291,21 @@ invalid("for ( %a ; ; ) { }"); valid ("for (a in b) break"); valid ("for (a() in b) break"); valid ("for (a().l[4] in b) break"); -valid ("for (new a in b in c in d) break"); -valid ("for (new new new a in b) break"); +invalid("for (new a in b in c in d) break"); +invalid("for (new new new a in b) break"); invalid("for (delete new a() in b) break"); invalid("for (a * a in b) break"); -valid ("for ((a * a) in b) break"); +invalid("for ((a * a) in b) break"); invalid("for (a++ in b) break"); -valid ("for ((a++) in b) break"); +invalid("for ((a++) in b) break"); invalid("for (++a in b) break"); -valid ("for ((++a) in b) break"); +invalid("for ((++a) in b) break"); invalid("for (a, b in c) break"); invalid("for (a,b in c ;;) break"); valid ("for (a,(b in c) ;;) break"); -valid ("for ((a, b) in c) break"); +invalid("for ((a, b) in c) break"); invalid("for (a ? b : c in c) break"); -valid ("for ((a ? b : c) in c) break"); +invalid("for ((a ? b : c) in c) break"); valid ("for (var a in b in c) break"); valid ("for (var a = 5 += 6 in b) break"); invalid("for (var a += 5 in b) break"); diff --git a/deps/v8/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt b/deps/v8/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt index df66f4eba4..e86d26a83c 100644 --- a/deps/v8/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt +++ b/deps/v8/test/webkit/fast/js/primitive-property-access-edge-cases-expected.txt @@ -53,15 +53,15 @@ PASS checkWriteStrict(true, Boolean) threw exception TypeError: Cannot assign to PASS checkNumericGet(1, Number) is true PASS checkNumericGet('hello', String) is true PASS checkNumericGet(true, Boolean) is true -FAIL checkNumericSet(1, Number) should be true. Was false. -FAIL checkNumericSet('hello', String) should be true. Was false. -FAIL checkNumericSet(true, Boolean) should be true. Was false. +PASS checkNumericSet(1, Number) is true +PASS checkNumericSet('hello', String) is true +PASS checkNumericSet(true, Boolean) is true PASS checkNumericGetStrict(1, Number) is true PASS checkNumericGetStrict('hello', String) is true PASS checkNumericGetStrict(true, Boolean) is true -FAIL checkNumericSetStrict(1, Number) should be true. Was false. -FAIL checkNumericSetStrict('hello', String) should be true. Was false. -FAIL checkNumericSetStrict(true, Boolean) should be true. Was false. +PASS checkNumericSetStrict(1, Number) is true +PASS checkNumericSetStrict('hello', String) is true +PASS checkNumericSetStrict(true, Boolean) is true PASS checkNumericRead(1, Number) is true PASS checkNumericRead('hello', String) is true PASS checkNumericRead(true, Boolean) is true @@ -71,9 +71,9 @@ PASS checkNumericWrite(true, Boolean) is true PASS checkNumericReadStrict(1, Number) is true PASS checkNumericReadStrict('hello', String) is true PASS checkNumericReadStrict(true, Boolean) is true -FAIL checkNumericWriteStrict(1, Number) should throw an exception. Was true. -FAIL checkNumericWriteStrict('hello', String) should throw an exception. Was true. -FAIL checkNumericWriteStrict(true, Boolean) should throw an exception. Was true. +PASS checkNumericWriteStrict(1, Number) threw exception TypeError: Cannot assign to read only property '42' of 1. +PASS checkNumericWriteStrict('hello', String) threw exception TypeError: Cannot assign to read only property '42' of hello. +PASS checkNumericWriteStrict(true, Boolean) threw exception TypeError: Cannot assign to read only property '42' of true. PASS didNotCrash is true PASS successfullyParsed is true diff --git a/deps/v8/test/webkit/function-apply-aliased-expected.txt b/deps/v8/test/webkit/function-apply-aliased-expected.txt index b6c6c86607..8007e1a546 100644 --- a/deps/v8/test/webkit/function-apply-aliased-expected.txt +++ b/deps/v8/test/webkit/function-apply-aliased-expected.txt @@ -45,7 +45,7 @@ PASS myFunctionWithApply.aliasedApply(myObject, ['arg1']) is [myObject, "myFunct PASS myFunctionWithApply.apply(myObject, arg1Array) is [myFunctionWithApply, "myFunctionWithApply.apply", myObject] PASS forwarder(myFunctionWithApply, myObject, arg1Array) is [myFunctionWithApply, "myFunctionWithApply.apply", myObject] PASS myFunctionWithApply.aliasedApply(myObject, arg1Array) is [myObject, "myFunctionWithApply", "arg1"] -PASS myFunction.apply(null, new Array(5000000)) threw exception RangeError: Maximum call stack size exceeded. +PASS myFunction.apply(null, new Array(500000)) threw exception RangeError: Maximum call stack size exceeded. PASS myFunction.apply(null, new Array(1 << 30)) threw exception RangeError: Maximum call stack size exceeded. PASS recurseArguments.apply(null, new Array(50000)) threw exception RangeError: Maximum call stack size exceeded. PASS successfullyParsed is true diff --git a/deps/v8/test/webkit/function-apply-aliased.js b/deps/v8/test/webkit/function-apply-aliased.js index cda3b1bc60..a6a7ff4533 100644 --- a/deps/v8/test/webkit/function-apply-aliased.js +++ b/deps/v8/test/webkit/function-apply-aliased.js @@ -20,6 +20,7 @@ // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (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: --stack-size=100 description( "This tests that we can correctly call Function.prototype.apply" @@ -73,7 +74,7 @@ function stackOverflowTest() { stackOverflowTest(); } catch(e) { // Blow the stack with a sparse array - shouldThrow("myFunction.apply(null, new Array(5000000))"); + shouldThrow("myFunction.apply(null, new Array(500000))"); // Blow the stack with a sparse array that is sufficiently large to cause int overflow shouldThrow("myFunction.apply(null, new Array(1 << 30))"); } |