diff options
Diffstat (limited to 'deps/v8/test/cctest')
163 files changed, 29499 insertions, 11409 deletions
diff --git a/deps/v8/test/cctest/OWNERS b/deps/v8/test/cctest/OWNERS index ea8a397300..7fae8f355a 100644 --- a/deps/v8/test/cctest/OWNERS +++ b/deps/v8/test/cctest/OWNERS @@ -3,6 +3,7 @@ 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 *-mips*=ivica.bogosavljevic@imgtec.com per-file *-ppc*=dstence@us.ibm.com per-file *-ppc*=joransiu@ca.ibm.com per-file *-ppc*=jyan@ca.ibm.com @@ -10,3 +11,7 @@ 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 +per-file expression-type-collector*=aseemgarg@chromium.org +per-file expression-type-collector*=bradnelson@chromium.org +per-file test-asm-validator.cc=aseemgarg@chromium.org +per-file test-asm-validator.cc=bradnelson@chromium.org diff --git a/deps/v8/test/cctest/cctest.gyp b/deps/v8/test/cctest/cctest.gyp index 8b32b63160..9ef2d9bfb2 100644 --- a/deps/v8/test/cctest/cctest.gyp +++ b/deps/v8/test/cctest/cctest.gyp @@ -52,6 +52,7 @@ 'compiler/test-basic-block-profiler.cc', 'compiler/test-branch-combine.cc', 'compiler/test-changes-lowering.cc', + 'compiler/test-code-stub-assembler.cc', 'compiler/test-gap-resolver.cc', 'compiler/test-graph-visualizer.cc', 'compiler/test-instruction.cc', @@ -93,17 +94,23 @@ 'gay-fixed.cc', 'gay-precision.cc', 'gay-shortest.cc', - 'heap-tester.h', + 'heap/heap-tester.h', + 'heap/test-alloc.cc', + 'heap/test-compaction.cc', + 'heap/test-heap.cc', + 'heap/test-incremental-marking.cc', + 'heap/test-lab.cc', + 'heap/test-mark-compact.cc', + 'heap/test-spaces.cc', + 'heap/utils-inl.h', 'print-extension.cc', 'profiler-extension.cc', 'test-accessors.cc', - 'test-alloc.cc', 'test-api.cc', 'test-api.h', - # TODO(epertoso): re-enable the following test after the API change is - # checked in. - # 'test-api-accessors.cc', + 'test-api-accessors.cc', 'test-api-interceptors.cc', + 'test-api-fast-accessor-builder.cc', 'test-array-list.cc', 'test-ast.cc', 'test-ast-expression-visitor.cc', @@ -137,23 +144,22 @@ 'test-global-object.cc', 'test-hashing.cc', 'test-hashmap.cc', - 'test-heap.cc', 'test-heap-profiler.cc', 'test-hydrogen-types.cc', 'test-identity-map.cc', - 'test-incremental-marking.cc', + 'test-inobject-slack-tracking.cc', 'test-list.cc', 'test-liveedit.cc', 'test-lockers.cc', 'test-log.cc', 'test-microtask-delivery.cc', - 'test-mark-compact.cc', 'test-mementos.cc', 'test-object-observe.cc', 'test-parsing.cc', 'test-platform.cc', 'test-profile-generator.cc', 'test-random-number-generator.cc', + 'test-receiver-check-hidden-prototype.cc', 'test-regexp.cc', 'test-reloc-info.cc', 'test-representation.cc', @@ -161,12 +167,12 @@ 'test-serialize.cc', 'test-simd.cc', 'test-slots-buffer.cc', - 'test-spaces.cc', 'test-strings.cc', 'test-symbols.cc', 'test-strtod.cc', 'test-thread-termination.cc', 'test-threads.cc', + 'test-trace-event.cc', 'test-transitions.cc', 'test-typedarrays.cc', 'test-types.cc', @@ -180,6 +186,11 @@ 'test-weakmaps.cc', 'test-weaksets.cc', 'trace-extension.cc', + 'wasm/test-run-wasm.cc', + 'wasm/test-run-wasm-js.cc', + 'wasm/test-run-wasm-module.cc', + 'wasm/test-signatures.h', + 'wasm/wasm-run-utils.h', ], 'conditions': [ ['v8_target_arch=="ia32"', { @@ -296,11 +307,6 @@ }, { '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 4cfb8b0d70..fe9ae6e38d 100644 --- a/deps/v8/test/cctest/cctest.h +++ b/deps/v8/test/cctest/cctest.h @@ -341,6 +341,13 @@ static inline v8::Local<v8::String> v8_str(const char* x) { } +static inline v8::Local<v8::String> v8_str(v8::Isolate* isolate, + const char* x) { + return v8::String::NewFromUtf8(isolate, x, v8::NewStringType::kNormal) + .ToLocalChecked(); +} + + static inline v8::Local<v8::Symbol> v8_symbol(const char* name) { return v8::Symbol::New(v8::Isolate::GetCurrent(), v8_str(name)); } @@ -361,6 +368,12 @@ static inline v8::Local<v8::Script> v8_compile(const char* x) { } +static inline int32_t v8_run_int32value(v8::Local<v8::Script> script) { + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); + return script->Run(context).ToLocalChecked()->Int32Value(context).FromJust(); +} + + static inline v8::Local<v8::Script> CompileWithOrigin( v8::Local<v8::String> source, v8::Local<v8::String> origin_url) { v8::ScriptOrigin origin(origin_url); @@ -392,6 +405,18 @@ static inline v8::MaybeLocal<v8::Value> CompileRun( } +static inline v8::Local<v8::Value> CompileRunChecked(v8::Isolate* isolate, + const char* source) { + v8::Local<v8::String> source_string = + v8::String::NewFromUtf8(isolate, source, v8::NewStringType::kNormal) + .ToLocalChecked(); + v8::Local<v8::Context> context = isolate->GetCurrentContext(); + v8::Local<v8::Script> script = + v8::Script::Compile(context, source_string).ToLocalChecked(); + return script->Run(context).ToLocalChecked(); +} + + static inline v8::Local<v8::Value> CompileRun(v8::Local<v8::String> source) { v8::Local<v8::Value> result; if (v8_compile(source) @@ -525,6 +550,12 @@ static inline void ExpectUndefined(const char* code) { } +static inline void ExpectNull(const char* code) { + v8::Local<v8::Value> result = CompileRun(code); + CHECK(result->IsNull()); +} + + static inline void CheckDoubleEquals(double expected, double actual) { const double kEpsilon = 1e-10; CHECK_LE(expected, actual + kEpsilon); @@ -532,134 +563,18 @@ static inline void CheckDoubleEquals(double expected, double actual) { } -static int LenFromSize(int size) { - return (size - i::FixedArray::kHeaderSize) / i::kPointerSize; -} - - -static inline void CreatePadding(i::Heap* heap, int padding_size, - i::PretenureFlag tenure) { - const int max_number_of_objects = 20; - v8::internal::Handle<v8::internal::FixedArray> - big_objects[max_number_of_objects]; - i::Isolate* isolate = heap->isolate(); - int allocate_memory; - int length; - int free_memory = padding_size; - if (tenure == i::TENURED) { - int current_free_memory = - static_cast<int>(*heap->old_space()->allocation_limit_address() - - *heap->old_space()->allocation_top_address()); - CHECK(padding_size <= current_free_memory || current_free_memory == 0); - } else { - heap->new_space()->DisableInlineAllocationSteps(); - int current_free_memory = - static_cast<int>(*heap->new_space()->allocation_limit_address() - - *heap->new_space()->allocation_top_address()); - CHECK(padding_size <= current_free_memory || current_free_memory == 0); - } - for (int i = 0; i < max_number_of_objects && free_memory > 0; i++) { - if (free_memory > i::Page::kMaxRegularHeapObjectSize) { - allocate_memory = i::Page::kMaxRegularHeapObjectSize; - length = LenFromSize(allocate_memory); - } else { - allocate_memory = free_memory; - length = LenFromSize(allocate_memory); - if (length <= 0) { - // Not enough room to create another fixed array. Let's create a filler. - heap->CreateFillerObjectAt(*heap->old_space()->allocation_top_address(), - free_memory); - break; - } - } - big_objects[i] = isolate->factory()->NewFixedArray(length, tenure); - CHECK((tenure == i::NOT_TENURED && heap->InNewSpace(*big_objects[i])) || - (tenure == i::TENURED && heap->InOldSpace(*big_objects[i]))); - free_memory -= allocate_memory; - } -} - - -// Helper function that simulates a full new-space in the heap. -static inline bool FillUpOnePage(v8::internal::NewSpace* space) { - space->DisableInlineAllocationSteps(); - int space_remaining = static_cast<int>(*space->allocation_limit_address() - - *space->allocation_top_address()); - if (space_remaining == 0) return false; - CreatePadding(space->heap(), space_remaining, i::NOT_TENURED); - return true; -} - - -// Helper function that simulates a fill new-space in the heap. -static inline void AllocateAllButNBytes(v8::internal::NewSpace* space, - int extra_bytes) { - space->DisableInlineAllocationSteps(); - int space_remaining = static_cast<int>(*space->allocation_limit_address() - - *space->allocation_top_address()); - CHECK(space_remaining >= extra_bytes); - int new_linear_size = space_remaining - extra_bytes; - if (new_linear_size == 0) return; - CreatePadding(space->heap(), new_linear_size, i::NOT_TENURED); -} - - -static inline void FillCurrentPage(v8::internal::NewSpace* space) { - AllocateAllButNBytes(space, 0); -} - - -static inline void SimulateFullSpace(v8::internal::NewSpace* space) { - FillCurrentPage(space); - while (FillUpOnePage(space)) { - } -} - - -// Helper function that simulates a full old-space in the heap. -static inline void SimulateFullSpace(v8::internal::PagedSpace* space) { - space->EmptyAllocationInfo(); - space->ResetFreeList(); - space->ClearStats(); -} - - -// Helper function that simulates many incremental marking steps until -// marking is completed. -static inline void SimulateIncrementalMarking(i::Heap* heap, - bool force_completion = true) { - i::MarkCompactCollector* collector = heap->mark_compact_collector(); - i::IncrementalMarking* marking = heap->incremental_marking(); - if (collector->sweeping_in_progress()) { - collector->EnsureSweepingCompleted(); - } - CHECK(marking->IsMarking() || marking->IsStopped()); - if (marking->IsStopped()) { - heap->StartIncrementalMarking(); - } - CHECK(marking->IsMarking()); - if (!force_completion) return; - - while (!marking->IsComplete()) { - marking->Step(i::MB, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD); - if (marking->IsReadyToOverApproximateWeakClosure()) { - marking->FinalizeIncrementally(); - } - } - CHECK(marking->IsComplete()); -} - - static void DummyDebugEventListener( const v8::Debug::EventDetails& event_details) {} -static inline void EnableDebugger() { - v8::Debug::SetDebugEventListener(&DummyDebugEventListener); +static inline void EnableDebugger(v8::Isolate* isolate) { + v8::Debug::SetDebugEventListener(isolate, &DummyDebugEventListener); } -static inline void DisableDebugger() { v8::Debug::SetDebugEventListener(NULL); } +static inline void DisableDebugger(v8::Isolate* isolate) { + v8::Debug::SetDebugEventListener(isolate, nullptr); +} static inline void EmptyMessageQueues(v8::Isolate* isolate) { diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status index d01a2474d4..80837534ce 100644 --- a/deps/v8/test/cctest/cctest.status +++ b/deps/v8/test/cctest/cctest.status @@ -33,12 +33,6 @@ ############################################################################## - # TODO(danno): These tests fail because the incoming descriptor for JavaScript - # calls has nothing to do with the interface descriptors of some code stubs, - # and they cannot be used interchangably. - 'test-run-stubs/RunOptimizedMathFloorStub': [SKIP], - 'test-run-stubs/RunStringAddTFStub': [SKIP], - # BUG(382): Weird test. Can't guarantee that it never times out. 'test-api/ApplyInterruption': [PASS, TIMEOUT], @@ -96,8 +90,8 @@ 'test-debug/RecursiveBreakpoints': [PASS, FLAKY], 'test-debug/RecursiveBreakpointsGlobal': [PASS, FLAKY], - # Fails sometimes. - 'test-debug/ProcessDebugMessagesThreaded': [PASS, FLAKY], + # BUG(v8:4358). Hangs flakily. + 'test-debug/ProcessDebugMessagesThreaded': [SKIP], # BUG(2340). Preprocessing stack traces is disabled at the moment. 'test-heap/PreprocessStackTrace': [FAIL], @@ -121,10 +115,13 @@ # optimized and hence scripts don't "return" the correct value. Fix this. 'test-compiler/CompileFunctionInContext*': [PASS, NO_VARIANTS], + # TODO(bmeurer): TurboFan embeds strong references to all kinds of objects + # via deoptimization data (Crankshaft also does this, but lack proper test + # coverage). + 'test-heap/ObjectsInOptimizedCodeAreWeak': [PASS, NO_VARIANTS], + # TurboFan doesn't support allocation sites currently. - 'test-heap/CellsInOptimizedCodeAreWeak': [PASS, NO_VARIANTS], 'test-heap/EnsureAllocationSiteDependentCodesProcessed': [PASS, NO_VARIANTS], - 'test-heap/ObjectsInOptimizedCodeAreWeak': [PASS, NO_VARIANTS], 'test-heap/OptimizedPretenuringAllocationFolding': [PASS, NO_VARIANTS], 'test-heap/OptimizedPretenuringdoubleArrayLiterals': [PASS, NO_VARIANTS], 'test-heap/OptimizedPretenuringDoubleArrayProperties': [PASS, NO_VARIANTS], @@ -240,6 +237,11 @@ # BUG(3331). Fails on windows. 'test-heap/NoWeakHashTableLeakWithIncrementalMarking': [SKIP], + # BUG(v8:4573). + 'test-api/MultipleIsolatesOnIndividualThreads': [PASS, NO_VARIANTS], + + # BUG(v8:4642). + 'test-lockers/LockAndUnlockDifferentIsolates': [PASS, NO_VARIANTS], }], # 'system == windows' ############################################################################## @@ -252,6 +254,26 @@ }], # 'system == macos' ############################################################################## +['byteorder == big', { + # TODO(mips-team): Fix Wasm for big-endian. + 'test-run-wasm-module/Run_WasmModule_CallAdd_rev': [SKIP], + 'test-run-wasm-module/Run_WasmModule_ReadLoadedDataSegment': [SKIP], + 'test-run-wasm-module/Run_WasmModule_CheckMemoryIsZero': [SKIP], + 'test-run-wasm-module/Run_WasmModule_Global': [SKIP], + 'test-run-wasm/Run_WasmInt32*': [SKIP], + 'test-run-wasm/Run_Wasm_TableSwitch*': [SKIP], + 'test-run-wasm/Run_Wasm_StoreMemI32_offset': [SKIP], + 'test-run-wasm/Run_Wasm_Int32LoadInt16_*': [SKIP], + 'test-run-wasm/Run_WasmMixedGlobals': [SKIP], + 'test-run-wasm/Run_WasmCall*': [SKIP], + 'test-run-wasm/Run_WasmMixedCall_*': [SKIP], + 'test-run-wasm/Run_WasmInt64*': [SKIP], + 'test-run-wasm/Run_Wasm_LoadStoreI64_sx': [SKIP], + 'test-run-wasm/Run_WASM_Int64DivS_byzero_const': [SKIP], + 'test-run-wasm/Run_TestI64WasmRunner': [SKIP], +}], # 'byteorder == big' + +############################################################################## ['arch == arm', { 'test-cpu-profiler/CollectDeoptEvents': [PASS, FAIL], @@ -308,6 +330,9 @@ # BUG(v8:3154). 'test-heap/ReleaseOverReservedPages': [PASS, FAIL], + # TODO(mips-team): Improve code-size on large RegExp's. + 'test-heap/TestSizeOfRegExpCode': [SKIP], + # BUG(1075): Unresolved crashes on MIPS also. 'test-serialize/Deserialize': [SKIP], 'test-serialize/DeserializeFromSecondSerializationAndRunScript2': [SKIP], @@ -453,8 +478,11 @@ ############################################################################## ['system == aix or (arch == ppc64 and byteorder == big)', { - # Test currently broken for platforms with function desciptors + # TODO(ppc): Fix for platforms with function desciptors. 'test-run-machops/RunComputedCodeObject' : [SKIP], + 'test-run-wasm-module/Run_WasmModule_Return114' : [SKIP], + 'test-run-wasm-module/Run_WasmModule_CallAdd' : [SKIP], + 'test-run-wasm-module/Run_WasmModule_CallMain_recursive' : [SKIP], }], # 'system == aix or (arch == ppc64 and byteorder == big)' @@ -467,4 +495,95 @@ 'test-api/ExternalArrays': [PASS, SLOW], }], # 'arch == ppc64 and simulator_run == True' + +['ignition == True', { + 'test-api/*' : [SKIP], + 'test-cpu-profiler/*' : [SKIP], + 'test-debug/*' : [SKIP], + 'test-func-name-inference/*' : [SKIP], + 'test-inobject-slack-tracking/*' : [SKIP], + 'test-run-jsexceptions/*' : [SKIP], + 'test-serialize/*' : [SKIP], + + 'test-api-interceptors/InterceptorCallICInvalidatedConstantFunctionViaGlobal': [SKIP], + 'test-api-interceptors/InterceptorLoadICInvalidatedCallbackViaGlobal': [SKIP], + 'test-api-interceptors/InterceptorLoadICInvalidatedFieldViaGlobal': [SKIP], + 'test-bytecode-generator/TryCatch': [SKIP], + 'test-bytecode-generator/TryFinally': [SKIP], + 'test-compiler/C2JSFrames': [SKIP], + 'test-compiler/FeedbackVectorPreservedAcrossRecompiles': [SKIP], + 'test-compiler/FeedbackVectorUnaffectedByScopeChanges': [SKIP], + 'test-compiler/OptimizedCodeSharing2': [SKIP], + 'test-compiler/OptimizedCodeSharing3': [SKIP], + 'test-compiler/Print': [SKIP], + 'test-compiler/UncaughtThrow': [SKIP], + 'test-decls/CrossScriptDynamicLookup': [SKIP], + 'test-decls/Regress425510': [SKIP], + 'test-feedback-vector/VectorCallICStates': [SKIP], + 'test-heap/AddInstructionChangesNewSpacePromotion': [SKIP], + 'test-heap/ArrayShiftSweeping': [SKIP], + 'test-heap/CanonicalSharedFunctionInfo': [SKIP], + 'test-heap/CellsInOptimizedCodeAreWeak': [SKIP], + 'test-heap/CompilationCacheCachingBehavior': [SKIP], + 'test-heap/CountForcedGC': [SKIP], + 'test-heap/IncrementalMarkingClearsMonomorphicConstructor': [SKIP], + 'test-heap/IncrementalMarkingPreservesMonomorphicCallIC': [SKIP], + 'test-heap/IncrementalMarkingPreservesMonomorphicConstructor': [SKIP], + 'test-heap/NoWeakHashTableLeakWithIncrementalMarking': [SKIP], + 'test-heap-profiler/HeapSnapshotCollection': [SKIP], + 'test-heap-profiler/HeapSnapshotSimd': [SKIP], + 'test-heap-profiler/HeapSnapshotWeakCollection': [SKIP], + 'test-heap/OptimizedAllocationAlwaysInNewSpace': [SKIP], + 'test-heap/PromotionQueue': [SKIP], + 'test-heap/Regress169209': [SKIP], + 'test-heap/Regress1878': [SKIP], + 'test-heap/Regress357137': [SKIP], + 'test-heap/Regress3631': [SKIP], + 'test-heap/Regress388880': [SKIP], + 'test-heap/TestCodeFlushingIncrementalAbort': [SKIP], + 'test-heap/TestCodeFlushingIncrementalScavenge': [SKIP], + 'test-heap/TestCodeFlushingIncremental': [SKIP], + 'test-heap/TestCodeFlushingPreAged': [SKIP], + 'test-heap/TestCodeFlushing': [SKIP], + 'test-heap/WeakFunctionInConstructor': [SKIP], + 'test-log-stack-tracer/CFromJSStackTrace': [SKIP], + 'test-log-stack-tracer/JsEntrySp': [SKIP], + 'test-log-stack-tracer/PureCStackTrace': [SKIP], + 'test-log-stack-tracer/PureJSStackTrace': [SKIP], + 'test-parsing/DestructuringNegativeTests': [SKIP], + 'test-parsing/StrongModeFreeVariablesDeclaredByLanguage': [SKIP], + 'test-parsing/StrongModeFreeVariablesDeclaredByPreviousScript': [SKIP], + 'test-parsing/StrongModeFreeVariablesDeclaredInGlobalPrototype': [SKIP], + 'test-pipeline/PipelineGeneric': [SKIP], + 'test-pipeline/PipelineTyped': [SKIP], + 'test-profile-generator/BailoutReason': [SKIP], + 'test-profile-generator/LineNumber': [SKIP], + 'test-profile-generator/ProfileNodeScriptId': [SKIP], + 'test-profile-generator/RecordStackTraceAtStartProfiling': [SKIP], + 'test-run-inlining/InlineTwice': [SKIP], + 'test-run-jsbranches/ForOfContinueStatement': [SKIP], + 'test-run-jscalls/LookupCall': [SKIP], + 'test-run-jsobjects/ArgumentsRest': [SKIP], + 'test-run-jsops/ClassLiteral': [SKIP], + 'test-run-jsops/LookupLoad': [SKIP], + 'test-run-jsops/LookupStore': [SKIP], + 'test-run-variables/ContextInitializeVariables': [SKIP], + 'test-run-variables/ContextLoadVariables': [SKIP], + 'test-run-variables/ContextStoreVariables': [SKIP], + 'test-run-variables/StackInitializeVariables': [SKIP], + 'test-run-variables/StackLoadVariables': [SKIP], + 'test-run-variables/StackStoreVariables': [SKIP], + 'test-sampler-api/StackFramesConsistent': [SKIP], + 'test-thread-termination/TerminateCancelTerminateFromThreadItself': [SKIP], + 'test-thread-termination/TerminateFromOtherThreadWhileMicrotaskRunning': [SKIP], + 'test-thread-termination/TerminateOnlyV8ThreadFromThreadItselfNoLoop': [SKIP], + 'test-thread-termination/TerminationInInnerTryCall': [SKIP], + 'test-unscopables-hidden-prototype/Unscopables': [SKIP], +}], # ignition == True + +['ignition == True and arch == arm64', { + 'test-js-arm64-variables/lookup_slots': [SKIP], + 'test-spaces/SizeOfFirstPageIsLargeEnough': [SKIP], +}], # ignition == True and arch == arm64 + ] diff --git a/deps/v8/test/cctest/compiler/c-signature.h b/deps/v8/test/cctest/compiler/c-signature.h index 5a72c551ab..13ef38aaed 100644 --- a/deps/v8/test/cctest/compiler/c-signature.h +++ b/deps/v8/test/cctest/compiler/c-signature.h @@ -5,27 +5,27 @@ #ifndef V8_COMPILER_C_SIGNATURE_H_ #define V8_COMPILER_C_SIGNATURE_H_ -#include "src/compiler/machine-type.h" +#include "src/machine-type.h" namespace v8 { namespace internal { namespace compiler { #define FOREACH_CTYPE_MACHINE_TYPE_MAPPING(V) \ - V(void, kMachNone) \ - V(bool, kMachUint8) \ - V(int8_t, kMachInt8) \ - V(uint8_t, kMachUint8) \ - V(int16_t, kMachInt16) \ - V(uint16_t, kMachUint16) \ - V(int32_t, kMachInt32) \ - V(uint32_t, kMachUint32) \ - V(int64_t, kMachInt64) \ - V(uint64_t, kMachUint64) \ - V(float, kMachFloat32) \ - V(double, kMachFloat64) \ - V(void*, kMachPtr) \ - V(int*, kMachPtr) + V(void, MachineType::None()) \ + V(bool, MachineType::Uint8()) \ + V(int8_t, MachineType::Int8()) \ + V(uint8_t, MachineType::Uint8()) \ + V(int16_t, MachineType::Int16()) \ + V(uint16_t, MachineType::Uint16()) \ + V(int32_t, MachineType::Int32()) \ + V(uint32_t, MachineType::Uint32()) \ + V(int64_t, MachineType::Int64()) \ + V(uint64_t, MachineType::Uint64()) \ + V(float, MachineType::Float32()) \ + V(double, MachineType::Float64()) \ + V(void*, MachineType::Pointer()) \ + V(int*, MachineType::Pointer()) template <typename T> inline MachineType MachineTypeForC() { @@ -33,7 +33,7 @@ inline MachineType MachineTypeForC() { // All other types T must be assignable to Object* *(static_cast<Object* volatile*>(0)) = static_cast<T>(0); } - return kMachAnyTagged; + return MachineType::AnyTagged(); } #define DECLARE_TEMPLATE_SPECIALIZATION(ctype, mtype) \ @@ -64,7 +64,7 @@ class CSignature : public MachineSignature { if (p < static_cast<int>(parameter_count())) { CHECK_EQ(GetParam(p), params[p]); } else { - CHECK_EQ(kMachNone, params[p]); + CHECK_EQ(MachineType::None(), params[p]); } } } @@ -74,13 +74,15 @@ class CSignature : public MachineSignature { } static CSignature* New(Zone* zone, MachineType ret, - MachineType p1 = kMachNone, MachineType p2 = kMachNone, - MachineType p3 = kMachNone, MachineType p4 = kMachNone, - MachineType p5 = kMachNone) { + MachineType p1 = MachineType::None(), + MachineType p2 = MachineType::None(), + MachineType p3 = MachineType::None(), + MachineType p4 = MachineType::None(), + MachineType p5 = MachineType::None()) { MachineType* buffer = zone->NewArray<MachineType>(6); int pos = 0; size_t return_count = 0; - if (ret != kMachNone) { + if (ret != MachineType::None()) { buffer[pos++] = ret; return_count++; } @@ -90,14 +92,15 @@ class CSignature : public MachineSignature { buffer[pos++] = p4; buffer[pos++] = p5; size_t param_count = 5; - if (p5 == kMachNone) param_count--; - if (p4 == kMachNone) param_count--; - if (p3 == kMachNone) param_count--; - if (p2 == kMachNone) param_count--; - if (p1 == kMachNone) param_count--; + if (p5 == MachineType::None()) param_count--; + if (p4 == MachineType::None()) param_count--; + if (p3 == MachineType::None()) param_count--; + if (p2 == MachineType::None()) param_count--; + if (p1 == MachineType::None()) param_count--; for (size_t i = 0; i < param_count; i++) { - // Check that there are no kMachNone's in the middle of parameters. - CHECK_NE(kMachNone, buffer[return_count + i]); + // Check that there are no MachineType::None()'s in the middle of + // parameters. + CHECK_NE(MachineType::None(), buffer[return_count + i]); } return new (zone) CSignature(return_count, param_count, buffer); } @@ -110,12 +113,13 @@ class CSignatureOf : public CSignature { MachineType storage_[1 + kParamCount]; CSignatureOf() - : CSignature(MachineTypeForC<Ret>() != kMachNone ? 1 : 0, kParamCount, - reinterpret_cast<MachineType*>(&storage_)) { + : CSignature(MachineTypeForC<Ret>() != MachineType::None() ? 1 : 0, + kParamCount, reinterpret_cast<MachineType*>(&storage_)) { if (return_count_ == 1) storage_[0] = MachineTypeForC<Ret>(); } void Set(int index, MachineType type) { - DCHECK(index >= 0 && index < kParamCount); + CHECK_LE(0, index); + CHECK_LT(index, kParamCount); reps_[return_count_ + index] = type; } }; diff --git a/deps/v8/test/cctest/compiler/codegen-tester.cc b/deps/v8/test/cctest/compiler/codegen-tester.cc index ba73822d32..fc0956fb50 100644 --- a/deps/v8/test/cctest/compiler/codegen-tester.cc +++ b/deps/v8/test/cctest/compiler/codegen-tester.cc @@ -291,7 +291,8 @@ void Int32BinopInputShapeTester::TestAllInputShapes() { for (int i = -2; i < num_int_inputs; i++) { // for all left shapes for (int j = -2; j < num_int_inputs; j++) { // for all right shapes if (i >= 0 && j >= 0) break; // No constant/constant combos - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); Node* p0 = m.Parameter(0); Node* p1 = m.Parameter(1); Node* n0; @@ -301,7 +302,7 @@ void Int32BinopInputShapeTester::TestAllInputShapes() { if (i == -2) { n0 = p0; } else if (i == -1) { - n0 = m.LoadFromPointer(&input_a, kMachInt32); + n0 = m.LoadFromPointer(&input_a, MachineType::Int32()); } else { n0 = m.Int32Constant(inputs[i]); } @@ -310,7 +311,7 @@ void Int32BinopInputShapeTester::TestAllInputShapes() { if (j == -2) { n1 = p1; } else if (j == -1) { - n1 = m.LoadFromPointer(&input_b, kMachInt32); + n1 = m.LoadFromPointer(&input_b, MachineType::Int32()); } else { n1 = m.Int32Constant(inputs[j]); } @@ -368,7 +369,8 @@ void Int32BinopInputShapeTester::RunRight( TEST(ParametersEqual) { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); Node* p1 = m.Parameter(1); CHECK(p1); Node* p0 = m.Parameter(0); @@ -482,7 +484,7 @@ TEST(RunHeapNumberConstant) { TEST(RunParam1) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); m.Return(m.Parameter(0)); FOR_INT32_INPUTS(i) { @@ -493,7 +495,8 @@ TEST(RunParam1) { TEST(RunParam2_1) { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); Node* p0 = m.Parameter(0); Node* p1 = m.Parameter(1); m.Return(p0); @@ -507,7 +510,8 @@ TEST(RunParam2_1) { TEST(RunParam2_2) { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); Node* p0 = m.Parameter(0); Node* p1 = m.Parameter(1); m.Return(p1); @@ -522,7 +526,8 @@ TEST(RunParam2_2) { TEST(RunParam3) { for (int i = 0; i < 3; i++) { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); Node* nodes[] = {m.Parameter(0), m.Parameter(1), m.Parameter(2)}; m.Return(nodes[i]); @@ -580,12 +585,13 @@ TEST(RunBufferedRawMachineAssemblerTesterTester) { CHECK_EQ(0x12500000000, m.Call()); } { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); m.Return(m.Parameter(0)); FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(*i, m.Call(*i)); } } { - BufferedRawMachineAssemblerTester<int64_t> m(kMachInt64, kMachInt64); + BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Int64(), + MachineType::Int64()); m.Return(m.Int64Add(m.Parameter(0), m.Parameter(1))); FOR_INT64_INPUTS(i) { FOR_INT64_INPUTS(j) { @@ -595,8 +601,8 @@ TEST(RunBufferedRawMachineAssemblerTesterTester) { } } { - BufferedRawMachineAssemblerTester<int64_t> m(kMachInt64, kMachInt64, - kMachInt64); + BufferedRawMachineAssemblerTester<int64_t> m( + MachineType::Int64(), MachineType::Int64(), MachineType::Int64()); m.Return( m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); FOR_INT64_INPUTS(i) { @@ -608,8 +614,9 @@ TEST(RunBufferedRawMachineAssemblerTesterTester) { } } { - BufferedRawMachineAssemblerTester<int64_t> m(kMachInt64, kMachInt64, - kMachInt64, kMachInt64); + BufferedRawMachineAssemblerTester<int64_t> m( + MachineType::Int64(), MachineType::Int64(), MachineType::Int64(), + MachineType::Int64()); m.Return(m.Int64Add( m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)), m.Parameter(2)), m.Parameter(3))); @@ -625,17 +632,18 @@ TEST(RunBufferedRawMachineAssemblerTesterTester) { { BufferedRawMachineAssemblerTester<void> m; int64_t result; - m.Store(MachineTypeForC<int64_t>(), m.PointerConstant(&result), - m.Int64Constant(0x12500000000), kNoWriteBarrier); + m.Store(MachineTypeForC<int64_t>().representation(), + m.PointerConstant(&result), m.Int64Constant(0x12500000000), + kNoWriteBarrier); m.Return(m.Int32Constant(0)); m.Call(); CHECK_EQ(0x12500000000, result); } { - BufferedRawMachineAssemblerTester<void> m(kMachFloat64); + BufferedRawMachineAssemblerTester<void> m(MachineType::Float64()); double result; - m.Store(MachineTypeForC<double>(), m.PointerConstant(&result), - m.Parameter(0), kNoWriteBarrier); + m.Store(MachineTypeForC<double>().representation(), + m.PointerConstant(&result), m.Parameter(0), kNoWriteBarrier); m.Return(m.Int32Constant(0)); FOR_FLOAT64_INPUTS(i) { m.Call(*i); @@ -643,9 +651,11 @@ TEST(RunBufferedRawMachineAssemblerTesterTester) { } } { - BufferedRawMachineAssemblerTester<void> m(kMachInt64, kMachInt64); + BufferedRawMachineAssemblerTester<void> m(MachineType::Int64(), + MachineType::Int64()); int64_t result; - m.Store(MachineTypeForC<int64_t>(), m.PointerConstant(&result), + m.Store(MachineTypeForC<int64_t>().representation(), + m.PointerConstant(&result), m.Int64Add(m.Parameter(0), m.Parameter(1)), kNoWriteBarrier); m.Return(m.Int32Constant(0)); FOR_INT64_INPUTS(i) { @@ -659,11 +669,11 @@ TEST(RunBufferedRawMachineAssemblerTesterTester) { } } { - BufferedRawMachineAssemblerTester<void> m(kMachInt64, kMachInt64, - kMachInt64); + BufferedRawMachineAssemblerTester<void> m( + MachineType::Int64(), MachineType::Int64(), MachineType::Int64()); int64_t result; m.Store( - MachineTypeForC<int64_t>(), m.PointerConstant(&result), + MachineTypeForC<int64_t>().representation(), m.PointerConstant(&result), m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)), m.Parameter(2)), kNoWriteBarrier); m.Return(m.Int32Constant(0)); @@ -681,10 +691,12 @@ TEST(RunBufferedRawMachineAssemblerTesterTester) { } } { - BufferedRawMachineAssemblerTester<void> m(kMachInt64, kMachInt64, - kMachInt64, kMachInt64); + BufferedRawMachineAssemblerTester<void> m( + MachineType::Int64(), MachineType::Int64(), MachineType::Int64(), + MachineType::Int64()); int64_t result; - m.Store(MachineTypeForC<int64_t>(), m.PointerConstant(&result), + m.Store(MachineTypeForC<int64_t>().representation(), + m.PointerConstant(&result), m.Int64Add(m.Int64Add(m.Int64Add(m.Parameter(0), m.Parameter(1)), m.Parameter(2)), m.Parameter(3)), diff --git a/deps/v8/test/cctest/compiler/codegen-tester.h b/deps/v8/test/cctest/compiler/codegen-tester.h index 55dbecdb9e..56e90c65b7 100644 --- a/deps/v8/test/cctest/compiler/codegen-tester.h +++ b/deps/v8/test/cctest/compiler/codegen-tester.h @@ -20,11 +20,11 @@ class RawMachineAssemblerTester : public HandleAndZoneScope, public CallHelper<ReturnType>, public RawMachineAssembler { public: - RawMachineAssemblerTester(MachineType p0 = kMachNone, - MachineType p1 = kMachNone, - MachineType p2 = kMachNone, - MachineType p3 = kMachNone, - MachineType p4 = kMachNone) + RawMachineAssemblerTester(MachineType p0 = MachineType::None(), + MachineType p1 = MachineType::None(), + MachineType p2 = MachineType::None(), + MachineType p3 = MachineType::None(), + MachineType p4 = MachineType::None()) : HandleAndZoneScope(), CallHelper<ReturnType>( main_isolate(), @@ -36,7 +36,8 @@ class RawMachineAssemblerTester : public HandleAndZoneScope, main_zone(), CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1, p2, p3, p4)), - kMachPtr, InstructionSelector::SupportedMachineOperatorFlags()) {} + MachineType::PointerRepresentation(), + InstructionSelector::SupportedMachineOperatorFlags()) {} void CheckNumber(double expected, Object* number) { CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number)); @@ -77,10 +78,10 @@ template <typename ReturnType> class BufferedRawMachineAssemblerTester : public RawMachineAssemblerTester<int32_t> { public: - BufferedRawMachineAssemblerTester(MachineType p0 = kMachNone, - MachineType p1 = kMachNone, - MachineType p2 = kMachNone, - MachineType p3 = kMachNone) + BufferedRawMachineAssemblerTester(MachineType p0 = MachineType::None(), + MachineType p1 = MachineType::None(), + MachineType p2 = MachineType::None(), + MachineType p3 = MachineType::None()) : BufferedRawMachineAssemblerTester(ComputeParameterCount(p0, p1, p2, p3), p0, p1, p2, p3) {} @@ -101,7 +102,7 @@ class BufferedRawMachineAssemblerTester // Store node is provided as a parameter. By storing the return value in // memory it is possible to return 64 bit values. void Return(Node* input) { - Store(MachineTypeForC<ReturnType>(), + Store(MachineTypeForC<ReturnType>().representation(), RawMachineAssembler::Parameter(return_parameter_index_), input, kNoWriteBarrier); RawMachineAssembler::Return(Int32Constant(1234)); @@ -159,36 +160,45 @@ class BufferedRawMachineAssemblerTester MachineType p0, MachineType p1, MachineType p2, MachineType p3) : RawMachineAssemblerTester<int32_t>( - kMachPtr, p0 == kMachNone ? kMachNone : kMachPtr, - p1 == kMachNone ? kMachNone : kMachPtr, - p2 == kMachNone ? kMachNone : kMachPtr, - p3 == kMachNone ? kMachNone : kMachPtr), + MachineType::Pointer(), + p0 == MachineType::None() ? MachineType::None() + : MachineType::Pointer(), + p1 == MachineType::None() ? MachineType::None() + : MachineType::Pointer(), + p2 == MachineType::None() ? MachineType::None() + : MachineType::Pointer(), + p3 == MachineType::None() ? MachineType::None() + : MachineType::Pointer()), test_graph_signature_( - CSignature::New(main_zone(), kMachInt32, p0, p1, p2, p3)), + CSignature::New(main_zone(), MachineType::Int32(), p0, p1, p2, p3)), return_parameter_index_(return_parameter_index) { - parameter_nodes_[0] = - p0 == kMachNone ? nullptr : Load(p0, RawMachineAssembler::Parameter(0)); - parameter_nodes_[1] = - p1 == kMachNone ? nullptr : Load(p1, RawMachineAssembler::Parameter(1)); - parameter_nodes_[2] = - p2 == kMachNone ? nullptr : Load(p2, RawMachineAssembler::Parameter(2)); - parameter_nodes_[3] = - p3 == kMachNone ? nullptr : Load(p3, RawMachineAssembler::Parameter(3)); + parameter_nodes_[0] = p0 == MachineType::None() + ? nullptr + : Load(p0, RawMachineAssembler::Parameter(0)); + parameter_nodes_[1] = p1 == MachineType::None() + ? nullptr + : Load(p1, RawMachineAssembler::Parameter(1)); + parameter_nodes_[2] = p2 == MachineType::None() + ? nullptr + : Load(p2, RawMachineAssembler::Parameter(2)); + parameter_nodes_[3] = p3 == MachineType::None() + ? nullptr + : Load(p3, RawMachineAssembler::Parameter(3)); } static uint32_t ComputeParameterCount(MachineType p0, MachineType p1, MachineType p2, MachineType p3) { - if (p0 == kMachNone) { + if (p0 == MachineType::None()) { return 0; } - if (p1 == kMachNone) { + if (p1 == MachineType::None()) { return 1; } - if (p2 == kMachNone) { + if (p2 == MachineType::None()) { return 2; } - if (p3 == kMachNone) { + if (p3 == MachineType::None()) { return 3; } return 4; @@ -205,25 +215,34 @@ template <> class BufferedRawMachineAssemblerTester<void> : public RawMachineAssemblerTester<void> { public: - BufferedRawMachineAssemblerTester(MachineType p0 = kMachNone, - MachineType p1 = kMachNone, - MachineType p2 = kMachNone, - MachineType p3 = kMachNone) - : RawMachineAssemblerTester<void>(p0 == kMachNone ? kMachNone : kMachPtr, - p1 == kMachNone ? kMachNone : kMachPtr, - p2 == kMachNone ? kMachNone : kMachPtr, - p3 == kMachNone ? kMachNone : kMachPtr), + BufferedRawMachineAssemblerTester(MachineType p0 = MachineType::None(), + MachineType p1 = MachineType::None(), + MachineType p2 = MachineType::None(), + MachineType p3 = MachineType::None()) + : RawMachineAssemblerTester<void>( + p0 == MachineType::None() ? MachineType::None() + : MachineType::Pointer(), + p1 == MachineType::None() ? MachineType::None() + : MachineType::Pointer(), + p2 == MachineType::None() ? MachineType::None() + : MachineType::Pointer(), + p3 == MachineType::None() ? MachineType::None() + : MachineType::Pointer()), test_graph_signature_( CSignature::New(RawMachineAssemblerTester<void>::main_zone(), - kMachNone, p0, p1, p2, p3)) { - parameter_nodes_[0] = - p0 == kMachNone ? nullptr : Load(p0, RawMachineAssembler::Parameter(0)); - parameter_nodes_[1] = - p1 == kMachNone ? nullptr : Load(p1, RawMachineAssembler::Parameter(1)); - parameter_nodes_[2] = - p2 == kMachNone ? nullptr : Load(p2, RawMachineAssembler::Parameter(2)); - parameter_nodes_[3] = - p3 == kMachNone ? nullptr : Load(p3, RawMachineAssembler::Parameter(3)); + MachineType::None(), p0, p1, p2, p3)) { + parameter_nodes_[0] = p0 == MachineType::None() + ? nullptr + : Load(p0, RawMachineAssembler::Parameter(0)); + parameter_nodes_[1] = p1 == MachineType::None() + ? nullptr + : Load(p1, RawMachineAssembler::Parameter(1)); + parameter_nodes_[2] = p2 == MachineType::None() + ? nullptr + : Load(p2, RawMachineAssembler::Parameter(2)); + parameter_nodes_[3] = p3 == MachineType::None() + ? nullptr + : Load(p3, RawMachineAssembler::Parameter(3)); } @@ -283,13 +302,15 @@ static const int32_t CHECK_VALUE = 0x99BEEDCE; // TODO(titzer): use the C-style calling convention, or any register-based // calling convention for binop tests. -template <typename CType, MachineType rep, bool use_result_buffer> +template <typename CType, bool use_result_buffer> class BinopTester { public: - explicit BinopTester(RawMachineAssemblerTester<int32_t>* tester) + explicit BinopTester(RawMachineAssemblerTester<int32_t>* tester, + MachineType rep) : T(tester), param0(T->LoadFromPointer(&p0, rep)), param1(T->LoadFromPointer(&p1, rep)), + rep(rep), p0(static_cast<CType>(0)), p1(static_cast<CType>(0)), result(static_cast<CType>(0)) {} @@ -311,8 +332,8 @@ class BinopTester { void AddReturn(Node* val) { if (use_result_buffer) { - T->Store(rep, T->PointerConstant(&result), T->Int32Constant(0), val, - kNoWriteBarrier); + T->Store(rep.representation(), T->PointerConstant(&result), + T->Int32Constant(0), val, kNoWriteBarrier); T->Return(T->Int32Constant(CHECK_VALUE)); } else { T->Return(val); @@ -331,6 +352,7 @@ class BinopTester { } protected: + MachineType rep; CType p0; CType p1; CType result; @@ -339,21 +361,31 @@ class BinopTester { // A helper class for testing code sequences that take two int parameters and // return an int value. -class Int32BinopTester - : public BinopTester<int32_t, kMachInt32, USE_RETURN_REGISTER> { +class Int32BinopTester : public BinopTester<int32_t, USE_RETURN_REGISTER> { public: explicit Int32BinopTester(RawMachineAssemblerTester<int32_t>* tester) - : BinopTester<int32_t, kMachInt32, USE_RETURN_REGISTER>(tester) {} + : BinopTester<int32_t, USE_RETURN_REGISTER>(tester, + MachineType::Int32()) {} +}; + + +// A helper class for testing code sequences that take two int parameters and +// return an int value. +class Int64BinopTester : public BinopTester<int64_t, USE_RETURN_REGISTER> { + public: + explicit Int64BinopTester(RawMachineAssemblerTester<int32_t>* tester) + : BinopTester<int64_t, USE_RETURN_REGISTER>(tester, + MachineType::Int64()) {} }; // A helper class for testing code sequences that take two uint parameters and // return an uint value. -class Uint32BinopTester - : public BinopTester<uint32_t, kMachUint32, USE_RETURN_REGISTER> { +class Uint32BinopTester : public BinopTester<uint32_t, USE_RETURN_REGISTER> { public: explicit Uint32BinopTester(RawMachineAssemblerTester<int32_t>* tester) - : BinopTester<uint32_t, kMachUint32, USE_RETURN_REGISTER>(tester) {} + : BinopTester<uint32_t, USE_RETURN_REGISTER>(tester, + MachineType::Uint32()) {} uint32_t call(uint32_t a0, uint32_t a1) { p0 = a0; @@ -366,22 +398,21 @@ class Uint32BinopTester // A helper class for testing code sequences that take two float parameters and // return a float value. // TODO(titzer): figure out how to return floats correctly on ia32. -class Float32BinopTester - : public BinopTester<float, kMachFloat32, USE_RESULT_BUFFER> { +class Float32BinopTester : public BinopTester<float, USE_RESULT_BUFFER> { public: explicit Float32BinopTester(RawMachineAssemblerTester<int32_t>* tester) - : BinopTester<float, kMachFloat32, USE_RESULT_BUFFER>(tester) {} + : BinopTester<float, USE_RESULT_BUFFER>(tester, MachineType::Float32()) {} }; // A helper class for testing code sequences that take two double parameters and // return a double value. // TODO(titzer): figure out how to return doubles correctly on ia32. -class Float64BinopTester - : public BinopTester<double, kMachFloat64, USE_RESULT_BUFFER> { +class Float64BinopTester : public BinopTester<double, USE_RESULT_BUFFER> { public: explicit Float64BinopTester(RawMachineAssemblerTester<int32_t>* tester) - : BinopTester<double, kMachFloat64, USE_RESULT_BUFFER>(tester) {} + : BinopTester<double, USE_RESULT_BUFFER>(tester, MachineType::Float64()) { + } }; @@ -389,22 +420,22 @@ class Float64BinopTester // and return a pointer value. // TODO(titzer): pick word size of pointers based on V8_TARGET. template <typename Type> -class PointerBinopTester - : public BinopTester<Type*, kMachPtr, USE_RETURN_REGISTER> { +class PointerBinopTester : public BinopTester<Type*, USE_RETURN_REGISTER> { public: explicit PointerBinopTester(RawMachineAssemblerTester<int32_t>* tester) - : BinopTester<Type*, kMachPtr, USE_RETURN_REGISTER>(tester) {} + : BinopTester<Type*, USE_RETURN_REGISTER>(tester, + MachineType::Pointer()) {} }; // A helper class for testing code sequences that take two tagged parameters and // return a tagged value. template <typename Type> -class TaggedBinopTester - : public BinopTester<Type*, kMachAnyTagged, USE_RETURN_REGISTER> { +class TaggedBinopTester : public BinopTester<Type*, USE_RETURN_REGISTER> { public: explicit TaggedBinopTester(RawMachineAssemblerTester<int32_t>* tester) - : BinopTester<Type*, kMachAnyTagged, USE_RETURN_REGISTER>(tester) {} + : BinopTester<Type*, USE_RETURN_REGISTER>(tester, + MachineType::AnyTagged()) {} }; // A helper class for testing compares. Wraps a machine opcode and provides @@ -512,7 +543,7 @@ static inline void CheckFloatEq(volatile float x, volatile float y) { if (std::isnan(x)) { CHECK(std::isnan(y)); } else { - CHECK(x == y); + CHECK_EQ(x, y); } } diff --git a/deps/v8/test/cctest/compiler/function-tester.h b/deps/v8/test/cctest/compiler/function-tester.h index 8741808d82..2fcd35398c 100644 --- a/deps/v8/test/cctest/compiler/function-tester.h +++ b/deps/v8/test/cctest/compiler/function-tester.h @@ -5,7 +5,8 @@ #ifndef V8_CCTEST_COMPILER_FUNCTION_TESTER_H_ #define V8_CCTEST_COMPILER_FUNCTION_TESTER_H_ -#include "src/ast-numbering.h" +#include "src/ast/ast-numbering.h" +#include "src/ast/scopes.h" #include "src/compiler.h" #include "src/compiler/linkage.h" #include "src/compiler/pipeline.h" @@ -13,9 +14,8 @@ #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" +#include "src/parsing/parser.h" +#include "src/parsing/rewriter.h" #include "test/cctest/cctest.h" namespace v8 { @@ -35,18 +35,30 @@ class FunctionTester : public InitializedHandleScope { CHECK_EQ(0u, flags_ & ~supported_flags); } - // TODO(turbofan): generalize FunctionTester to work with N arguments. Now, it - // can handle up to four. - explicit FunctionTester(Graph* graph) + FunctionTester(Graph* graph, int param_count) : isolate(main_isolate()), - function(NewFunction("(function(a,b,c,d){})")), + function(NewFunction(BuildFunction(param_count).c_str())), flags_(0) { CompileGraph(graph); } + FunctionTester(const CallInterfaceDescriptor& descriptor, Handle<Code> code) + : isolate(main_isolate()), + function( + (FLAG_allow_natives_syntax = true, + NewFunction(BuildFunctionFromDescriptor(descriptor).c_str()))), + flags_(0) { + Compile(function); + function->ReplaceCode(*code); + } + Isolate* isolate; Handle<JSFunction> function; + MaybeHandle<Object> Call() { + return Execution::Call(isolate, function, undefined(), 0, nullptr); + } + MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b) { Handle<Object> args[] = {a, b}; return Execution::Call(isolate, function, undefined(), 2, args); @@ -124,8 +136,8 @@ class FunctionTester : public InitializedHandleScope { } Handle<JSObject> NewObject(const char* source) { - return v8::Utils::OpenHandle( - *v8::Local<v8::Object>::Cast(CompileRun(source))); + return Handle<JSObject>::cast(v8::Utils::OpenHandle( + *v8::Local<v8::Object>::Cast(CompileRun(source)))); } Handle<String> Val(const char* string) { @@ -180,10 +192,10 @@ class FunctionTester : public InitializedHandleScope { return function; } - static Handle<JSFunction> ForMachineGraph(Graph* graph) { + static Handle<JSFunction> ForMachineGraph(Graph* graph, int param_count) { JSFunction* p = NULL; { // because of the implicit handle scope of FunctionTester. - FunctionTester f(graph); + FunctionTester f(graph, param_count); p = *f.function; } return Handle<JSFunction>(p); // allocated in outer handle scope. @@ -192,6 +204,25 @@ class FunctionTester : public InitializedHandleScope { private: uint32_t flags_; + std::string BuildFunction(int param_count) { + std::string function_string = "(function("; + if (param_count > 0) { + char next = 'a'; + function_string += next; + while (param_count-- > 0) { + function_string += ','; + function_string += ++next; + } + } + function_string += "){})"; + return function_string; + } + + std::string BuildFunctionFromDescriptor( + const CallInterfaceDescriptor& descriptor) { + return BuildFunction(descriptor.GetParameterCount()); + } + // 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) { diff --git a/deps/v8/test/cctest/compiler/graph-builder-tester.h b/deps/v8/test/cctest/compiler/graph-builder-tester.h index ea2c3ad139..de2713a5ac 100644 --- a/deps/v8/test/cctest/compiler/graph-builder-tester.h +++ b/deps/v8/test/cctest/compiler/graph-builder-tester.h @@ -24,7 +24,7 @@ class GraphAndBuilders { explicit GraphAndBuilders(Zone* zone) : main_graph_(new (zone) Graph(zone)), main_common_(zone), - main_machine_(zone, kMachPtr, + main_machine_(zone, MachineType::PointerRepresentation(), InstructionSelector::SupportedMachineOperatorFlags()), main_simplified_(zone) {} @@ -48,11 +48,11 @@ class GraphBuilderTester : public HandleAndZoneScope, public GraphAndBuilders, public CallHelper<ReturnType> { public: - explicit GraphBuilderTester(MachineType p0 = kMachNone, - MachineType p1 = kMachNone, - MachineType p2 = kMachNone, - MachineType p3 = kMachNone, - MachineType p4 = kMachNone) + explicit GraphBuilderTester(MachineType p0 = MachineType::None(), + MachineType p1 = MachineType::None(), + MachineType p2 = MachineType::None(), + MachineType p3 = MachineType::None(), + MachineType p4 = MachineType::None()) : GraphAndBuilders(main_zone()), CallHelper<ReturnType>( main_isolate(), @@ -68,7 +68,7 @@ class GraphBuilderTester : public HandleAndZoneScope, void GenerateCode() { Generate(); } Node* Parameter(size_t index) { - DCHECK(index < parameter_count()); + CHECK_LT(index, parameter_count()); return parameters_[index]; } @@ -77,7 +77,7 @@ class GraphBuilderTester : public HandleAndZoneScope, // Initialize graph and builder. void Begin(int num_parameters) { - DCHECK(graph()->start() == NULL); + CHECK_NULL(graph()->start()); Node* start = graph()->NewNode(common()->Start(num_parameters + 3)); graph()->SetStart(start); effect_ = start; @@ -235,15 +235,15 @@ class GraphBuilderTester : public HandleAndZoneScope, protected: Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs) { - DCHECK(op->ValueInputCount() == value_input_count); + CHECK_EQ(op->ValueInputCount(), value_input_count); - DCHECK(!OperatorProperties::HasContextInput(op)); - DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op)); + CHECK(!OperatorProperties::HasContextInput(op)); + CHECK_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); + CHECK_LT(op->ControlInputCount(), 2); + CHECK_LT(op->EffectInputCount(), 2); Node* result = NULL; if (!has_control && !has_effect) { 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 1f4d87f18d..17400abe53 100644 --- a/deps/v8/test/cctest/compiler/test-basic-block-profiler.cc +++ b/deps/v8/test/cctest/compiler/test-basic-block-profiler.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/basic-block-profiler.h" #include "test/cctest/cctest.h" #include "test/cctest/compiler/codegen-tester.h" @@ -13,11 +10,10 @@ namespace v8 { namespace internal { namespace compiler { -typedef RawMachineAssembler::Label MLabel; - class BasicBlockProfilerTest : public RawMachineAssemblerTester<int32_t> { public: - BasicBlockProfilerTest() : RawMachineAssemblerTester<int32_t>(kMachInt32) { + BasicBlockProfilerTest() + : RawMachineAssemblerTester<int32_t>(MachineType::Int32()) { FLAG_turbo_profiling = true; } @@ -41,7 +37,7 @@ class BasicBlockProfilerTest : public RawMachineAssemblerTester<int32_t> { TEST(ProfileDiamond) { BasicBlockProfilerTest m; - MLabel blocka, blockb, end; + RawMachineLabel blocka, blockb, end; m.Branch(m.Parameter(0), &blocka, &blockb); m.Bind(&blocka); m.Goto(&end); @@ -81,12 +77,12 @@ TEST(ProfileDiamond) { TEST(ProfileLoop) { BasicBlockProfilerTest m; - MLabel header, body, end; + RawMachineLabel header, body, end; Node* one = m.Int32Constant(1); m.Goto(&header); m.Bind(&header); - Node* count = m.Phi(kMachInt32, m.Parameter(0), one); + Node* count = m.Phi(MachineRepresentation::kWord32, m.Parameter(0), one); m.Branch(count, &body, &end); m.Bind(&body); diff --git a/deps/v8/test/cctest/compiler/test-branch-combine.cc b/deps/v8/test/cctest/compiler/test-branch-combine.cc index 984c7130ba..c3b4308a93 100644 --- a/deps/v8/test/cctest/compiler/test-branch-combine.cc +++ b/deps/v8/test/cctest/compiler/test-branch-combine.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "test/cctest/cctest.h" #include "test/cctest/compiler/codegen-tester.h" #include "test/cctest/compiler/value-helper.h" @@ -13,8 +10,6 @@ namespace v8 { namespace internal { namespace compiler { -typedef RawMachineAssembler::Label MLabel; - static IrOpcode::Value int32cmp_opcodes[] = { IrOpcode::kWord32Equal, IrOpcode::kInt32LessThan, IrOpcode::kInt32LessThanOrEqual, IrOpcode::kUint32LessThan, @@ -23,12 +18,12 @@ static IrOpcode::Value int32cmp_opcodes[] = { TEST(BranchCombineWord32EqualZero_1) { // Test combining a branch with x == 0 - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); int32_t eq_constant = -1033; int32_t ne_constant = 825118; Node* p0 = m.Parameter(0); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch(m.Word32Equal(p0, m.Int32Constant(0)), &blocka, &blockb); m.Bind(&blocka); m.Return(m.Int32Constant(eq_constant)); @@ -49,9 +44,9 @@ TEST(BranchCombineWord32EqualZero_chain) { int32_t ne_constant = 815118; for (int k = 0; k < 6; k++) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); Node* p0 = m.Parameter(0); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; Node* cond = p0; for (int j = 0; j < k; j++) { cond = m.Word32Equal(cond, m.Int32Constant(0)); @@ -74,12 +69,12 @@ TEST(BranchCombineWord32EqualZero_chain) { TEST(BranchCombineInt32LessThanZero_1) { // Test combining a branch with x < 0 - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); int32_t eq_constant = -1433; int32_t ne_constant = 845118; Node* p0 = m.Parameter(0); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch(m.Int32LessThan(p0, m.Int32Constant(0)), &blocka, &blockb); m.Bind(&blocka); m.Return(m.Int32Constant(eq_constant)); @@ -96,12 +91,12 @@ TEST(BranchCombineInt32LessThanZero_1) { TEST(BranchCombineUint32LessThan100_1) { // Test combining a branch with x < 100 - RawMachineAssemblerTester<int32_t> m(kMachUint32); + RawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); int32_t eq_constant = 1471; int32_t ne_constant = 88845718; Node* p0 = m.Parameter(0); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch(m.Uint32LessThan(p0, m.Int32Constant(100)), &blocka, &blockb); m.Bind(&blocka); m.Return(m.Int32Constant(eq_constant)); @@ -118,12 +113,12 @@ TEST(BranchCombineUint32LessThan100_1) { TEST(BranchCombineUint32LessThanOrEqual100_1) { // Test combining a branch with x <= 100 - RawMachineAssemblerTester<int32_t> m(kMachUint32); + RawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); int32_t eq_constant = 1479; int32_t ne_constant = 77845719; Node* p0 = m.Parameter(0); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch(m.Uint32LessThanOrEqual(p0, m.Int32Constant(100)), &blocka, &blockb); m.Bind(&blocka); m.Return(m.Int32Constant(eq_constant)); @@ -140,12 +135,12 @@ TEST(BranchCombineUint32LessThanOrEqual100_1) { TEST(BranchCombineZeroLessThanInt32_1) { // Test combining a branch with 0 < x - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); int32_t eq_constant = -2033; int32_t ne_constant = 225118; Node* p0 = m.Parameter(0); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch(m.Int32LessThan(m.Int32Constant(0), p0), &blocka, &blockb); m.Bind(&blocka); m.Return(m.Int32Constant(eq_constant)); @@ -162,12 +157,12 @@ TEST(BranchCombineZeroLessThanInt32_1) { TEST(BranchCombineInt32GreaterThanZero_1) { // Test combining a branch with x > 0 - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); int32_t eq_constant = -1073; int32_t ne_constant = 825178; Node* p0 = m.Parameter(0); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch(m.Int32GreaterThan(p0, m.Int32Constant(0)), &blocka, &blockb); m.Bind(&blocka); m.Return(m.Int32Constant(eq_constant)); @@ -184,13 +179,14 @@ TEST(BranchCombineInt32GreaterThanZero_1) { TEST(BranchCombineWord32EqualP) { // Test combining a branch with an Word32Equal. - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); int32_t eq_constant = -1035; int32_t ne_constant = 825018; Node* p0 = m.Parameter(0); Node* p1 = m.Parameter(1); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch(m.Word32Equal(p0, p1), &blocka, &blockb); m.Bind(&blocka); m.Return(m.Int32Constant(eq_constant)); @@ -214,13 +210,13 @@ TEST(BranchCombineWord32EqualI) { for (int left = 0; left < 2; left++) { FOR_INT32_INPUTS(i) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); int32_t a = *i; Node* p0 = m.Int32Constant(a); Node* p1 = m.Parameter(0); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; if (left == 1) m.Branch(m.Word32Equal(p0, p1), &blocka, &blockb); if (left == 0) m.Branch(m.Word32Equal(p1, p0), &blocka, &blockb); m.Bind(&blocka); @@ -243,11 +239,12 @@ TEST(BranchCombineInt32CmpP) { int32_t ne_constant = 725018; for (int op = 0; op < 2; op++) { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); Node* p0 = m.Parameter(0); Node* p1 = m.Parameter(1); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; if (op == 0) m.Branch(m.Int32LessThan(p0, p1), &blocka, &blockb); if (op == 1) m.Branch(m.Int32LessThanOrEqual(p0, p1), &blocka, &blockb); m.Bind(&blocka); @@ -275,12 +272,12 @@ TEST(BranchCombineInt32CmpI) { for (int op = 0; op < 2; op++) { FOR_INT32_INPUTS(i) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); int32_t a = *i; Node* p0 = m.Int32Constant(a); Node* p1 = m.Parameter(0); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; if (op == 0) m.Branch(m.Int32LessThan(p0, p1), &blocka, &blockb); if (op == 1) m.Branch(m.Int32LessThanOrEqual(p0, p1), &blocka, &blockb); m.Bind(&blocka); @@ -336,7 +333,7 @@ class CmpBranchGen : public BinopGen<int32_t> { : w(opcode), invert(i), true_first(t), eq_constant(eq), ne_constant(ne) {} virtual void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) { - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; Node* cond = w.MakeNode(m, a, b); if (invert) cond = m->Word32Equal(cond, m->Int32Constant(0)); m->Branch(cond, &blocka, &blockb); @@ -432,10 +429,10 @@ TEST(BranchCombineFloat64Compares) { CompareWrapper cmp = cmps[c]; for (int invert = 0; invert < 2; invert++) { RawMachineAssemblerTester<int32_t> m; - Node* a = m.LoadFromPointer(&input_a, kMachFloat64); - Node* b = m.LoadFromPointer(&input_b, kMachFloat64); + Node* a = m.LoadFromPointer(&input_a, MachineType::Float64()); + Node* b = m.LoadFromPointer(&input_b, MachineType::Float64()); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; Node* cond = cmp.MakeNode(&m, a, b); if (invert) cond = m.Word32Equal(cond, m.Int32Constant(0)); m.Branch(cond, &blocka, &blockb); diff --git a/deps/v8/test/cctest/compiler/test-changes-lowering.cc b/deps/v8/test/cctest/compiler/test-changes-lowering.cc index 028ac4b7c8..e850da7735 100644 --- a/deps/v8/test/cctest/compiler/test-changes-lowering.cc +++ b/deps/v8/test/cctest/compiler/test-changes-lowering.cc @@ -2,11 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <limits> +#include "src/ast/scopes.h" #include "src/compiler/change-lowering.h" #include "src/compiler/control-builders.h" #include "src/compiler/js-graph.h" @@ -18,9 +16,8 @@ #include "src/compiler/verifier.h" #include "src/execution.h" #include "src/globals.h" -#include "src/parser.h" -#include "src/rewriter.h" -#include "src/scopes.h" +#include "src/parsing/parser.h" +#include "src/parsing/rewriter.h" #include "test/cctest/cctest.h" #include "test/cctest/compiler/codegen-tester.h" #include "test/cctest/compiler/function-tester.h" @@ -34,7 +31,7 @@ namespace compiler { template <typename ReturnType> class ChangesLoweringTester : public GraphBuilderTester<ReturnType> { public: - explicit ChangesLoweringTester(MachineType p0 = kMachNone) + explicit ChangesLoweringTester(MachineType p0 = MachineType::None()) : GraphBuilderTester<ReturnType>(p0), javascript(this->zone()), jsgraph(this->isolate(), this->graph(), this->common(), &javascript, @@ -63,22 +60,22 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> { void StoreFloat64(Node* node, double* ptr) { Node* ptr_node = this->PointerConstant(ptr); - this->Store(kMachFloat64, ptr_node, node); + this->Store(MachineType::Float64(), ptr_node, node); } Node* LoadInt32(int32_t* ptr) { Node* ptr_node = this->PointerConstant(ptr); - return this->Load(kMachInt32, ptr_node); + return this->Load(MachineType::Int32(), ptr_node); } Node* LoadUint32(uint32_t* ptr) { Node* ptr_node = this->PointerConstant(ptr); - return this->Load(kMachUint32, ptr_node); + return this->Load(MachineType::Uint32(), ptr_node); } Node* LoadFloat64(double* ptr) { Node* ptr_node = this->PointerConstant(ptr); - return this->Load(kMachFloat64, ptr_node); + return this->Load(MachineType::Float64(), ptr_node); } void CheckNumber(double expected, Object* number) { @@ -148,7 +145,7 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> { TEST(RunChangeTaggedToInt32) { // Build and lower a graph by hand. - ChangesLoweringTester<int32_t> t(kMachAnyTagged); + ChangesLoweringTester<int32_t> t(MachineType::AnyTagged()); t.BuildAndLower(t.simplified()->ChangeTaggedToInt32()); FOR_INT32_INPUTS(i) { @@ -176,7 +173,7 @@ TEST(RunChangeTaggedToInt32) { TEST(RunChangeTaggedToUint32) { // Build and lower a graph by hand. - ChangesLoweringTester<uint32_t> t(kMachAnyTagged); + ChangesLoweringTester<uint32_t> t(MachineType::AnyTagged()); t.BuildAndLower(t.simplified()->ChangeTaggedToUint32()); FOR_UINT32_INPUTS(i) { @@ -203,13 +200,13 @@ TEST(RunChangeTaggedToUint32) { TEST(RunChangeTaggedToFloat64) { - ChangesLoweringTester<int32_t> t(kMachAnyTagged); + ChangesLoweringTester<int32_t> t(MachineType::AnyTagged()); double result; - t.BuildStoreAndLower( - t.simplified()->ChangeTaggedToFloat64(), - t.machine()->Store(StoreRepresentation(kMachFloat64, kNoWriteBarrier)), - &result); + t.BuildStoreAndLower(t.simplified()->ChangeTaggedToFloat64(), + t.machine()->Store(StoreRepresentation( + MachineRepresentation::kFloat64, kNoWriteBarrier)), + &result); { FOR_INT32_INPUTS(i) { @@ -254,7 +251,7 @@ TEST(RunChangeTaggedToFloat64) { TEST(RunChangeBoolToBit) { - ChangesLoweringTester<int32_t> t(kMachAnyTagged); + ChangesLoweringTester<int32_t> t(MachineType::AnyTagged()); t.BuildAndLower(t.simplified()->ChangeBoolToBit()); { @@ -272,7 +269,7 @@ TEST(RunChangeBoolToBit) { TEST(RunChangeBitToBool) { - ChangesLoweringTester<Object*> t(kMachInt32); + ChangesLoweringTester<Object*> t(MachineType::Int32()); t.BuildAndLower(t.simplified()->ChangeBitToBool()); { diff --git a/deps/v8/test/cctest/compiler/test-code-stub-assembler.cc b/deps/v8/test/cctest/compiler/test-code-stub-assembler.cc new file mode 100644 index 0000000000..d7a7a8198a --- /dev/null +++ b/deps/v8/test/cctest/compiler/test-code-stub-assembler.cc @@ -0,0 +1,125 @@ +// 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/interface-descriptors.h" +#include "src/isolate.h" +#include "test/cctest/compiler/function-tester.h" + +namespace v8 { +namespace internal { +namespace compiler { + + +class CodeStubAssemblerTester : public CodeStubAssembler { + public: + CodeStubAssemblerTester(Isolate* isolate, + const CallInterfaceDescriptor& descriptor) + : CodeStubAssembler(isolate, isolate->runtime_zone(), descriptor, + Code::STUB, "test"), + scope_(isolate) {} + + private: + HandleScope scope_; + LocalContext context_; +}; + + +TEST(SimpleSmiReturn) { + Isolate* isolate(CcTest::InitIsolateOnce()); + VoidDescriptor descriptor(isolate); + CodeStubAssemblerTester m(isolate, descriptor); + m.Return(m.SmiTag(m.Int32Constant(37))); + Handle<Code> code = m.GenerateCode(); + FunctionTester ft(descriptor, code); + MaybeHandle<Object> result = ft.Call(); + CHECK_EQ(37, Handle<Smi>::cast(result.ToHandleChecked())->value()); +} + + +TEST(SimpleIntPtrReturn) { + Isolate* isolate(CcTest::InitIsolateOnce()); + VoidDescriptor descriptor(isolate); + CodeStubAssemblerTester m(isolate, descriptor); + int test; + m.Return(m.IntPtrConstant(reinterpret_cast<intptr_t>(&test))); + Handle<Code> code = m.GenerateCode(); + FunctionTester ft(descriptor, code); + MaybeHandle<Object> result = ft.Call(); + CHECK_EQ(reinterpret_cast<intptr_t>(&test), + reinterpret_cast<intptr_t>(*result.ToHandleChecked())); +} + + +TEST(SimpleDoubleReturn) { + Isolate* isolate(CcTest::InitIsolateOnce()); + VoidDescriptor descriptor(isolate); + CodeStubAssemblerTester m(isolate, descriptor); + m.Return(m.NumberConstant(0.5)); + Handle<Code> code = m.GenerateCode(); + FunctionTester ft(descriptor, code); + MaybeHandle<Object> result = ft.Call(); + CHECK_EQ(0.5, Handle<HeapNumber>::cast(result.ToHandleChecked())->value()); +} + + +TEST(SimpleCallRuntime1Arg) { + Isolate* isolate(CcTest::InitIsolateOnce()); + VoidDescriptor descriptor(isolate); + CodeStubAssemblerTester m(isolate, descriptor); + Node* context = m.HeapConstant(Handle<Context>(isolate->native_context())); + Node* b = m.SmiTag(m.Int32Constant(256)); + m.Return(m.CallRuntime(Runtime::kMathSqrt, context, b)); + Handle<Code> code = m.GenerateCode(); + FunctionTester ft(descriptor, code); + MaybeHandle<Object> result = ft.Call(); + CHECK_EQ(16, Handle<Smi>::cast(result.ToHandleChecked())->value()); +} + + +TEST(SimpleTailCallRuntime1Arg) { + Isolate* isolate(CcTest::InitIsolateOnce()); + VoidDescriptor descriptor(isolate); + CodeStubAssemblerTester m(isolate, descriptor); + Node* context = m.HeapConstant(Handle<Context>(isolate->native_context())); + Node* b = m.SmiTag(m.Int32Constant(256)); + m.TailCallRuntime(Runtime::kMathSqrt, context, b); + Handle<Code> code = m.GenerateCode(); + FunctionTester ft(descriptor, code); + MaybeHandle<Object> result = ft.Call(); + CHECK_EQ(16, Handle<Smi>::cast(result.ToHandleChecked())->value()); +} + + +TEST(SimpleCallRuntime2Arg) { + Isolate* isolate(CcTest::InitIsolateOnce()); + VoidDescriptor descriptor(isolate); + CodeStubAssemblerTester m(isolate, descriptor); + Node* context = m.HeapConstant(Handle<Context>(isolate->native_context())); + Node* a = m.SmiTag(m.Int32Constant(2)); + Node* b = m.SmiTag(m.Int32Constant(4)); + m.Return(m.CallRuntime(Runtime::kMathPow, context, a, b)); + Handle<Code> code = m.GenerateCode(); + FunctionTester ft(descriptor, code); + MaybeHandle<Object> result = ft.Call(); + CHECK_EQ(16, Handle<Smi>::cast(result.ToHandleChecked())->value()); +} + + +TEST(SimpleTailCallRuntime2Arg) { + Isolate* isolate(CcTest::InitIsolateOnce()); + VoidDescriptor descriptor(isolate); + CodeStubAssemblerTester m(isolate, descriptor); + Node* context = m.HeapConstant(Handle<Context>(isolate->native_context())); + Node* a = m.SmiTag(m.Int32Constant(2)); + Node* b = m.SmiTag(m.Int32Constant(4)); + m.TailCallRuntime(Runtime::kMathPow, context, a, b); + Handle<Code> code = m.GenerateCode(); + FunctionTester ft(descriptor, code); + MaybeHandle<Object> result = ft.Call(); + CHECK_EQ(16, Handle<Smi>::cast(result.ToHandleChecked())->value()); +} + +} // namespace compiler +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/cctest/compiler/test-gap-resolver.cc b/deps/v8/test/cctest/compiler/test-gap-resolver.cc index a0e1d6023b..7f85088809 100644 --- a/deps/v8/test/cctest/compiler/test-gap-resolver.cc +++ b/deps/v8/test/cctest/compiler/test-gap-resolver.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/compiler/gap-resolver.h" #include "src/base/utils/random-number-generator.h" @@ -89,7 +86,7 @@ class InterpreterState { } else { index = LocationOperand::cast(op).index(); } - is_float = IsFloatingPoint(LocationOperand::cast(op).machine_type()); + is_float = IsFloatingPoint(LocationOperand::cast(op).representation()); kind = LocationOperand::cast(op).location_kind(); } else { index = ConstantOperand::cast(op).virtual_register(); @@ -181,24 +178,24 @@ class ParallelMoveCreator : public HandleAndZoneScope { } private: - MachineType RandomType() { + MachineRepresentation RandomRepresentation() { int index = rng_->NextInt(3); switch (index) { case 0: - return kRepWord32; + return MachineRepresentation::kWord32; case 1: - return kRepWord64; + return MachineRepresentation::kWord64; case 2: - return kRepTagged; + return MachineRepresentation::kTagged; } UNREACHABLE(); - return kMachNone; + return MachineRepresentation::kNone; } - MachineType RandomDoubleType() { + MachineRepresentation RandomDoubleRepresentation() { int index = rng_->NextInt(2); - if (index == 0) return kRepFloat64; - return kRepFloat32; + if (index == 0) return MachineRepresentation::kFloat64; + return MachineRepresentation::kFloat32; } InstructionOperand CreateRandomOperand(bool is_source) { @@ -206,24 +203,25 @@ class ParallelMoveCreator : public HandleAndZoneScope { // destination can't be Constant. switch (rng_->NextInt(is_source ? 7 : 6)) { case 0: - return AllocatedOperand(LocationOperand::STACK_SLOT, RandomType(), - index); + return AllocatedOperand(LocationOperand::STACK_SLOT, + RandomRepresentation(), index); case 1: - return AllocatedOperand(LocationOperand::STACK_SLOT, RandomDoubleType(), - index); + return AllocatedOperand(LocationOperand::STACK_SLOT, + RandomDoubleRepresentation(), index); case 2: - return AllocatedOperand(LocationOperand::REGISTER, RandomType(), index); + return AllocatedOperand(LocationOperand::REGISTER, + RandomRepresentation(), index); case 3: - return AllocatedOperand(LocationOperand::REGISTER, RandomDoubleType(), - index); + return AllocatedOperand(LocationOperand::REGISTER, + RandomDoubleRepresentation(), index); case 4: return ExplicitOperand( - LocationOperand::REGISTER, RandomType(), + LocationOperand::REGISTER, RandomRepresentation(), RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN) ->GetAllocatableGeneralCode(1)); case 5: return ExplicitOperand( - LocationOperand::STACK_SLOT, RandomType(), + LocationOperand::STACK_SLOT, RandomRepresentation(), RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN) ->GetAllocatableGeneralCode(index)); case 6: diff --git a/deps/v8/test/cctest/compiler/test-graph-visualizer.cc b/deps/v8/test/cctest/compiler/test-graph-visualizer.cc index 9ce34cd64a..48be46ce5f 100644 --- a/deps/v8/test/cctest/compiler/test-graph-visualizer.cc +++ b/deps/v8/test/cctest/compiler/test-graph-visualizer.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/compiler/common-operator.h" #include "src/compiler/graph.h" #include "src/compiler/graph-visualizer.h" @@ -36,12 +33,12 @@ TEST(NodeWithNullInputReachableFromEnd) { Node* start = graph.NewNode(common.Start(0)); graph.SetStart(start); Node* k = graph.NewNode(common.Int32Constant(0)); - Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 1), k, start); + Node* phi = + graph.NewNode(common.Phi(MachineRepresentation::kTagged, 1), k, start); phi->ReplaceInput(0, NULL); graph.SetEnd(phi); OFStream os(stdout); - os << AsDOT(graph); SourcePositionTable table(&graph); os << AsJSON(graph, &table); } @@ -55,12 +52,12 @@ TEST(NodeWithNullControlReachableFromEnd) { Node* start = graph.NewNode(common.Start(0)); graph.SetStart(start); Node* k = graph.NewNode(common.Int32Constant(0)); - Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 1), k, start); + Node* phi = + graph.NewNode(common.Phi(MachineRepresentation::kTagged, 1), k, start); phi->ReplaceInput(1, NULL); graph.SetEnd(phi); OFStream os(stdout); - os << AsDOT(graph); SourcePositionTable table(&graph); os << AsJSON(graph, &table); } @@ -74,12 +71,12 @@ TEST(NodeWithNullInputReachableFromStart) { Node* start = graph.NewNode(common.Start(0)); graph.SetStart(start); Node* k = graph.NewNode(common.Int32Constant(0)); - Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 1), k, start); + Node* phi = + graph.NewNode(common.Phi(MachineRepresentation::kTagged, 1), k, start); phi->ReplaceInput(0, NULL); graph.SetEnd(start); OFStream os(stdout); - os << AsDOT(graph); SourcePositionTable table(&graph); os << AsJSON(graph, &table); } @@ -97,7 +94,6 @@ TEST(NodeWithNullControlReachableFromStart) { graph.SetEnd(merge); OFStream os(stdout); - os << AsDOT(graph); SourcePositionTable table(&graph); os << AsJSON(graph, &table); } @@ -125,7 +121,6 @@ TEST(NodeNetworkOfDummiesReachableFromEnd) { graph.SetEnd(end); OFStream os(stdout); - os << AsDOT(graph); SourcePositionTable table(&graph); os << AsJSON(graph, &table); } diff --git a/deps/v8/test/cctest/compiler/test-instruction.cc b/deps/v8/test/cctest/compiler/test-instruction.cc index 53562953ee..4de3373dad 100644 --- a/deps/v8/test/cctest/compiler/test-instruction.cc +++ b/deps/v8/test/cctest/compiler/test-instruction.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/compiler/code-generator.h" #include "src/compiler/common-operator.h" #include "src/compiler/graph.h" @@ -46,7 +43,7 @@ class InstructionTester : public HandleAndZoneScope { if (schedule.rpo_order()->size() == 0) { // Compute the RPO order. Scheduler::ComputeSpecialRPO(main_zone(), &schedule); - DCHECK(schedule.rpo_order()->size() > 0); + CHECK_NE(0u, schedule.rpo_order()->size()); } InstructionBlocks* instruction_blocks = TestInstrSeq::InstructionBlocksFor(main_zone(), &schedule); diff --git a/deps/v8/test/cctest/compiler/test-js-constant-cache.cc b/deps/v8/test/cctest/compiler/test-js-constant-cache.cc index 7559ecd16b..06169f3ba6 100644 --- a/deps/v8/test/cctest/compiler/test-js-constant-cache.cc +++ b/deps/v8/test/cctest/compiler/test-js-constant-cache.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/assembler.h" #include "src/compiler/js-graph.h" #include "src/compiler/node-properties.h" diff --git a/deps/v8/test/cctest/compiler/test-js-context-specialization.cc b/deps/v8/test/cctest/compiler/test-js-context-specialization.cc index e2612e9ea8..43b7665459 100644 --- a/deps/v8/test/cctest/compiler/test-js-context-specialization.cc +++ b/deps/v8/test/cctest/compiler/test-js-context-specialization.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/compiler/js-context-specialization.h" #include "src/compiler/js-graph.h" #include "src/compiler/js-operator.h" @@ -65,7 +62,7 @@ TEST(ReduceJSLoadContext) { subcontext2->set_previous(*subcontext1); subcontext1->set_previous(*native); Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); - const int slot = Context::GLOBAL_OBJECT_INDEX; + const int slot = Context::NATIVE_CONTEXT_INDEX; native->set(slot, *expected); Node* const_context = t.jsgraph()->Constant(native); @@ -136,7 +133,7 @@ TEST(ReduceJSStoreContext) { subcontext2->set_previous(*subcontext1); subcontext1->set_previous(*native); Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); - const int slot = Context::GLOBAL_OBJECT_INDEX; + const int slot = Context::NATIVE_CONTEXT_INDEX; native->set(slot, *expected); Node* const_context = t.jsgraph()->Constant(native); @@ -204,7 +201,7 @@ TEST(SpecializeToContext) { // Make a context and initialize it a bit for this test. Handle<Context> native = t.factory()->NewNativeContext(); Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); - const int slot = Context::GLOBAL_OBJECT_INDEX; + const int slot = Context::NATIVE_CONTEXT_INDEX; native->set(slot, *expected); Node* const_context = t.jsgraph()->Constant(native); @@ -228,8 +225,8 @@ TEST(SpecializeToContext) { t.graph()->NewNode(t.simplified()->ChangeTaggedToInt32(), other_load); Node* add = t.graph()->NewNode( - t.javascript()->Add(LanguageMode::SLOPPY), value_use, other_use, - param_context, t.jsgraph()->EmptyFrameState(), + t.javascript()->Add(LanguageMode::SLOPPY, BinaryOperationHints::Any()), + value_use, other_use, param_context, t.jsgraph()->EmptyFrameState(), t.jsgraph()->EmptyFrameState(), other_load, start); Node* ret = diff --git a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc index b22785207d..c8b7734eb2 100644 --- a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc +++ b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/compilation-dependencies.h" #include "src/compiler/js-graph.h" #include "src/compiler/js-typed-lowering.h" @@ -63,6 +60,7 @@ class JSTypedLoweringTester : public HandleAndZoneScope { Graph graph; Typer typer; Node* context_node; + BinaryOperationHints const hints = BinaryOperationHints::Any(); Node* Parameter(Type* t, int32_t index = 0) { Node* n = graph.NewNode(common.Parameter(index), graph.start()); @@ -156,7 +154,7 @@ class JSTypedLoweringTester : public HandleAndZoneScope { Node* Unop(const Operator* op, Node* input) { // JS unops also require context, effect, and control if (OperatorProperties::GetFrameStateInputCount(op) > 0) { - DCHECK(OperatorProperties::GetFrameStateInputCount(op) == 1); + CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(op)); return graph.NewNode(op, input, context(), EmptyFrameState(context()), start(), control()); } else { @@ -168,8 +166,8 @@ class JSTypedLoweringTester : public HandleAndZoneScope { // TODO(titzer): use EffectPhi after fixing EffectCount if (OperatorProperties::GetFrameStateInputCount(javascript.ToNumber()) > 0) { - DCHECK(OperatorProperties::GetFrameStateInputCount( - javascript.ToNumber()) == 1); + CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount( + javascript.ToNumber())); return graph.NewNode(javascript.ToNumber(), node, context(), EmptyFrameState(context()), node, control()); } else { @@ -268,7 +266,8 @@ TEST_WITH_STRONG(AddNumber1) { for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { Node* p0 = R.Parameter(kNumberTypes[i], 0); Node* p1 = R.Parameter(kNumberTypes[i], 1); - Node* add = R.Binop(R.javascript.Add(language_mode), p0, p1); + Node* add = R.Binop( + R.javascript.Add(language_mode, BinaryOperationHints::Any()), p0, p1); Node* r = R.reduce(add); R.CheckBinop(IrOpcode::kNumberAdd, r); @@ -281,11 +280,16 @@ TEST_WITH_STRONG(AddNumber1) { TEST_WITH_STRONG(NumberBinops) { JSTypedLoweringTester R; const Operator* ops[] = { - R.javascript.Add(language_mode), R.simplified.NumberAdd(), - R.javascript.Subtract(language_mode), R.simplified.NumberSubtract(), - R.javascript.Multiply(language_mode), R.simplified.NumberMultiply(), - R.javascript.Divide(language_mode), R.simplified.NumberDivide(), - R.javascript.Modulus(language_mode), R.simplified.NumberModulus(), + R.javascript.Add(language_mode, R.hints), + R.simplified.NumberAdd(), + R.javascript.Subtract(language_mode, R.hints), + R.simplified.NumberSubtract(), + R.javascript.Multiply(language_mode, R.hints), + R.simplified.NumberMultiply(), + R.javascript.Divide(language_mode, R.hints), + R.simplified.NumberDivide(), + R.javascript.Modulus(language_mode, R.hints), + R.simplified.NumberModulus(), }; for (size_t i = 0; i < arraysize(kNumberTypes); ++i) { @@ -328,11 +332,11 @@ class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester { explicit JSBitwiseShiftTypedLoweringTester(LanguageMode language_mode) : JSTypedLoweringTester(), language_mode_(language_mode) { int i = 0; - set(i++, javascript.ShiftLeft(language_mode_), true); + set(i++, javascript.ShiftLeft(language_mode_, hints), true); set(i++, simplified.NumberShiftLeft(), false); - set(i++, javascript.ShiftRight(language_mode_), true); + set(i++, javascript.ShiftRight(language_mode_, hints), true); set(i++, simplified.NumberShiftRight(), false); - set(i++, javascript.ShiftRightLogical(language_mode_), false); + set(i++, javascript.ShiftRightLogical(language_mode_, hints), false); set(i++, simplified.NumberShiftRightLogical(), false); } static const int kNumberOps = 6; @@ -386,11 +390,11 @@ class JSBitwiseTypedLoweringTester : public JSTypedLoweringTester { explicit JSBitwiseTypedLoweringTester(LanguageMode language_mode) : JSTypedLoweringTester(), language_mode_(language_mode) { int i = 0; - set(i++, javascript.BitwiseOr(language_mode_), true); + set(i++, javascript.BitwiseOr(language_mode_, hints), true); set(i++, simplified.NumberBitwiseOr(), true); - set(i++, javascript.BitwiseXor(language_mode_), true); + set(i++, javascript.BitwiseXor(language_mode_, hints), true); set(i++, simplified.NumberBitwiseXor(), true); - set(i++, javascript.BitwiseAnd(language_mode_), true); + set(i++, javascript.BitwiseAnd(language_mode_, hints), true); set(i++, simplified.NumberBitwiseAnd(), true); } static const int kNumberOps = 6; @@ -726,28 +730,28 @@ TEST_WITH_STRONG(RemoveToNumberEffects) { switch (i) { case 0: - DCHECK(OperatorProperties::GetFrameStateInputCount( - R.javascript.ToNumber()) == 1); + CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount( + R.javascript.ToNumber())); effect_use = R.graph.NewNode(R.javascript.ToNumber(), p0, R.context(), frame_state, ton, R.start()); break; case 1: - DCHECK(OperatorProperties::GetFrameStateInputCount( - R.javascript.ToNumber()) == 1); + CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount( + R.javascript.ToNumber())); effect_use = R.graph.NewNode(R.javascript.ToNumber(), ton, R.context(), frame_state, ton, R.start()); break; case 2: effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start()); case 3: - effect_use = R.graph.NewNode(R.javascript.Add(language_mode), ton, ton, - R.context(), frame_state, frame_state, ton, - R.start()); + effect_use = R.graph.NewNode(R.javascript.Add(language_mode, R.hints), + ton, ton, R.context(), frame_state, + frame_state, ton, R.start()); break; case 4: - effect_use = R.graph.NewNode(R.javascript.Add(language_mode), p0, p0, - R.context(), frame_state, frame_state, ton, - R.start()); + effect_use = R.graph.NewNode(R.javascript.Add(language_mode, R.hints), + p0, p0, R.context(), frame_state, + frame_state, ton, R.start()); break; case 5: effect_use = R.graph.NewNode(R.common.Return(), p0, ton, R.start()); @@ -910,13 +914,20 @@ TEST_WITH_STRONG(RemovePureNumberBinopEffects) { JSTypedLoweringTester R; const Operator* ops[] = { - R.javascript.Equal(), R.simplified.NumberEqual(), - R.javascript.Add(language_mode), R.simplified.NumberAdd(), - R.javascript.Subtract(language_mode), R.simplified.NumberSubtract(), - R.javascript.Multiply(language_mode), R.simplified.NumberMultiply(), - R.javascript.Divide(language_mode), R.simplified.NumberDivide(), - R.javascript.Modulus(language_mode), R.simplified.NumberModulus(), - R.javascript.LessThan(language_mode), R.simplified.NumberLessThan(), + R.javascript.Equal(), + R.simplified.NumberEqual(), + R.javascript.Add(language_mode, R.hints), + R.simplified.NumberAdd(), + R.javascript.Subtract(language_mode, R.hints), + R.simplified.NumberSubtract(), + R.javascript.Multiply(language_mode, R.hints), + R.simplified.NumberMultiply(), + R.javascript.Divide(language_mode, R.hints), + R.simplified.NumberDivide(), + R.javascript.Modulus(language_mode, R.hints), + R.simplified.NumberModulus(), + R.javascript.LessThan(language_mode), + R.simplified.NumberLessThan(), R.javascript.LessThanOrEqual(language_mode), R.simplified.NumberLessThanOrEqual(), }; @@ -939,11 +950,11 @@ TEST(OrderNumberBinopEffects1) { JSTypedLoweringTester R; const Operator* ops[] = { - R.javascript.Subtract(LanguageMode::SLOPPY), + R.javascript.Subtract(LanguageMode::SLOPPY, R.hints), R.simplified.NumberSubtract(), - R.javascript.Multiply(LanguageMode::SLOPPY), + R.javascript.Multiply(LanguageMode::SLOPPY, R.hints), R.simplified.NumberMultiply(), - R.javascript.Divide(LanguageMode::SLOPPY), + R.javascript.Divide(LanguageMode::SLOPPY, R.hints), R.simplified.NumberDivide(), }; @@ -967,13 +978,13 @@ TEST(OrderNumberBinopEffects2) { JSTypedLoweringTester R; const Operator* ops[] = { - R.javascript.Add(LanguageMode::SLOPPY), + R.javascript.Add(LanguageMode::SLOPPY, R.hints), R.simplified.NumberAdd(), - R.javascript.Subtract(LanguageMode::SLOPPY), + R.javascript.Subtract(LanguageMode::SLOPPY, R.hints), R.simplified.NumberSubtract(), - R.javascript.Multiply(LanguageMode::SLOPPY), + R.javascript.Multiply(LanguageMode::SLOPPY, R.hints), R.simplified.NumberMultiply(), - R.javascript.Divide(LanguageMode::SLOPPY), + R.javascript.Divide(LanguageMode::SLOPPY, R.hints), R.simplified.NumberDivide(), }; diff --git a/deps/v8/test/cctest/compiler/test-jump-threading.cc b/deps/v8/test/cctest/compiler/test-jump-threading.cc index 00baca2c5b..8c02012e0a 100644 --- a/deps/v8/test/cctest/compiler/test-jump-threading.cc +++ b/deps/v8/test/cctest/compiler/test-jump-threading.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/compiler/instruction.h" #include "src/compiler/instruction-codes.h" #include "src/compiler/jump-threading.h" @@ -60,16 +57,18 @@ class TestCode : public HandleAndZoneScope { Start(); sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop)); int index = static_cast<int>(sequence_.instructions().size()) - 1; - AddGapMove(index, - AllocatedOperand(LocationOperand::REGISTER, kRepWord32, 13), - AllocatedOperand(LocationOperand::REGISTER, kRepWord32, 13)); + AddGapMove(index, AllocatedOperand(LocationOperand::REGISTER, + MachineRepresentation::kWord32, 13), + AllocatedOperand(LocationOperand::REGISTER, + MachineRepresentation::kWord32, 13)); } void NonRedundantMoves() { Start(); sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop)); int index = static_cast<int>(sequence_.instructions().size()) - 1; AddGapMove(index, ConstantOperand(11), - AllocatedOperand(LocationOperand::REGISTER, kRepWord32, 11)); + AllocatedOperand(LocationOperand::REGISTER, + MachineRepresentation::kWord32, 11)); } void Other() { Start(); diff --git a/deps/v8/test/cctest/compiler/test-linkage.cc b/deps/v8/test/cctest/compiler/test-linkage.cc index 2aaf8c766d..939b144731 100644 --- a/deps/v8/test/cctest/compiler/test-linkage.cc +++ b/deps/v8/test/cctest/compiler/test-linkage.cc @@ -2,12 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/code-stubs.h" #include "src/compiler.h" -#include "src/parser.h" +#include "src/parsing/parser.h" #include "src/zone.h" #include "src/compiler/common-operator.h" diff --git a/deps/v8/test/cctest/compiler/test-loop-analysis.cc b/deps/v8/test/cctest/compiler/test-loop-analysis.cc index 3862a647de..68bfc2858f 100644 --- a/deps/v8/test/cctest/compiler/test-loop-analysis.cc +++ b/deps/v8/test/cctest/compiler/test-loop-analysis.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/compiler/access-builder.h" #include "src/compiler/common-operator.h" #include "src/compiler/graph.h" @@ -114,7 +111,8 @@ class LoopFinderTester : HandleAndZoneScope { } const Operator* op(int count, bool effect) { - return effect ? common.EffectPhi(count) : common.Phi(kMachAnyTagged, count); + return effect ? common.EffectPhi(count) + : common.Phi(MachineRepresentation::kTagged, count); } Node* Return(Node* val, Node* effect, Node* control) { @@ -269,8 +267,8 @@ TEST(LaLoop1phi) { // One loop with a simple phi. LoopFinderTester t; While w(t, t.p0); - Node* phi = - t.graph.NewNode(t.common.Phi(kMachAnyTagged, 2), t.zero, t.one, w.loop); + Node* phi = t.graph.NewNode(t.common.Phi(MachineRepresentation::kTagged, 2), + t.zero, t.one, w.loop); t.Return(phi, t.start, w.exit); Node* chain[] = {w.loop}; @@ -478,7 +476,7 @@ TEST(LaNestedLoop1x) { While w2(t, t.p0); w2.nest(w1); - const Operator* op = t.common.Phi(kMachInt32, 2); + const Operator* op = t.common.Phi(MachineRepresentation::kWord32, 2); Node* p1a = t.graph.NewNode(op, t.p0, t.p0, w1.loop); Node* p1b = t.graph.NewNode(op, t.p0, t.p0, w1.loop); Node* p2a = t.graph.NewNode(op, p1a, t.p0, w2.loop); @@ -691,8 +689,8 @@ TEST(LaEdgeMatrix1) { Node* p3 = t.jsgraph.Int32Constant(33); Node* loop = t.graph.NewNode(t.common.Loop(2), t.start, t.start); - Node* phi = - t.graph.NewNode(t.common.Phi(kMachInt32, 2), t.one, p1, loop); + Node* phi = t.graph.NewNode( + t.common.Phi(MachineRepresentation::kWord32, 2), t.one, p1, loop); Node* cond = t.graph.NewNode(&kIntAdd, phi, p2); Node* branch = t.graph.NewNode(t.common.Branch(), cond, loop); Node* if_true = t.graph.NewNode(t.common.IfTrue(), branch); @@ -716,7 +714,7 @@ TEST(LaEdgeMatrix1) { void RunEdgeMatrix2(int i) { - DCHECK(i >= 0 && i < 5); + CHECK(i >= 0 && i < 5); for (int j = 0; j < 5; j++) { for (int k = 0; k < 5; k++) { LoopFinderTester t; @@ -727,8 +725,8 @@ void RunEdgeMatrix2(int i) { // outer loop. Node* loop1 = t.graph.NewNode(t.common.Loop(2), t.start, t.start); - Node* phi1 = - t.graph.NewNode(t.common.Phi(kMachInt32, 2), t.one, p1, loop1); + Node* phi1 = t.graph.NewNode( + t.common.Phi(MachineRepresentation::kWord32, 2), t.one, p1, loop1); Node* cond1 = t.graph.NewNode(&kIntAdd, phi1, t.one); Node* branch1 = t.graph.NewNode(t.common.Branch(), cond1, loop1); Node* if_true1 = t.graph.NewNode(t.common.IfTrue(), branch1); @@ -736,8 +734,8 @@ void RunEdgeMatrix2(int i) { // inner loop. Node* loop2 = t.graph.NewNode(t.common.Loop(2), if_true1, t.start); - Node* phi2 = - t.graph.NewNode(t.common.Phi(kMachInt32, 2), t.one, p2, loop2); + Node* phi2 = t.graph.NewNode( + t.common.Phi(MachineRepresentation::kWord32, 2), t.one, p2, loop2); Node* cond2 = t.graph.NewNode(&kIntAdd, phi2, p3); Node* branch2 = t.graph.NewNode(t.common.Branch(), cond2, loop2); Node* if_true2 = t.graph.NewNode(t.common.IfTrue(), branch2); @@ -803,7 +801,8 @@ void RunEdgeMatrix3(int c1a, int c1b, int c1c, // line break // L1 depth = 0 Node* loop1 = t.graph.NewNode(t.common.Loop(2), t.start, t.start); - Node* phi1 = t.graph.NewNode(t.common.Phi(kMachInt32, 2), p1a, p1c, loop1); + Node* phi1 = t.graph.NewNode(t.common.Phi(MachineRepresentation::kWord32, 2), + p1a, p1c, loop1); Node* cond1 = t.graph.NewNode(&kIntAdd, phi1, p1b); Node* branch1 = t.graph.NewNode(t.common.Branch(), cond1, loop1); Node* if_true1 = t.graph.NewNode(t.common.IfTrue(), branch1); @@ -811,7 +810,8 @@ void RunEdgeMatrix3(int c1a, int c1b, int c1c, // line break // L2 depth = 1 Node* loop2 = t.graph.NewNode(t.common.Loop(2), if_true1, t.start); - Node* phi2 = t.graph.NewNode(t.common.Phi(kMachInt32, 2), p2a, p2c, loop2); + Node* phi2 = t.graph.NewNode(t.common.Phi(MachineRepresentation::kWord32, 2), + p2a, p2c, loop2); Node* cond2 = t.graph.NewNode(&kIntAdd, phi2, p2b); Node* branch2 = t.graph.NewNode(t.common.Branch(), cond2, loop2); Node* if_true2 = t.graph.NewNode(t.common.IfTrue(), branch2); @@ -819,7 +819,8 @@ void RunEdgeMatrix3(int c1a, int c1b, int c1c, // line break // L3 depth = 2 Node* loop3 = t.graph.NewNode(t.common.Loop(2), if_true2, t.start); - Node* phi3 = t.graph.NewNode(t.common.Phi(kMachInt32, 2), p3a, p3c, loop3); + Node* phi3 = t.graph.NewNode(t.common.Phi(MachineRepresentation::kWord32, 2), + p3a, p3c, loop3); Node* cond3 = t.graph.NewNode(&kIntAdd, phi3, p3b); Node* branch3 = t.graph.NewNode(t.common.Branch(), cond3, loop3); Node* if_true3 = t.graph.NewNode(t.common.IfTrue(), branch3); @@ -927,7 +928,8 @@ static void RunManyChainedLoops_i(int count) { // Build loops. for (int i = 0; i < count; i++) { Node* loop = t.graph.NewNode(t.common.Loop(2), last, t.start); - Node* phi = t.graph.NewNode(t.common.Phi(kMachInt32, 2), k11, k12, loop); + Node* phi = t.graph.NewNode(t.common.Phi(MachineRepresentation::kWord32, 2), + k11, k12, loop); Node* branch = t.graph.NewNode(t.common.Branch(), phi, loop); Node* if_true = t.graph.NewNode(t.common.IfTrue(), branch); Node* exit = t.graph.NewNode(t.common.IfFalse(), branch); @@ -962,7 +964,8 @@ static void RunManyNestedLoops_i(int count) { // Build loops. for (int i = 0; i < count; i++) { Node* loop = t.graph.NewNode(t.common.Loop(2), entry, t.start); - Node* phi = t.graph.NewNode(t.common.Phi(kMachInt32, 2), k11, k12, loop); + Node* phi = t.graph.NewNode(t.common.Phi(MachineRepresentation::kWord32, 2), + k11, k12, loop); Node* branch = t.graph.NewNode(t.common.Branch(), phi, loop); Node* if_true = t.graph.NewNode(t.common.IfTrue(), branch); Node* exit = t.graph.NewNode(t.common.IfFalse(), branch); 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 e1af1626e1..69f5e157ad 100644 --- a/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc +++ b/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc @@ -2,13 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - +#include "src/ast/scopes.h" #include "src/compiler/ast-loop-assignment-analyzer.h" -#include "src/parser.h" -#include "src/rewriter.h" -#include "src/scopes.h" +#include "src/parsing/parser.h" +#include "src/parsing/rewriter.h" #include "test/cctest/cctest.h" namespace v8 { diff --git a/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc b/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc index ca49369592..86888e96f5 100644 --- a/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc +++ b/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/base/utils/random-number-generator.h" #include "src/codegen.h" #include "src/compiler/js-graph.h" @@ -59,7 +56,7 @@ class ReducerTester : public HandleAndZoneScope { : isolate(main_isolate()), binop(NULL), unop(NULL), - machine(main_zone(), kMachPtr, flags), + machine(main_zone(), MachineType::PointerRepresentation(), flags), common(main_zone()), graph(main_zone()), javascript(main_zone()), @@ -362,7 +359,7 @@ TEST(ReduceWord32Sar) { static void CheckJsShift(ReducerTester* R) { - DCHECK(R->machine.Word32ShiftIsSafe()); + CHECK(R->machine.Word32ShiftIsSafe()); Node* x = R->Parameter(0); Node* y = R->Parameter(1); @@ -706,8 +703,8 @@ TEST(ReduceLoadStore) { Node* base = R.Constant<int32_t>(11); Node* index = R.Constant<int32_t>(4); - Node* load = R.graph.NewNode(R.machine.Load(kMachInt32), base, index, - R.graph.start(), R.graph.start()); + Node* load = R.graph.NewNode(R.machine.Load(MachineType::Int32()), base, + index, R.graph.start(), R.graph.start()); { MachineOperatorReducer reducer(&R.jsgraph); @@ -716,9 +713,10 @@ TEST(ReduceLoadStore) { } { - Node* store = R.graph.NewNode( - R.machine.Store(StoreRepresentation(kMachInt32, kNoWriteBarrier)), base, - index, load, load, R.graph.start()); + Node* store = + R.graph.NewNode(R.machine.Store(StoreRepresentation( + MachineRepresentation::kWord32, kNoWriteBarrier)), + base, index, load, load, R.graph.start()); MachineOperatorReducer reducer(&R.jsgraph); Reduction reduction = reducer.Reduce(store); CHECK(!reduction.Changed()); // stores should not be reduced. diff --git a/deps/v8/test/cctest/compiler/test-multiple-return.cc b/deps/v8/test/cctest/compiler/test-multiple-return.cc index 00fcc5f814..7c08238411 100644 --- a/deps/v8/test/cctest/compiler/test-multiple-return.cc +++ b/deps/v8/test/cctest/compiler/test-multiple-return.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <cmath> #include <functional> #include <limits> @@ -34,17 +31,17 @@ CallDescriptor* GetCallDescriptor(Zone* zone, int return_count, RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN); // Add return location(s). - DCHECK(return_count <= config->num_allocatable_general_registers()); + CHECK(return_count <= config->num_allocatable_general_registers()); for (int i = 0; i < return_count; i++) { - msig.AddReturn(compiler::kMachInt32); + msig.AddReturn(MachineType::Int32()); locations.AddReturn( LinkageLocation::ForRegister(config->allocatable_general_codes()[i])); } // Add register and/or stack parameter(s). - DCHECK(param_count <= config->num_allocatable_general_registers()); + CHECK(param_count <= config->num_allocatable_general_registers()); for (int i = 0; i < param_count; i++) { - msig.AddParam(compiler::kMachInt32); + msig.AddParam(MachineType::Int32()); locations.AddParam( LinkageLocation::ForRegister(config->allocatable_general_codes()[i])); } @@ -53,7 +50,7 @@ CallDescriptor* GetCallDescriptor(Zone* zone, int return_count, const RegList kCalleeSaveFPRegisters = 0; // The target for WASM calls is always a code object. - MachineType target_type = compiler::kMachAnyTagged; + MachineType target_type = MachineType::AnyTagged(); LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); return new (zone) CallDescriptor( // -- CallDescriptor::kCallCodeObject, // kind @@ -77,7 +74,7 @@ TEST(ReturnThreeValues) { HandleAndZoneScope handles; RawMachineAssembler m(handles.main_isolate(), new (handles.main_zone()) Graph(handles.main_zone()), - desc, kMachPtr, + desc, MachineType::PointerRepresentation(), InstructionSelector::SupportedMachineOperatorFlags()); Node* p0 = m.Parameter(0); diff --git a/deps/v8/test/cctest/compiler/test-node.cc b/deps/v8/test/cctest/compiler/test-node.cc index fcd6b74c4b..de1c2c02a2 100644 --- a/deps/v8/test/cctest/compiler/test-node.cc +++ b/deps/v8/test/cctest/compiler/test-node.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <functional> #include "src/compiler/graph.h" diff --git a/deps/v8/test/cctest/compiler/test-operator.cc b/deps/v8/test/cctest/compiler/test-operator.cc index 7d2dfdd469..eecf46a054 100644 --- a/deps/v8/test/cctest/compiler/test-operator.cc +++ b/deps/v8/test/cctest/compiler/test-operator.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <sstream> #include "src/compiler/operator.h" diff --git a/deps/v8/test/cctest/compiler/test-osr.cc b/deps/v8/test/cctest/compiler/test-osr.cc index 7cc8fa6338..f0640c2e0a 100644 --- a/deps/v8/test/cctest/compiler/test-osr.cc +++ b/deps/v8/test/cctest/compiler/test-osr.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/codegen.h" #include "src/compiler/all-nodes.h" #include "src/compiler/common-operator.h" @@ -94,7 +91,8 @@ class OsrDeconstructorTester : public HandleAndZoneScope { if (count > 3) inputs[3] = back2; if (count > 4) inputs[4] = back3; inputs[count] = loop; - return graph.NewNode(common.Phi(kMachAnyTagged, count), count + 1, inputs); + return graph.NewNode(common.Phi(MachineRepresentation::kTagged, count), + count + 1, inputs); } Node* NewLoop(bool is_osr, int num_backedges, Node* entry = nullptr) { @@ -317,9 +315,11 @@ struct While { Node* Phi(Node* i1, Node* i2, Node* i3) { if (loop->InputCount() == 2) { - return t.graph.NewNode(t.common.Phi(kMachAnyTagged, 2), i1, i2, loop); + return t.graph.NewNode(t.common.Phi(MachineRepresentation::kTagged, 2), + i1, i2, loop); } else { - return t.graph.NewNode(t.common.Phi(kMachAnyTagged, 3), i1, i2, i3, loop); + return t.graph.NewNode(t.common.Phi(MachineRepresentation::kTagged, 3), + i1, i2, i3, loop); } } }; @@ -476,7 +476,8 @@ Node* MakeCounter(JSGraph* jsgraph, Node* start, Node* loop) { tmp_inputs.push_back(loop); Node* phi = jsgraph->graph()->NewNode( - jsgraph->common()->Phi(kMachInt32, count), count + 1, &tmp_inputs[0]); + jsgraph->common()->Phi(MachineRepresentation::kWord32, count), count + 1, + &tmp_inputs[0]); Node* inc = jsgraph->graph()->NewNode(&kIntAdd, phi, jsgraph->OneConstant()); for (int i = 1; i < count; i++) { @@ -496,8 +497,9 @@ TEST(Deconstruct_osr_nested3) { // middle loop. Node* loop1 = T.graph.NewNode(T.common.Loop(1), loop0.if_true); - Node* loop1_phi = T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), loop0_cntr, - loop0_cntr, loop1); + Node* loop1_phi = + T.graph.NewNode(T.common.Phi(MachineRepresentation::kTagged, 2), + loop0_cntr, loop0_cntr, loop1); // innermost (OSR) loop. While loop2(T, T.p0, true, 1); diff --git a/deps/v8/test/cctest/compiler/test-pipeline.cc b/deps/v8/test/cctest/compiler/test-pipeline.cc index c00fa6a331..f4ffd02296 100644 --- a/deps/v8/test/cctest/compiler/test-pipeline.cc +++ b/deps/v8/test/cctest/compiler/test-pipeline.cc @@ -2,13 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/compiler.h" #include "src/compiler/pipeline.h" #include "src/handles.h" -#include "src/parser.h" +#include "src/parsing/parser.h" #include "test/cctest/cctest.h" namespace v8 { diff --git a/deps/v8/test/cctest/compiler/test-representation-change.cc b/deps/v8/test/cctest/compiler/test-representation-change.cc index 616c3736e1..7353e167d9 100644 --- a/deps/v8/test/cctest/compiler/test-representation-change.cc +++ b/deps/v8/test/cctest/compiler/test-representation-change.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <limits> #include "test/cctest/cctest.h" @@ -64,7 +61,7 @@ class RepresentationChangerTester : public HandleAndZoneScope, void CheckFloat32Constant(Node* n, float expected) { CHECK_EQ(IrOpcode::kFloat32Constant, n->opcode()); float fval = OpParameter<float>(n->op()); - CHECK_EQ(expected, fval); + CheckDoubleEq(expected, fval); } void CheckHeapConstant(Node* n, HeapObject* expected) { @@ -81,41 +78,50 @@ class RepresentationChangerTester : public HandleAndZoneScope, } Node* Parameter(int index = 0) { - return graph()->NewNode(common()->Parameter(index), graph()->start()); + Node* n = graph()->NewNode(common()->Parameter(index), graph()->start()); + NodeProperties::SetType(n, Type::Any()); + return n; } - void CheckTypeError(MachineTypeUnion from, MachineTypeUnion to) { + void CheckTypeError(MachineRepresentation from, Type* from_type, + MachineRepresentation to) { changer()->testing_type_errors_ = true; changer()->type_error_ = false; Node* n = Parameter(0); - Node* c = changer()->GetRepresentationFor(n, from, to); + Node* c = changer()->GetRepresentationFor(n, from, from_type, to); CHECK(changer()->type_error_); CHECK_EQ(n, c); } - void CheckNop(MachineTypeUnion from, MachineTypeUnion to) { + void CheckNop(MachineRepresentation from, Type* from_type, + MachineRepresentation to) { Node* n = Parameter(0); - Node* c = changer()->GetRepresentationFor(n, from, to); + Node* c = changer()->GetRepresentationFor(n, from, from_type, to); CHECK_EQ(n, c); } }; -static const MachineType all_reps[] = {kRepBit, kRepWord32, kRepWord64, - kRepFloat32, kRepFloat64, kRepTagged}; +const MachineType kMachineTypes[] = { + MachineType::Float32(), MachineType::Float64(), MachineType::Int8(), + MachineType::Uint8(), MachineType::Int16(), MachineType::Uint16(), + MachineType::Int32(), MachineType::Uint32(), MachineType::Int64(), + MachineType::Uint64(), MachineType::AnyTagged()}; TEST(BoolToBit_constant) { RepresentationChangerTester r; Node* true_node = r.jsgraph()->TrueConstant(); - Node* true_bit = - r.changer()->GetRepresentationFor(true_node, kRepTagged, kRepBit); + Node* true_bit = r.changer()->GetRepresentationFor( + true_node, MachineRepresentation::kTagged, Type::None(), + MachineRepresentation::kBit); r.CheckInt32Constant(true_bit, 1); Node* false_node = r.jsgraph()->FalseConstant(); - Node* false_bit = - r.changer()->GetRepresentationFor(false_node, kRepTagged, kRepBit); + Node* false_bit = r.changer()->GetRepresentationFor( + false_node, MachineRepresentation::kTagged, Type::None(), + MachineRepresentation::kBit); r.CheckInt32Constant(false_bit, 0); } @@ -125,7 +131,9 @@ TEST(BitToBool_constant) { for (int i = -5; i < 5; i++) { Node* node = r.jsgraph()->Int32Constant(i); - Node* val = r.changer()->GetRepresentationFor(node, kRepBit, kRepTagged); + Node* val = r.changer()->GetRepresentationFor( + node, MachineRepresentation::kBit, Type::Boolean(), + MachineRepresentation::kTagged); r.CheckHeapConstant(val, i == 0 ? r.isolate()->heap()->false_value() : r.isolate()->heap()->true_value()); } @@ -138,7 +146,9 @@ TEST(ToTagged_constant) { { FOR_FLOAT64_INPUTS(i) { Node* n = r.jsgraph()->Float64Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kFloat64, Type::None(), + MachineRepresentation::kTagged); r.CheckNumberConstant(c, *i); } } @@ -146,7 +156,9 @@ TEST(ToTagged_constant) { { FOR_FLOAT64_INPUTS(i) { Node* n = r.jsgraph()->Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kFloat64, Type::None(), + MachineRepresentation::kTagged); r.CheckNumberConstant(c, *i); } } @@ -154,7 +166,9 @@ TEST(ToTagged_constant) { { FOR_FLOAT32_INPUTS(i) { Node* n = r.jsgraph()->Float32Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepTagged); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kFloat32, Type::None(), + MachineRepresentation::kTagged); r.CheckNumberConstant(c, *i); } } @@ -162,8 +176,9 @@ TEST(ToTagged_constant) { { FOR_INT32_INPUTS(i) { Node* n = r.jsgraph()->Int32Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, - kRepTagged); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kWord32, Type::Signed32(), + MachineRepresentation::kTagged); r.CheckNumberConstant(c, *i); } } @@ -171,8 +186,9 @@ TEST(ToTagged_constant) { { FOR_UINT32_INPUTS(i) { Node* n = r.jsgraph()->Int32Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, - kRepTagged); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kWord32, Type::Unsigned32(), + MachineRepresentation::kTagged); r.CheckNumberConstant(c, *i); } } @@ -185,7 +201,9 @@ TEST(ToFloat64_constant) { { FOR_FLOAT64_INPUTS(i) { Node* n = r.jsgraph()->Float64Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepFloat64); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kFloat64, Type::None(), + MachineRepresentation::kFloat64); CHECK_EQ(n, c); } } @@ -193,7 +211,9 @@ TEST(ToFloat64_constant) { { FOR_FLOAT64_INPUTS(i) { Node* n = r.jsgraph()->Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepTagged, kRepFloat64); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kTagged, Type::None(), + MachineRepresentation::kFloat64); r.CheckFloat64Constant(c, *i); } } @@ -201,7 +221,9 @@ TEST(ToFloat64_constant) { { FOR_FLOAT32_INPUTS(i) { Node* n = r.jsgraph()->Float32Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepFloat64); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kFloat32, Type::None(), + MachineRepresentation::kFloat64); r.CheckFloat64Constant(c, *i); } } @@ -209,8 +231,9 @@ TEST(ToFloat64_constant) { { FOR_INT32_INPUTS(i) { Node* n = r.jsgraph()->Int32Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, - kRepFloat64); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kWord32, Type::Signed32(), + MachineRepresentation::kFloat64); r.CheckFloat64Constant(c, *i); } } @@ -218,8 +241,9 @@ TEST(ToFloat64_constant) { { FOR_UINT32_INPUTS(i) { Node* n = r.jsgraph()->Int32Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, - kRepFloat64); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kWord32, Type::Unsigned32(), + MachineRepresentation::kFloat64); r.CheckFloat64Constant(c, *i); } } @@ -240,7 +264,9 @@ TEST(ToFloat32_constant) { { FOR_FLOAT32_INPUTS(i) { Node* n = r.jsgraph()->Float32Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepFloat32); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kFloat32, Type::None(), + MachineRepresentation::kFloat32); CHECK_EQ(n, c); } } @@ -248,7 +274,9 @@ TEST(ToFloat32_constant) { { FOR_FLOAT32_INPUTS(i) { Node* n = r.jsgraph()->Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepTagged, kRepFloat32); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kTagged, Type::None(), + MachineRepresentation::kFloat32); r.CheckFloat32Constant(c, *i); } } @@ -256,7 +284,9 @@ TEST(ToFloat32_constant) { { FOR_FLOAT32_INPUTS(i) { Node* n = r.jsgraph()->Float64Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepFloat32); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kFloat64, Type::None(), + MachineRepresentation::kFloat32); r.CheckFloat32Constant(c, *i); } } @@ -265,8 +295,9 @@ TEST(ToFloat32_constant) { FOR_INT32_INPUTS(i) { if (!IsFloat32Int32(*i)) continue; Node* n = r.jsgraph()->Int32Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, - kRepFloat32); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kWord32, Type::Signed32(), + MachineRepresentation::kFloat32); r.CheckFloat32Constant(c, static_cast<float>(*i)); } } @@ -275,8 +306,9 @@ TEST(ToFloat32_constant) { FOR_UINT32_INPUTS(i) { if (!IsFloat32Uint32(*i)) continue; Node* n = r.jsgraph()->Int32Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, - kRepFloat32); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kWord32, Type::Unsigned32(), + MachineRepresentation::kFloat32); r.CheckFloat32Constant(c, static_cast<float>(*i)); } } @@ -289,8 +321,9 @@ TEST(ToInt32_constant) { { FOR_INT32_INPUTS(i) { Node* n = r.jsgraph()->Int32Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32, - kRepWord32); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kWord32, Type::Signed32(), + MachineRepresentation::kWord32); r.CheckInt32Constant(c, *i); } } @@ -299,8 +332,9 @@ TEST(ToInt32_constant) { FOR_INT32_INPUTS(i) { if (!IsFloat32Int32(*i)) continue; Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i)); - Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32 | kTypeInt32, - kRepWord32); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kFloat32, Type::Signed32(), + MachineRepresentation::kWord32); r.CheckInt32Constant(c, *i); } } @@ -308,8 +342,9 @@ TEST(ToInt32_constant) { { FOR_INT32_INPUTS(i) { Node* n = r.jsgraph()->Float64Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64 | kTypeInt32, - kRepWord32); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kFloat64, Type::Signed32(), + MachineRepresentation::kWord32); r.CheckInt32Constant(c, *i); } } @@ -317,8 +352,9 @@ TEST(ToInt32_constant) { { FOR_INT32_INPUTS(i) { Node* n = r.jsgraph()->Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeInt32, - kRepWord32); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kTagged, Type::Signed32(), + MachineRepresentation::kWord32); r.CheckInt32Constant(c, *i); } } @@ -331,8 +367,9 @@ TEST(ToUint32_constant) { { FOR_UINT32_INPUTS(i) { Node* n = r.jsgraph()->Int32Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32, - kRepWord32); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kWord32, Type::Unsigned32(), + MachineRepresentation::kWord32); r.CheckUint32Constant(c, *i); } } @@ -341,8 +378,9 @@ TEST(ToUint32_constant) { FOR_UINT32_INPUTS(i) { if (!IsFloat32Uint32(*i)) continue; Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i)); - Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32 | kTypeUint32, - kRepWord32); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kFloat32, Type::Unsigned32(), + MachineRepresentation::kWord32); r.CheckUint32Constant(c, *i); } } @@ -350,8 +388,9 @@ TEST(ToUint32_constant) { { FOR_UINT32_INPUTS(i) { Node* n = r.jsgraph()->Float64Constant(*i); - Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64 | kTypeUint32, - kRepWord32); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kFloat64, Type::Unsigned32(), + MachineRepresentation::kWord32); r.CheckUint32Constant(c, *i); } } @@ -359,20 +398,21 @@ TEST(ToUint32_constant) { { FOR_UINT32_INPUTS(i) { Node* n = r.jsgraph()->Constant(static_cast<double>(*i)); - Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeUint32, - kRepWord32); + Node* c = r.changer()->GetRepresentationFor( + n, MachineRepresentation::kTagged, Type::Unsigned32(), + MachineRepresentation::kWord32); r.CheckUint32Constant(c, *i); } } } -static void CheckChange(IrOpcode::Value expected, MachineTypeUnion from, - MachineTypeUnion to) { +static void CheckChange(IrOpcode::Value expected, MachineRepresentation from, + Type* from_type, MachineRepresentation to) { RepresentationChangerTester r; Node* n = r.Parameter(); - Node* c = r.changer()->GetRepresentationFor(n, from, to); + Node* c = r.changer()->GetRepresentationFor(n, from, from_type, to); CHECK_NE(c, n); CHECK_EQ(expected, c->opcode()); @@ -381,12 +421,13 @@ static void CheckChange(IrOpcode::Value expected, MachineTypeUnion from, static void CheckTwoChanges(IrOpcode::Value expected2, - IrOpcode::Value expected1, MachineTypeUnion from, - MachineTypeUnion to) { + IrOpcode::Value expected1, + MachineRepresentation from, Type* from_type, + MachineRepresentation to) { RepresentationChangerTester r; Node* n = r.Parameter(); - Node* c1 = r.changer()->GetRepresentationFor(n, from, to); + Node* c1 = r.changer()->GetRepresentationFor(n, from, from_type, to); CHECK_NE(c1, n); CHECK_EQ(expected1, c1->opcode()); @@ -398,70 +439,92 @@ static void CheckTwoChanges(IrOpcode::Value expected2, TEST(SingleChanges) { - CheckChange(IrOpcode::kChangeBoolToBit, kRepTagged, kRepBit); - CheckChange(IrOpcode::kChangeBitToBool, kRepBit, kRepTagged); - - CheckChange(IrOpcode::kChangeInt32ToTagged, kRepWord32 | kTypeInt32, - kRepTagged); - CheckChange(IrOpcode::kChangeUint32ToTagged, kRepWord32 | kTypeUint32, - kRepTagged); - CheckChange(IrOpcode::kChangeFloat64ToTagged, kRepFloat64, kRepTagged); - - CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged | kTypeInt32, - kRepWord32); - CheckChange(IrOpcode::kChangeTaggedToUint32, kRepTagged | kTypeUint32, - kRepWord32); - CheckChange(IrOpcode::kChangeTaggedToFloat64, kRepTagged, kRepFloat64); + CheckChange(IrOpcode::kChangeBoolToBit, MachineRepresentation::kTagged, + Type::None(), MachineRepresentation::kBit); + CheckChange(IrOpcode::kChangeBitToBool, MachineRepresentation::kBit, + Type::None(), MachineRepresentation::kTagged); + + CheckChange(IrOpcode::kChangeInt32ToTagged, MachineRepresentation::kWord32, + Type::Signed32(), MachineRepresentation::kTagged); + CheckChange(IrOpcode::kChangeUint32ToTagged, MachineRepresentation::kWord32, + Type::Unsigned32(), MachineRepresentation::kTagged); + CheckChange(IrOpcode::kChangeFloat64ToTagged, MachineRepresentation::kFloat64, + Type::None(), MachineRepresentation::kTagged); + + CheckChange(IrOpcode::kChangeTaggedToInt32, MachineRepresentation::kTagged, + Type::Signed32(), MachineRepresentation::kWord32); + CheckChange(IrOpcode::kChangeTaggedToUint32, MachineRepresentation::kTagged, + Type::Unsigned32(), MachineRepresentation::kWord32); + CheckChange(IrOpcode::kChangeTaggedToFloat64, MachineRepresentation::kTagged, + Type::None(), MachineRepresentation::kFloat64); // Int32,Uint32 <-> Float64 are actually machine conversions. - CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32 | kTypeInt32, - kRepFloat64); - CheckChange(IrOpcode::kChangeUint32ToFloat64, kRepWord32 | kTypeUint32, - kRepFloat64); - CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64 | kTypeInt32, - kRepWord32); - CheckChange(IrOpcode::kChangeFloat64ToUint32, kRepFloat64 | kTypeUint32, - kRepWord32); - - CheckChange(IrOpcode::kTruncateFloat64ToFloat32, kRepFloat64, kRepFloat32); + CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineRepresentation::kWord32, + Type::Signed32(), MachineRepresentation::kFloat64); + CheckChange(IrOpcode::kChangeUint32ToFloat64, MachineRepresentation::kWord32, + Type::Unsigned32(), MachineRepresentation::kFloat64); + CheckChange(IrOpcode::kChangeFloat64ToInt32, MachineRepresentation::kFloat64, + Type::Signed32(), MachineRepresentation::kWord32); + CheckChange(IrOpcode::kChangeFloat64ToUint32, MachineRepresentation::kFloat64, + Type::Unsigned32(), MachineRepresentation::kWord32); + + CheckChange(IrOpcode::kTruncateFloat64ToFloat32, + MachineRepresentation::kFloat64, Type::None(), + MachineRepresentation::kFloat32); // Int32,Uint32 <-> Float32 require two changes. CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64, - IrOpcode::kTruncateFloat64ToFloat32, kRepWord32 | kTypeInt32, - kRepFloat32); + IrOpcode::kTruncateFloat64ToFloat32, + MachineRepresentation::kWord32, Type::Signed32(), + MachineRepresentation::kFloat32); CheckTwoChanges(IrOpcode::kChangeUint32ToFloat64, - IrOpcode::kTruncateFloat64ToFloat32, kRepWord32 | kTypeUint32, - kRepFloat32); + IrOpcode::kTruncateFloat64ToFloat32, + MachineRepresentation::kWord32, Type::Unsigned32(), + MachineRepresentation::kFloat32); CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, - IrOpcode::kChangeFloat64ToInt32, kRepFloat32 | kTypeInt32, - kRepWord32); + IrOpcode::kChangeFloat64ToInt32, + MachineRepresentation::kFloat32, Type::Signed32(), + MachineRepresentation::kWord32); CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, - IrOpcode::kChangeFloat64ToUint32, kRepFloat32 | kTypeUint32, - kRepWord32); + IrOpcode::kChangeFloat64ToUint32, + MachineRepresentation::kFloat32, Type::Unsigned32(), + MachineRepresentation::kWord32); // Float32 <-> Tagged require two changes. CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, - IrOpcode::kChangeFloat64ToTagged, kRepFloat32, kRepTagged); + IrOpcode::kChangeFloat64ToTagged, + MachineRepresentation::kFloat32, Type::None(), + MachineRepresentation::kTagged); CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64, - IrOpcode::kTruncateFloat64ToFloat32, kRepTagged, kRepFloat32); + IrOpcode::kTruncateFloat64ToFloat32, + MachineRepresentation::kTagged, Type::None(), + MachineRepresentation::kFloat32); } TEST(SignednessInWord32) { RepresentationChangerTester r; - // TODO(titzer): assume that uses of a word32 without a sign mean kTypeInt32. - CheckChange(IrOpcode::kChangeTaggedToInt32, kRepTagged, - kRepWord32 | kTypeInt32); - CheckChange(IrOpcode::kChangeTaggedToUint32, kRepTagged, - kRepWord32 | kTypeUint32); - CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32, kRepFloat64); - CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64, kRepWord32); + CheckChange(IrOpcode::kChangeTaggedToInt32, MachineRepresentation::kTagged, + Type::Signed32(), MachineRepresentation::kWord32); + CheckChange(IrOpcode::kChangeTaggedToUint32, MachineRepresentation::kTagged, + Type::Unsigned32(), MachineRepresentation::kWord32); + CheckChange(IrOpcode::kChangeInt32ToFloat64, MachineRepresentation::kWord32, + Type::None(), MachineRepresentation::kFloat64); + CheckChange(IrOpcode::kChangeFloat64ToInt32, MachineRepresentation::kFloat64, + Type::Signed32(), MachineRepresentation::kWord32); + CheckChange(IrOpcode::kTruncateFloat64ToInt32, + MachineRepresentation::kFloat64, Type::Number(), + MachineRepresentation::kWord32); CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64, - IrOpcode::kTruncateFloat64ToFloat32, kRepWord32, kRepFloat32); + IrOpcode::kTruncateFloat64ToFloat32, + MachineRepresentation::kWord32, Type::None(), + MachineRepresentation::kFloat32); CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64, - IrOpcode::kChangeFloat64ToInt32, kRepFloat32, kRepWord32); + IrOpcode::kTruncateFloat64ToInt32, + MachineRepresentation::kFloat32, Type::Number(), + MachineRepresentation::kWord32); } @@ -469,33 +532,48 @@ TEST(Nops) { RepresentationChangerTester r; // X -> X is always a nop for any single representation X. - for (size_t i = 0; i < arraysize(all_reps); i++) { - r.CheckNop(all_reps[i], all_reps[i]); + for (size_t i = 0; i < arraysize(kMachineTypes); i++) { + r.CheckNop(kMachineTypes[i].representation(), Type::None(), + kMachineTypes[i].representation()); } // 32-bit floats. - r.CheckNop(kRepFloat32, kRepFloat32); - r.CheckNop(kRepFloat32 | kTypeNumber, kRepFloat32); - r.CheckNop(kRepFloat32, kRepFloat32 | kTypeNumber); + r.CheckNop(MachineRepresentation::kFloat32, Type::None(), + MachineRepresentation::kFloat32); + r.CheckNop(MachineRepresentation::kFloat32, Type::Number(), + MachineRepresentation::kFloat32); // 32-bit words can be used as smaller word sizes and vice versa, because // loads from memory implicitly sign or zero extend the value to the // full machine word size, and stores implicitly truncate. - r.CheckNop(kRepWord32, kRepWord8); - r.CheckNop(kRepWord32, kRepWord16); - r.CheckNop(kRepWord32, kRepWord32); - r.CheckNop(kRepWord8, kRepWord32); - r.CheckNop(kRepWord16, kRepWord32); + r.CheckNop(MachineRepresentation::kWord32, Type::Signed32(), + MachineRepresentation::kWord8); + r.CheckNop(MachineRepresentation::kWord32, Type::Signed32(), + MachineRepresentation::kWord16); + r.CheckNop(MachineRepresentation::kWord32, Type::Signed32(), + MachineRepresentation::kWord32); + r.CheckNop(MachineRepresentation::kWord8, Type::Signed32(), + MachineRepresentation::kWord32); + r.CheckNop(MachineRepresentation::kWord16, Type::Signed32(), + MachineRepresentation::kWord32); // kRepBit (result of comparison) is implicitly a wordish thing. - r.CheckNop(kRepBit, kRepWord8); - r.CheckNop(kRepBit | kTypeBool, kRepWord8); - r.CheckNop(kRepBit, kRepWord16); - r.CheckNop(kRepBit | kTypeBool, kRepWord16); - r.CheckNop(kRepBit, kRepWord32); - r.CheckNop(kRepBit | kTypeBool, kRepWord32); - r.CheckNop(kRepBit, kRepWord64); - r.CheckNop(kRepBit | kTypeBool, kRepWord64); + r.CheckNop(MachineRepresentation::kBit, Type::None(), + MachineRepresentation::kWord8); + r.CheckNop(MachineRepresentation::kBit, Type::None(), + MachineRepresentation::kWord16); + r.CheckNop(MachineRepresentation::kBit, Type::None(), + MachineRepresentation::kWord32); + r.CheckNop(MachineRepresentation::kBit, Type::None(), + MachineRepresentation::kWord64); + r.CheckNop(MachineRepresentation::kBit, Type::Boolean(), + MachineRepresentation::kWord8); + r.CheckNop(MachineRepresentation::kBit, Type::Boolean(), + MachineRepresentation::kWord16); + r.CheckNop(MachineRepresentation::kBit, Type::Boolean(), + MachineRepresentation::kWord32); + r.CheckNop(MachineRepresentation::kBit, Type::Boolean(), + MachineRepresentation::kWord64); } @@ -503,49 +581,48 @@ TEST(TypeErrors) { RepresentationChangerTester r; // Wordish cannot be implicitly converted to/from comparison conditions. - r.CheckTypeError(kRepWord8, kRepBit); - r.CheckTypeError(kRepWord8, kRepBit | kTypeBool); - r.CheckTypeError(kRepWord16, kRepBit); - r.CheckTypeError(kRepWord16, kRepBit | kTypeBool); - r.CheckTypeError(kRepWord32, kRepBit); - r.CheckTypeError(kRepWord32, kRepBit | kTypeBool); - r.CheckTypeError(kRepWord64, kRepBit); - r.CheckTypeError(kRepWord64, kRepBit | kTypeBool); + r.CheckTypeError(MachineRepresentation::kWord8, Type::None(), + MachineRepresentation::kBit); + r.CheckTypeError(MachineRepresentation::kWord16, Type::None(), + MachineRepresentation::kBit); + r.CheckTypeError(MachineRepresentation::kWord32, Type::None(), + MachineRepresentation::kBit); + r.CheckTypeError(MachineRepresentation::kWord64, Type::None(), + MachineRepresentation::kBit); // Floats cannot be implicitly converted to/from comparison conditions. - r.CheckTypeError(kRepFloat64, kRepBit); - r.CheckTypeError(kRepFloat64, kRepBit | kTypeBool); - r.CheckTypeError(kRepBit, kRepFloat64); - r.CheckTypeError(kRepBit | kTypeBool, kRepFloat64); + r.CheckTypeError(MachineRepresentation::kFloat64, Type::None(), + MachineRepresentation::kBit); + r.CheckTypeError(MachineRepresentation::kBit, Type::None(), + MachineRepresentation::kFloat64); + r.CheckTypeError(MachineRepresentation::kBit, Type::Boolean(), + MachineRepresentation::kFloat64); // Floats cannot be implicitly converted to/from comparison conditions. - r.CheckTypeError(kRepFloat32, kRepBit); - r.CheckTypeError(kRepFloat32, kRepBit | kTypeBool); - r.CheckTypeError(kRepBit, kRepFloat32); - r.CheckTypeError(kRepBit | kTypeBool, kRepFloat32); + r.CheckTypeError(MachineRepresentation::kFloat32, Type::None(), + MachineRepresentation::kBit); + r.CheckTypeError(MachineRepresentation::kBit, Type::None(), + MachineRepresentation::kFloat32); + r.CheckTypeError(MachineRepresentation::kBit, Type::Boolean(), + MachineRepresentation::kFloat32); // Word64 is internal and shouldn't be implicitly converted. - r.CheckTypeError(kRepWord64, kRepTagged | kTypeBool); - r.CheckTypeError(kRepWord64, kRepTagged); - r.CheckTypeError(kRepWord64, kRepTagged | kTypeBool); - r.CheckTypeError(kRepTagged, kRepWord64); - r.CheckTypeError(kRepTagged | kTypeBool, kRepWord64); + r.CheckTypeError(MachineRepresentation::kWord64, Type::None(), + MachineRepresentation::kTagged); + r.CheckTypeError(MachineRepresentation::kTagged, Type::None(), + MachineRepresentation::kWord64); + r.CheckTypeError(MachineRepresentation::kTagged, Type::Boolean(), + MachineRepresentation::kWord64); // Word64 / Word32 shouldn't be implicitly converted. - r.CheckTypeError(kRepWord64, kRepWord32); - r.CheckTypeError(kRepWord32, kRepWord64); - r.CheckTypeError(kRepWord64, kRepWord32 | kTypeInt32); - r.CheckTypeError(kRepWord32 | kTypeInt32, kRepWord64); - r.CheckTypeError(kRepWord64, kRepWord32 | kTypeUint32); - r.CheckTypeError(kRepWord32 | kTypeUint32, kRepWord64); - - for (size_t i = 0; i < arraysize(all_reps); i++) { - for (size_t j = 0; j < arraysize(all_reps); j++) { - if (i == j) continue; - // Only a single from representation is allowed. - r.CheckTypeError(all_reps[i] | all_reps[j], kRepTagged); - } - } + r.CheckTypeError(MachineRepresentation::kWord64, Type::None(), + MachineRepresentation::kWord32); + r.CheckTypeError(MachineRepresentation::kWord32, Type::None(), + MachineRepresentation::kWord64); + r.CheckTypeError(MachineRepresentation::kWord32, Type::Signed32(), + MachineRepresentation::kWord64); + r.CheckTypeError(MachineRepresentation::kWord32, Type::Unsigned32(), + MachineRepresentation::kWord64); } } // namespace compiler diff --git a/deps/v8/test/cctest/compiler/test-run-bytecode-graph-builder.cc b/deps/v8/test/cctest/compiler/test-run-bytecode-graph-builder.cc index cadd436385..88555b7d57 100644 --- a/deps/v8/test/cctest/compiler/test-run-bytecode-graph-builder.cc +++ b/deps/v8/test/cctest/compiler/test-run-bytecode-graph-builder.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <utility> #include "src/compiler/pipeline.h" @@ -12,7 +9,7 @@ #include "src/handles.h" #include "src/interpreter/bytecode-array-builder.h" #include "src/interpreter/interpreter.h" -#include "src/parser.h" +#include "src/parsing/parser.h" #include "test/cctest/cctest.h" namespace v8 { @@ -22,6 +19,13 @@ namespace compiler { static const char kFunctionName[] = "f"; +static const Token::Value kCompareOperators[] = { + Token::Value::EQ, Token::Value::NE, Token::Value::EQ_STRICT, + Token::Value::NE_STRICT, Token::Value::LT, Token::Value::LTE, + Token::Value::GT, Token::Value::GTE}; + +static const int SMI_MAX = (1 << 30) - 1; +static const int SMI_MIN = -(1 << 30); static MaybeHandle<Object> CallFunction(Isolate* isolate, Handle<JSFunction> function) { @@ -60,15 +64,17 @@ class BytecodeGraphCallable { class BytecodeGraphTester { public: - BytecodeGraphTester(Isolate* isolate, Zone* zone, const char* script) + BytecodeGraphTester(Isolate* isolate, Zone* zone, const char* script, + const char* filter = kFunctionName) : isolate_(isolate), zone_(zone), script_(script) { i::FLAG_ignition = true; i::FLAG_always_opt = false; - i::FLAG_vector_stores = true; + i::FLAG_allow_natives_syntax = true; + i::FLAG_ignition_fallback_on_eval_and_catch = false; // Set ignition filter flag via SetFlagsFromString to avoid double-free // (or potential leak with StrDup() based on ownership confusion). ScopedVector<char> ignition_filter(64); - SNPrintF(ignition_filter, "--ignition-filter=%s", kFunctionName); + SNPrintF(ignition_filter, "--ignition-filter=%s", filter); FlagList::SetFlagsFromString(ignition_filter.start(), ignition_filter.length()); // Ensure handler table is generated. @@ -77,8 +83,25 @@ class BytecodeGraphTester { virtual ~BytecodeGraphTester() {} template <class... A> - BytecodeGraphCallable<A...> GetCallable() { - return BytecodeGraphCallable<A...>(isolate_, GetFunction()); + BytecodeGraphCallable<A...> GetCallable( + const char* functionName = kFunctionName) { + return BytecodeGraphCallable<A...>(isolate_, GetFunction(functionName)); + } + + Local<Message> CheckThrowsReturnMessage() { + TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate_)); + auto callable = GetCallable<>(); + MaybeHandle<Object> no_result = callable(); + CHECK(isolate_->has_pending_exception()); + CHECK(try_catch.HasCaught()); + CHECK(no_result.is_null()); + isolate_->OptionalRescheduleException(true); + CHECK(!try_catch.Message().IsEmpty()); + return try_catch.Message(); + } + + static Handle<Object> NewObject(const char* script) { + return v8::Utils::OpenHandle(*CompileRun(script)); } private: @@ -86,11 +109,11 @@ class BytecodeGraphTester { Zone* zone_; const char* script_; - Handle<JSFunction> GetFunction() { + Handle<JSFunction> GetFunction(const char* functionName) { CompileRun(script_); Local<Function> api_function = Local<Function>::Cast( CcTest::global() - ->Get(CcTest::isolate()->GetCurrentContext(), v8_str(kFunctionName)) + ->Get(CcTest::isolate()->GetCurrentContext(), v8_str(functionName)) .ToLocalChecked()); Handle<JSFunction> function = Handle<JSFunction>::cast(v8::Utils::OpenHandle(*api_function)); @@ -100,8 +123,9 @@ class BytecodeGraphTester { CompilationInfo compilation_info(&parse_info); compilation_info.SetOptimizing(BailoutId::None(), Handle<Code>()); - Parser parser(&parse_info); - CHECK(parser.Parse(&parse_info)); + compilation_info.MarkAsDeoptimizationEnabled(); + // TODO(mythria): Remove this step once parse_info is not needed. + CHECK(Compiler::ParseAndAnalyze(&parse_info)); compiler::Pipeline pipeline(&compilation_info); Handle<Code> code = pipeline.GenerateCode(); function->ReplaceCode(*code); @@ -113,16 +137,46 @@ class BytecodeGraphTester { }; -template <int N> +#define SPACE() + +#define REPEAT_2(SEP, ...) __VA_ARGS__ SEP() __VA_ARGS__ +#define REPEAT_4(SEP, ...) \ + REPEAT_2(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) +#define REPEAT_8(SEP, ...) \ + REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_4(SEP, __VA_ARGS__) +#define REPEAT_16(SEP, ...) \ + REPEAT_8(SEP, __VA_ARGS__) SEP() REPEAT_8(SEP, __VA_ARGS__) +#define REPEAT_32(SEP, ...) \ + REPEAT_16(SEP, __VA_ARGS__) SEP() REPEAT_16(SEP, __VA_ARGS__) +#define REPEAT_64(SEP, ...) \ + REPEAT_32(SEP, __VA_ARGS__) SEP() REPEAT_32(SEP, __VA_ARGS__) +#define REPEAT_128(SEP, ...) \ + REPEAT_64(SEP, __VA_ARGS__) SEP() REPEAT_64(SEP, __VA_ARGS__) +#define REPEAT_256(SEP, ...) \ + REPEAT_128(SEP, __VA_ARGS__) SEP() REPEAT_128(SEP, __VA_ARGS__) + +#define REPEAT_127(SEP, ...) \ + REPEAT_64(SEP, __VA_ARGS__) \ + SEP() \ + REPEAT_32(SEP, __VA_ARGS__) \ + SEP() \ + REPEAT_16(SEP, __VA_ARGS__) \ + SEP() \ + REPEAT_8(SEP, __VA_ARGS__) \ + SEP() \ + REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) SEP() __VA_ARGS__ + + +template <int N, typename T = Handle<Object>> struct ExpectedSnippet { const char* code_snippet; - Handle<Object> return_value_and_parameters[N + 1]; + T return_value_and_parameters[N + 1]; - inline Handle<Object> return_value() const { - return return_value_and_parameters[0]; - } + inline T return_value() const { return return_value_and_parameters[0]; } - inline Handle<Object> parameter(int i) const { + inline T parameter(int i) const { + CHECK_GE(i, 0); + CHECK_LT(i, N); return return_value_and_parameters[1 + i]; } }; @@ -148,9 +202,8 @@ TEST(BytecodeGraphBuilderReturnStatements) { {"return 3.7e-60;", {factory->NewNumber(3.7e-60)}}, {"return -3.7e60;", {factory->NewNumber(-3.7e60)}}, {"return '';", {factory->NewStringFromStaticChars("")}}, - {"return 'catfood';", {factory->NewStringFromStaticChars("catfood")}} - // TODO(oth): {"return NaN;", {factory->NewNumber(NAN)}} - }; + {"return 'catfood';", {factory->NewStringFromStaticChars("catfood")}}, + {"return NaN;", {factory->nan_value()}}}; size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); for (size_t i = 0; i < num_snippets; i++) { @@ -254,6 +307,2033 @@ TEST(BytecodeGraphBuilderTwoParameterTests) { } } + +TEST(BytecodeGraphBuilderNamedLoad) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<1> snippets[] = { + {"return p1.val;", + {factory->NewNumberFromInt(10), + BytecodeGraphTester::NewObject("({val : 10})")}}, + {"return p1[\"name\"];", + {factory->NewStringFromStaticChars("abc"), + BytecodeGraphTester::NewObject("({name : 'abc'})")}}, + {"'use strict'; return p1.val;", + {factory->NewNumberFromInt(10), + BytecodeGraphTester::NewObject("({val : 10 })")}}, + {"'use strict'; return p1[\"val\"];", + {factory->NewNumberFromInt(10), + BytecodeGraphTester::NewObject("({val : 10, name : 'abc'})")}}, + {"var b;\n" REPEAT_127(SPACE, " b = p1.name; ") " return p1.name;\n", + {factory->NewStringFromStaticChars("abc"), + BytecodeGraphTester::NewObject("({name : 'abc'})")}}, + {"'use strict'; var b;\n" + REPEAT_127(SPACE, " b = p1.name; ") + "return p1.name;\n", + {factory->NewStringFromStaticChars("abc"), + BytecodeGraphTester::NewObject("({ name : 'abc'})")}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(2048); + SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderKeyedLoad) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<2> snippets[] = { + {"return p1[p2];", + {factory->NewNumberFromInt(10), + BytecodeGraphTester::NewObject("({val : 10})"), + factory->NewStringFromStaticChars("val")}}, + {"return p1[100];", + {factory->NewStringFromStaticChars("abc"), + BytecodeGraphTester::NewObject("({100 : 'abc'})"), + factory->NewNumberFromInt(0)}}, + {"var b = 100; return p1[b];", + {factory->NewStringFromStaticChars("abc"), + BytecodeGraphTester::NewObject("({100 : 'abc'})"), + factory->NewNumberFromInt(0)}}, + {"'use strict'; return p1[p2];", + {factory->NewNumberFromInt(10), + BytecodeGraphTester::NewObject("({val : 10 })"), + factory->NewStringFromStaticChars("val")}}, + {"'use strict'; return p1[100];", + {factory->NewNumberFromInt(10), + BytecodeGraphTester::NewObject("({100 : 10})"), + factory->NewNumberFromInt(0)}}, + {"'use strict'; var b = p2; return p1[b];", + {factory->NewStringFromStaticChars("abc"), + BytecodeGraphTester::NewObject("({100 : 'abc'})"), + factory->NewNumberFromInt(100)}}, + {"var b;\n" REPEAT_127(SPACE, " b = p1[p2]; ") " return p1[p2];\n", + {factory->NewStringFromStaticChars("abc"), + BytecodeGraphTester::NewObject("({100 : 'abc'})"), + factory->NewNumberFromInt(100)}}, + {"'use strict'; var b;\n" REPEAT_127(SPACE, + " b = p1[p2]; ") "return p1[p2];\n", + {factory->NewStringFromStaticChars("abc"), + BytecodeGraphTester::NewObject("({ 100 : 'abc'})"), + factory->NewNumberFromInt(100)}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(2048); + SNPrintF(script, "function %s(p1, p2) { %s };\n%s(0);", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0), snippets[i].parameter(1)) + .ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderNamedStore) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<1> snippets[] = { + {"return p1.val = 20;", + {factory->NewNumberFromInt(20), + BytecodeGraphTester::NewObject("({val : 10})")}}, + {"p1.type = 'int'; return p1.type;", + {factory->NewStringFromStaticChars("int"), + BytecodeGraphTester::NewObject("({val : 10})")}}, + {"p1.name = 'def'; return p1[\"name\"];", + {factory->NewStringFromStaticChars("def"), + BytecodeGraphTester::NewObject("({name : 'abc'})")}}, + {"'use strict'; p1.val = 20; return p1.val;", + {factory->NewNumberFromInt(20), + BytecodeGraphTester::NewObject("({val : 10 })")}}, + {"'use strict'; return p1.type = 'int';", + {factory->NewStringFromStaticChars("int"), + BytecodeGraphTester::NewObject("({val : 10})")}}, + {"'use strict'; p1.val = 20; return p1[\"val\"];", + {factory->NewNumberFromInt(20), + BytecodeGraphTester::NewObject("({val : 10, name : 'abc'})")}}, + {"var b = 'abc';\n" REPEAT_127( + SPACE, " p1.name = b; ") " p1.name = 'def'; return p1.name;\n", + {factory->NewStringFromStaticChars("def"), + BytecodeGraphTester::NewObject("({name : 'abc'})")}}, + {"'use strict'; var b = 'def';\n" REPEAT_127( + SPACE, " p1.name = 'abc'; ") "p1.name = b; return p1.name;\n", + {factory->NewStringFromStaticChars("def"), + BytecodeGraphTester::NewObject("({ name : 'abc'})")}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(3072); + SNPrintF(script, "function %s(p1) { %s };\n%s({});", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderKeyedStore) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<2> snippets[] = { + {"p1[p2] = 20; return p1[p2];", + {factory->NewNumberFromInt(20), + BytecodeGraphTester::NewObject("({val : 10})"), + factory->NewStringFromStaticChars("val")}}, + {"return p1[100] = 'def';", + {factory->NewStringFromStaticChars("def"), + BytecodeGraphTester::NewObject("({100 : 'abc'})"), + factory->NewNumberFromInt(0)}}, + {"var b = 100; p1[b] = 'def'; return p1[b];", + {factory->NewStringFromStaticChars("def"), + BytecodeGraphTester::NewObject("({100 : 'abc'})"), + factory->NewNumberFromInt(0)}}, + {"'use strict'; p1[p2] = 20; return p1[p2];", + {factory->NewNumberFromInt(20), + BytecodeGraphTester::NewObject("({val : 10 })"), + factory->NewStringFromStaticChars("val")}}, + {"'use strict'; return p1[100] = 20;", + {factory->NewNumberFromInt(20), + BytecodeGraphTester::NewObject("({100 : 10})"), + factory->NewNumberFromInt(0)}}, + {"'use strict'; var b = p2; p1[b] = 'def'; return p1[b];", + {factory->NewStringFromStaticChars("def"), + BytecodeGraphTester::NewObject("({100 : 'abc'})"), + factory->NewNumberFromInt(100)}}, + {"var b;\n" REPEAT_127( + SPACE, " b = p1[p2]; ") " p1[p2] = 'def'; return p1[p2];\n", + {factory->NewStringFromStaticChars("def"), + BytecodeGraphTester::NewObject("({100 : 'abc'})"), + factory->NewNumberFromInt(100)}}, + {"'use strict'; var b;\n" REPEAT_127( + SPACE, " b = p1[p2]; ") " p1[p2] = 'def'; return p1[p2];\n", + {factory->NewStringFromStaticChars("def"), + BytecodeGraphTester::NewObject("({ 100 : 'abc'})"), + factory->NewNumberFromInt(100)}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(2048); + SNPrintF(script, "function %s(p1, p2) { %s };\n%s({});", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderPropertyCall) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<1> snippets[] = { + {"return p1.func();", + {factory->NewNumberFromInt(25), + BytecodeGraphTester::NewObject("({func() { return 25; }})")}}, + {"return p1.func('abc');", + {factory->NewStringFromStaticChars("abc"), + BytecodeGraphTester::NewObject("({func(a) { return a; }})")}}, + {"return p1.func(1, 2, 3, 4, 5, 6, 7, 8);", + {factory->NewNumberFromInt(36), + BytecodeGraphTester::NewObject( + "({func(a, b, c, d, e, f, g, h) {\n" + " return a + b + c + d + e + f + g + h;}})")}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(2048); + SNPrintF(script, "function %s(p1) { %s };\n%s({func() {}});", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderCallNew) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"function counter() { this.count = 20; }\n" + "function f() {\n" + " var c = new counter();\n" + " return c.count;\n" + "}; f()", + {factory->NewNumberFromInt(20)}}, + {"function counter(arg0) { this.count = 17; this.x = arg0; }\n" + "function f() {\n" + " var c = new counter(6);\n" + " return c.count + c.x;\n" + "}; f()", + {factory->NewNumberFromInt(23)}}, + {"function counter(arg0, arg1) {\n" + " this.count = 17; this.x = arg0; this.y = arg1;\n" + "}\n" + "function f() {\n" + " var c = new counter(3, 5);\n" + " return c.count + c.x + c.y;\n" + "}; f()", + {factory->NewNumberFromInt(25)}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderCreateClosure) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"function f() {\n" + " function counter() { this.count = 20; }\n" + " var c = new counter();\n" + " return c.count;\n" + "}; f()", + {factory->NewNumberFromInt(20)}}, + {"function f() {\n" + " function counter(arg0) { this.count = 17; this.x = arg0; }\n" + " var c = new counter(6);\n" + " return c.count + c.x;\n" + "}; f()", + {factory->NewNumberFromInt(23)}}, + {"function f() {\n" + " function counter(arg0, arg1) {\n" + " this.count = 17; this.x = arg0; this.y = arg1;\n" + " }\n" + " var c = new counter(3, 5);\n" + " return c.count + c.x + c.y;\n" + "}; f()", + {factory->NewNumberFromInt(25)}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderCallRuntime) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<1> snippets[] = { + {"function f(arg0) { return %MaxSmi(); }\nf()", + {factory->NewNumberFromInt(Smi::kMaxValue), factory->undefined_value()}}, + {"function f(arg0) { return %IsArray(arg0) }\nf(undefined)", + {factory->true_value(), BytecodeGraphTester::NewObject("[1, 2, 3]")}}, + {"function f(arg0) { return %Add(arg0, 2) }\nf(1)", + {factory->NewNumberFromInt(5), factory->NewNumberFromInt(3)}}, + {"function f(arg0) { return %spread_arguments(arg0).length }\nf([])", + {factory->NewNumberFromInt(3), + BytecodeGraphTester::NewObject("[1, 2, 3]")}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderGlobals) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"var global = 321;\n function f() { return global; };\n f();", + {factory->NewNumberFromInt(321)}}, + {"var global = 321;\n" + "function f() { global = 123; return global };\n f();", + {factory->NewNumberFromInt(123)}}, + {"var global = function() { return 'abc'};\n" + "function f() { return global(); };\n f();", + {factory->NewStringFromStaticChars("abc")}}, + {"var global = 456;\n" + "function f() { 'use strict'; return global; };\n f();", + {factory->NewNumberFromInt(456)}}, + {"var global = 987;\n" + "function f() { 'use strict'; global = 789; return global };\n f();", + {factory->NewNumberFromInt(789)}}, + {"var global = function() { return 'xyz'};\n" + "function f() { 'use strict'; return global(); };\n f();", + {factory->NewStringFromStaticChars("xyz")}}, + {"var global = 'abc'; var global_obj = {val:123};\n" + "function f() {\n" REPEAT_127( + SPACE, " var b = global_obj.name;\n") "return global; };\n f();\n", + {factory->NewStringFromStaticChars("abc")}}, + {"var global = 'abc'; var global_obj = {val:123};\n" + "function f() { 'use strict';\n" REPEAT_127( + SPACE, " var b = global_obj.name;\n") "global = 'xyz'; return " + "global };\n f();\n", + {factory->NewStringFromStaticChars("xyz")}}, + {"function f() { return typeof(undeclared_var); }\n; f();\n", + {factory->NewStringFromStaticChars("undefined")}}, + {"var defined_var = 10; function f() { return typeof(defined_var); }\n; " + "f();\n", + {factory->NewStringFromStaticChars("number")}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderToObject) { + // TODO(mythria): tests for ToObject. Needs ForIn. +} + + +TEST(BytecodeGraphBuilderToName) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"var a = 'val'; var obj = {[a] : 10}; return obj.val;", + {factory->NewNumberFromInt(10)}}, + {"var a = 20; var obj = {[a] : 10}; return obj['20'];", + {factory->NewNumberFromInt(10)}}, + {"var a = 20; var obj = {[a] : 10}; return obj[20];", + {factory->NewNumberFromInt(10)}}, + {"var a = {val:23}; var obj = {[a] : 10}; return obj[a];", + {factory->NewNumberFromInt(10)}}, + {"var a = {val:23}; var obj = {[a] : 10}; return obj['[object Object]'];", + {factory->NewNumberFromInt(10)}}, + {"var a = {toString : function() { return 'x'}};\n" + "var obj = {[a] : 10};\n" + "return obj.x;", + {factory->NewNumberFromInt(10)}}, + {"var a = {valueOf : function() { return 'x'}};\n" + "var obj = {[a] : 10};\n" + "return obj.x;", + {factory->undefined_value()}}, + {"var a = {[Symbol.toPrimitive] : function() { return 'x'}};\n" + "var obj = {[a] : 10};\n" + "return obj.x;", + {factory->NewNumberFromInt(10)}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s() { %s }\n%s({});", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderLogicalNot) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<1> snippets[] = { + {"return !p1;", + {factory->false_value(), + BytecodeGraphTester::NewObject("({val : 10})")}}, + {"return !p1;", {factory->true_value(), factory->NewNumberFromInt(0)}}, + {"return !p1;", {factory->true_value(), factory->undefined_value()}}, + {"return !p1;", {factory->false_value(), factory->NewNumberFromInt(10)}}, + {"return !p1;", {factory->false_value(), factory->true_value()}}, + {"return !p1;", + {factory->false_value(), factory->NewStringFromStaticChars("abc")}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderTypeOf) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<1> snippets[] = { + {"return typeof p1;", + {factory->NewStringFromStaticChars("object"), + BytecodeGraphTester::NewObject("({val : 10})")}}, + {"return typeof p1;", + {factory->NewStringFromStaticChars("undefined"), + factory->undefined_value()}}, + {"return typeof p1;", + {factory->NewStringFromStaticChars("number"), + factory->NewNumberFromInt(10)}}, + {"return typeof p1;", + {factory->NewStringFromStaticChars("boolean"), factory->true_value()}}, + {"return typeof p1;", + {factory->NewStringFromStaticChars("string"), + factory->NewStringFromStaticChars("abc")}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderCountOperation) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<1> snippets[] = { + {"return ++p1;", + {factory->NewNumberFromInt(11), factory->NewNumberFromInt(10)}}, + {"return p1++;", + {factory->NewNumberFromInt(10), factory->NewNumberFromInt(10)}}, + {"return p1++ + 10;", + {factory->NewHeapNumber(15.23), factory->NewHeapNumber(5.23)}}, + {"return 20 + ++p1;", + {factory->NewHeapNumber(27.23), factory->NewHeapNumber(6.23)}}, + {"return --p1;", + {factory->NewHeapNumber(9.8), factory->NewHeapNumber(10.8)}}, + {"return p1--;", + {factory->NewHeapNumber(10.8), factory->NewHeapNumber(10.8)}}, + {"return p1-- + 10;", + {factory->NewNumberFromInt(20), factory->NewNumberFromInt(10)}}, + {"return 20 + --p1;", + {factory->NewNumberFromInt(29), factory->NewNumberFromInt(10)}}, + {"return p1.val--;", + {factory->NewNumberFromInt(10), + BytecodeGraphTester::NewObject("({val : 10})")}}, + {"return ++p1['val'];", + {factory->NewNumberFromInt(11), + BytecodeGraphTester::NewObject("({val : 10})")}}, + {"return ++p1[1];", + {factory->NewNumberFromInt(11), + BytecodeGraphTester::NewObject("({1 : 10})")}}, + {" function inner() { return p1 } return --p1;", + {factory->NewNumberFromInt(9), factory->NewNumberFromInt(10)}}, + {" function inner() { return p1 } return p1--;", + {factory->NewNumberFromInt(10), factory->NewNumberFromInt(10)}}, + {"return ++p1;", + {factory->nan_value(), factory->NewStringFromStaticChars("String")}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderDelete) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<1> snippets[] = { + {"return delete p1.val;", + {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})")}}, + {"delete p1.val; return p1.val;", + {factory->undefined_value(), + BytecodeGraphTester::NewObject("({val : 10})")}}, + {"delete p1.name; return p1.val;", + {factory->NewNumberFromInt(10), + BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}}, + {"'use strict'; return delete p1.val;", + {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})")}}, + {"'use strict'; delete p1.val; return p1.val;", + {factory->undefined_value(), + BytecodeGraphTester::NewObject("({val : 10})")}}, + {"'use strict'; delete p1.name; return p1.val;", + {factory->NewNumberFromInt(10), + BytecodeGraphTester::NewObject("({val : 10, name:'abc'})")}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderDeleteGlobal) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"var obj = {val : 10, type : 'int'};" + "function f() {return delete obj;};", + {factory->false_value()}}, + {"function f() {return delete this;};", {factory->true_value()}}, + {"var obj = {val : 10, type : 'int'};" + "function f() {return delete obj.val;};", + {factory->true_value()}}, + {"var obj = {val : 10, type : 'int'};" + "function f() {'use strict'; return delete obj.val;};", + {factory->true_value()}}, + {"var obj = {val : 10, type : 'int'};" + "function f() {delete obj.val; return obj.val;};", + {factory->undefined_value()}}, + {"var obj = {val : 10, type : 'int'};" + "function f() {'use strict'; delete obj.val; return obj.val;};", + {factory->undefined_value()}}, + {"var obj = {1 : 10, 2 : 20};" + "function f() { return delete obj[1]; };", + {factory->true_value()}}, + {"var obj = {1 : 10, 2 : 20};" + "function f() { 'use strict'; return delete obj[1];};", + {factory->true_value()}}, + {"obj = {1 : 10, 2 : 20};" + "function f() { delete obj[1]; return obj[2];};", + {factory->NewNumberFromInt(20)}}, + {"function f() {" + " var obj = {1 : 10, 2 : 20};" + " function inner() { return obj[1]; };" + " return delete obj[1];" + "}", + {factory->true_value()}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "%s %s({});", snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderDeleteLookupSlot) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + // TODO(mythria): Add more tests when we have support for LdaLookupSlot. + const char* function_prologue = "var f;" + "var x = 1;" + "y = 10;" + "var obj = {val:10};" + "var z = 30;" + "function f1() {" + " var z = 20;" + " eval(\"function t() {"; + const char* function_epilogue = " }; f = t; t();\");" + "}" + "f1();"; + + ExpectedSnippet<0> snippets[] = { + {"return delete y;", {factory->true_value()}}, + {"return delete z;", {factory->false_value()}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet, + function_epilogue); + + BytecodeGraphTester tester(isolate, zone, script.start(), "t"); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderLookupSlot) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + const char* function_prologue = "var f;" + "var x = 12;" + "y = 10;" + "var obj = {val:3.1414};" + "var z = 30;" + "function f1() {" + " var z = 20;" + " eval(\"function t() {"; + const char* function_epilogue = " }; f = t; t();\");" + "}" + "f1();"; + + ExpectedSnippet<0> snippets[] = { + {"return x;", {factory->NewNumber(12)}}, + {"return obj.val;", {factory->NewNumber(3.1414)}}, + {"return typeof x;", {factory->NewStringFromStaticChars("number")}}, + {"return typeof dummy;", + {factory->NewStringFromStaticChars("undefined")}}, + {"x = 23; return x;", {factory->NewNumber(23)}}, + {"'use strict'; obj.val = 23.456; return obj.val;", + {factory->NewNumber(23.456)}}}; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet, + function_epilogue); + + BytecodeGraphTester tester(isolate, zone, script.start(), "t"); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderLookupSlotWide) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + const char* function_prologue = + "var f;" + "var x = 12;" + "y = 10;" + "var obj = {val:3.1414};" + "var z = 30;" + "function f1() {" + " var z = 20;" + " eval(\"function t() {"; + const char* function_epilogue = + " }; f = t; t();\");" + "}" + "f1();"; + + ExpectedSnippet<0> snippets[] = { + {"var y = 2.3;" REPEAT_256(SPACE, "y = 2.3;") "return x;", + {factory->NewNumber(12)}}, + {"var y = 2.3;" REPEAT_256(SPACE, "y = 2.3;") "return typeof x;", + {factory->NewStringFromStaticChars("number")}}, + {"var y = 2.3;" REPEAT_256(SPACE, "y = 2.3;") "return x = 23;", + {factory->NewNumber(23)}}, + {"'use strict';" REPEAT_256(SPACE, "y = 2.3;") "return obj.val = 23.456;", + {factory->NewNumber(23.456)}}}; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(3072); + SNPrintF(script, "%s %s %s", function_prologue, snippets[i].code_snippet, + function_epilogue); + + BytecodeGraphTester tester(isolate, zone, script.start(), "t"); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderCallLookupSlot) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + + ExpectedSnippet<0> snippets[] = { + {"g = function(){ return 2 }; eval(''); return g();", + {handle(Smi::FromInt(2), isolate)}}, + {"g = function(){ return 2 }; eval('g = function() {return 3}');\n" + "return g();", + {handle(Smi::FromInt(3), isolate)}}, + {"g = { x: function(){ return this.y }, y: 20 };\n" + "eval('g = { x: g.x, y: 30 }');\n" + "return g.x();", + {handle(Smi::FromInt(30), isolate)}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, + snippets[i].code_snippet, kFunctionName); + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderEval) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"return eval('1;');", {handle(Smi::FromInt(1), isolate)}}, + {"return eval('100 * 20;');", {handle(Smi::FromInt(2000), isolate)}}, + {"var x = 10; return eval('x + 20;');", + {handle(Smi::FromInt(30), isolate)}}, + {"var x = 10; eval('x = 33;'); return x;", + {handle(Smi::FromInt(33), isolate)}}, + {"'use strict'; var x = 20; var z = 0;\n" + "eval('var x = 33; z = x;'); return x + z;", + {handle(Smi::FromInt(53), isolate)}}, + {"eval('var x = 33;'); eval('var y = x + 20'); return x + y;", + {handle(Smi::FromInt(86), isolate)}}, + {"var x = 1; eval('for(i = 0; i < 10; i++) x = x + 1;'); return x", + {handle(Smi::FromInt(11), isolate)}}, + {"var x = 10; eval('var x = 20;'); return x;", + {handle(Smi::FromInt(20), isolate)}}, + {"var x = 1; eval('\"use strict\"; var x = 2;'); return x;", + {handle(Smi::FromInt(1), isolate)}}, + {"'use strict'; var x = 1; eval('var x = 2;'); return x;", + {handle(Smi::FromInt(1), isolate)}}, + {"var x = 10; eval('x + 20;'); return typeof x;", + {factory->NewStringFromStaticChars("number")}}, + {"eval('var y = 10;'); return typeof unallocated;", + {factory->NewStringFromStaticChars("undefined")}}, + {"'use strict'; eval('var y = 10;'); return typeof unallocated;", + {factory->NewStringFromStaticChars("undefined")}}, + {"eval('var x = 10;'); return typeof x;", + {factory->NewStringFromStaticChars("number")}}, + {"var x = {}; eval('var x = 10;'); return typeof x;", + {factory->NewStringFromStaticChars("number")}}, + {"'use strict'; var x = {}; eval('var x = 10;'); return typeof x;", + {factory->NewStringFromStaticChars("object")}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, + snippets[i].code_snippet, kFunctionName); + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderEvalParams) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + + ExpectedSnippet<1> snippets[] = { + {"var x = 10; return eval('x + p1;');", + {handle(Smi::FromInt(30), isolate), handle(Smi::FromInt(20), isolate)}}, + {"var x = 10; eval('p1 = x;'); return p1;", + {handle(Smi::FromInt(10), isolate), handle(Smi::FromInt(20), isolate)}}, + {"var a = 10;" + "function inner() { return eval('a + p1;');}" + "return inner();", + {handle(Smi::FromInt(30), isolate), handle(Smi::FromInt(20), isolate)}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s(p1) { %s }\n%s(0);", kFunctionName, + snippets[i].code_snippet, kFunctionName); + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderEvalGlobal) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"function add_global() { eval('function f() { z = 33; }; f()'); };" + "function f() { add_global(); return z; }; f();", + {handle(Smi::FromInt(33), isolate)}}, + {"function add_global() {\n" + " eval('\"use strict\"; function f() { y = 33; };" + " try { f() } catch(e) {}');\n" + "}\n" + "function f() { add_global(); return typeof y; } f();", + {factory->NewStringFromStaticChars("undefined")}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + BytecodeGraphTester tester(isolate, zone, snippets[i].code_snippet); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +bool get_compare_result(Token::Value opcode, Handle<Object> lhs_value, + Handle<Object> rhs_value) { + switch (opcode) { + case Token::Value::EQ: + return Object::Equals(lhs_value, rhs_value).FromJust(); + case Token::Value::NE: + return !Object::Equals(lhs_value, rhs_value).FromJust(); + case Token::Value::EQ_STRICT: + return lhs_value->StrictEquals(*rhs_value); + case Token::Value::NE_STRICT: + return !lhs_value->StrictEquals(*rhs_value); + case Token::Value::LT: + return Object::LessThan(lhs_value, rhs_value).FromJust(); + case Token::Value::LTE: + return Object::LessThanOrEqual(lhs_value, rhs_value).FromJust(); + case Token::Value::GT: + return Object::GreaterThan(lhs_value, rhs_value).FromJust(); + case Token::Value::GTE: + return Object::GreaterThanOrEqual(lhs_value, rhs_value).FromJust(); + default: + UNREACHABLE(); + return false; + } +} + + +const char* get_code_snippet(Token::Value opcode) { + switch (opcode) { + case Token::Value::EQ: + return "return p1 == p2;"; + case Token::Value::NE: + return "return p1 != p2;"; + case Token::Value::EQ_STRICT: + return "return p1 === p2;"; + case Token::Value::NE_STRICT: + return "return p1 !== p2;"; + case Token::Value::LT: + return "return p1 < p2;"; + case Token::Value::LTE: + return "return p1 <= p2;"; + case Token::Value::GT: + return "return p1 > p2;"; + case Token::Value::GTE: + return "return p1 >= p2;"; + default: + UNREACHABLE(); + return ""; + } +} + + +TEST(BytecodeGraphBuilderCompare) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + Handle<Object> lhs_values[] = { + factory->NewNumberFromInt(10), factory->NewHeapNumber(3.45), + factory->NewStringFromStaticChars("abc"), + factory->NewNumberFromInt(SMI_MAX), factory->NewNumberFromInt(SMI_MIN)}; + Handle<Object> rhs_values[] = {factory->NewNumberFromInt(10), + factory->NewStringFromStaticChars("10"), + factory->NewNumberFromInt(20), + factory->NewStringFromStaticChars("abc"), + factory->NewHeapNumber(3.45), + factory->NewNumberFromInt(SMI_MAX), + factory->NewNumberFromInt(SMI_MIN)}; + + for (size_t i = 0; i < arraysize(kCompareOperators); i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s(p1, p2) { %s }\n%s({}, {});", kFunctionName, + get_code_snippet(kCompareOperators[i]), kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); + for (size_t j = 0; j < arraysize(lhs_values); j++) { + for (size_t k = 0; k < arraysize(rhs_values); k++) { + Handle<Object> return_value = + callable(lhs_values[j], rhs_values[k]).ToHandleChecked(); + bool result = get_compare_result(kCompareOperators[i], lhs_values[j], + rhs_values[k]); + CHECK(return_value->SameValue(*factory->ToBoolean(result))); + } + } + } +} + + +TEST(BytecodeGraphBuilderTestIn) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<2> snippets[] = { + {"return p2 in p1;", + {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})"), + factory->NewStringFromStaticChars("val")}}, + {"return p2 in p1;", + {factory->true_value(), BytecodeGraphTester::NewObject("[]"), + factory->NewStringFromStaticChars("length")}}, + {"return p2 in p1;", + {factory->true_value(), BytecodeGraphTester::NewObject("[]"), + factory->NewStringFromStaticChars("toString")}}, + {"return p2 in p1;", + {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})"), + factory->NewStringFromStaticChars("toString")}}, + {"return p2 in p1;", + {factory->false_value(), BytecodeGraphTester::NewObject("({val : 10})"), + factory->NewStringFromStaticChars("abc")}}, + {"return p2 in p1;", + {factory->false_value(), BytecodeGraphTester::NewObject("({val : 10})"), + factory->NewNumberFromInt(10)}}, + {"return p2 in p1;", + {factory->true_value(), BytecodeGraphTester::NewObject("({10 : 'val'})"), + factory->NewNumberFromInt(10)}}, + {"return p2 in p1;", + {factory->false_value(), + BytecodeGraphTester::NewObject("({10 : 'val'})"), + factory->NewNumberFromInt(1)}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s(p1, p2) { %s }\n%s({}, {});", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0), snippets[i].parameter(1)) + .ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderTestInstanceOf) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<1> snippets[] = { + {"return p1 instanceof Object;", + {factory->true_value(), BytecodeGraphTester::NewObject("({val : 10})")}}, + {"return p1 instanceof String;", + {factory->false_value(), factory->NewStringFromStaticChars("string")}}, + {"var cons = function() {};" + "var obj = new cons();" + "return obj instanceof cons;", + {factory->true_value(), factory->undefined_value()}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s(p1) { %s }\n%s({});", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderThrow) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + + // TODO(mythria): Add more tests when real try-catch and deoptimization + // information are supported. + ExpectedSnippet<0, const char*> snippets[] = { + {"throw undefined;", {"Uncaught undefined"}}, + {"throw 1;", {"Uncaught 1"}}, + {"throw 'Error';", {"Uncaught Error"}}, + {"throw 'Error1'; throw 'Error2'", {"Uncaught Error1"}}, + // TODO(mythria): Enable these tests when JumpIfTrue is supported. + // {"var a = true; if (a) { throw 'Error'; }", {"Error"}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, + snippets[i].code_snippet, kFunctionName); + BytecodeGraphTester tester(isolate, zone, script.start()); + v8::Local<v8::String> message = tester.CheckThrowsReturnMessage()->Get(); + v8::Local<v8::String> expected_string = v8_str(snippets[i].return_value()); + CHECK( + message->Equals(CcTest::isolate()->GetCurrentContext(), expected_string) + .FromJust()); + } +} + + +TEST(BytecodeGraphBuilderContext) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"var x = 'outer';" + "function f() {" + " 'use strict';" + " {" + " let x = 'inner';" + " (function() {x});" + " }" + "return(x);" + "}" + "f();", + {factory->NewStringFromStaticChars("outer")}}, + {"var x = 'outer';" + "function f() {" + " 'use strict';" + " {" + " let x = 'inner ';" + " var innerFunc = function() {return x};" + " }" + "return(innerFunc() + x);" + "}" + "f();", + {factory->NewStringFromStaticChars("inner outer")}}, + {"var x = 'outer';" + "function f() {" + " 'use strict';" + " {" + " let x = 'inner ';" + " var innerFunc = function() {return x;};" + " {" + " let x = 'innermost ';" + " var innerMostFunc = function() {return x + innerFunc();};" + " }" + " x = 'inner_changed ';" + " }" + " return(innerMostFunc() + x);" + "}" + "f();", + {factory->NewStringFromStaticChars("innermost inner_changed outer")}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "%s", snippets[i].code_snippet); + + BytecodeGraphTester tester(isolate, zone, script.start(), "f"); + auto callable = tester.GetCallable<>("f"); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderLoadContext) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<1> snippets[] = { + {"function Outer() {" + " var outerVar = 2;" + " function Inner(innerArg) {" + " this.innerFunc = function () {" + " return outerVar * innerArg;" + " };" + " };" + " this.getInnerFunc = function GetInner() {" + " return new Inner(3).innerFunc;" + " }" + "}" + "var f = new Outer().getInnerFunc();" + "f();", + {factory->NewNumberFromInt(6), factory->undefined_value()}}, + {"function Outer() {" + " var outerVar = 2;" + " function Inner(innerArg) {" + " this.innerFunc = function () {" + " outerVar = innerArg; return outerVar;" + " };" + " };" + " this.getInnerFunc = function GetInner() {" + " return new Inner(10).innerFunc;" + " }" + "}" + "var f = new Outer().getInnerFunc();" + "f();", + {factory->NewNumberFromInt(10), factory->undefined_value()}}, + {"function testOuter(outerArg) {" + " this.testinnerFunc = function testInner(innerArg) {" + " return innerArg + outerArg;" + " }" + "}" + "var f = new testOuter(10).testinnerFunc;" + "f(0);", + {factory->NewNumberFromInt(14), factory->NewNumberFromInt(4)}}, + {"function testOuter(outerArg) {" + " var outerVar = outerArg * 2;" + " this.testinnerFunc = function testInner(innerArg) {" + " outerVar = outerVar + innerArg; return outerVar;" + " }" + "}" + "var f = new testOuter(10).testinnerFunc;" + "f(0);", + {factory->NewNumberFromInt(24), factory->NewNumberFromInt(4)}}}; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "%s", snippets[i].code_snippet); + + BytecodeGraphTester tester(isolate, zone, script.start(), "*"); + auto callable = tester.GetCallable<Handle<Object>>("f"); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderCreateArgumentsNoParameters) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"function f() {return arguments[0];}", {factory->undefined_value()}}, + {"function f(a) {return arguments[0];}", {factory->undefined_value()}}, + {"function f() {'use strict'; return arguments[0];}", + {factory->undefined_value()}}, + {"function f(a) {'use strict'; return arguments[0];}", + {factory->undefined_value()}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "%s\n%s();", snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderCreateArguments) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<3> snippets[] = { + {"function f(a, b, c) {return arguments[0];}", + {factory->NewNumberFromInt(1), factory->NewNumberFromInt(1), + factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}}, + {"function f(a, b, c) {return arguments[3];}", + {factory->undefined_value(), factory->NewNumberFromInt(1), + factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}}, + {"function f(a, b, c) { b = c; return arguments[1];}", + {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1), + factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}}, + {"function f(a, b, c) {'use strict'; return arguments[0];}", + {factory->NewNumberFromInt(1), factory->NewNumberFromInt(1), + factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}}, + {"function f(a, b, c) {'use strict'; return arguments[3];}", + {factory->undefined_value(), factory->NewNumberFromInt(1), + factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}}, + {"function f(a, b, c) {'use strict'; b = c; return arguments[1];}", + {factory->NewNumberFromInt(2), factory->NewNumberFromInt(1), + factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}}, + {"function inline_func(a, b) { return arguments[0] }" + "function f(a, b, c) {return inline_func(b, c) + arguments[0];}", + {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1), + factory->NewNumberFromInt(2), factory->NewNumberFromInt(30)}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "%s\n%s();", snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = + tester.GetCallable<Handle<Object>, Handle<Object>, Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0), snippets[i].parameter(1), + snippets[i].parameter(2)) + .ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderRegExpLiterals) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"return /abd/.exec('cccabbdd');", {factory->null_value()}}, + {"return /ab+d/.exec('cccabbdd')[0];", + {factory->NewStringFromStaticChars("abbd")}}, + {"var a = 3.1414;" + REPEAT_256(SPACE, "a = 3.1414;") + "return /ab+d/.exec('cccabbdd')[0];", + {factory->NewStringFromStaticChars("abbd")}}, + {"return /ab+d/.exec('cccabbdd')[1];", {factory->undefined_value()}}, + {"return /AbC/i.exec('ssaBC')[0];", + {factory->NewStringFromStaticChars("aBC")}}, + {"return 'ssaBC'.match(/AbC/i)[0];", + {factory->NewStringFromStaticChars("aBC")}}, + {"return 'ssaBCtAbC'.match(/(AbC)/gi)[1];", + {factory->NewStringFromStaticChars("AbC")}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(4096); + SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderArrayLiterals) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"return [][0];", {factory->undefined_value()}}, + {"return [1, 3, 2][1];", {factory->NewNumberFromInt(3)}}, + {"var a;" REPEAT_256(SPACE, "a = 9.87;") "return [1, 3, 2][1];", + {factory->NewNumberFromInt(3)}}, + {"return ['a', 'b', 'c'][2];", {factory->NewStringFromStaticChars("c")}}, + {"var a = 100; return [a, a++, a + 2, a + 3][2];", + {factory->NewNumberFromInt(103)}}, + {"var a = 100; return [a, ++a, a + 2, a + 3][1];", + {factory->NewNumberFromInt(101)}}, + {"var a = 9.2;" + REPEAT_256(SPACE, "a = 9.34;") + "return [a, ++a, a + 2, a + 3][2];", + {factory->NewHeapNumber(12.34)}}, + {"return [[1, 2, 3], ['a', 'b', 'c']][1][0];", + {factory->NewStringFromStaticChars("a")}}, + {"var t = 't'; return [[t, t + 'est'], [1 + t]][0][1];", + {factory->NewStringFromStaticChars("test")}}, + {"var t = 't'; return [[t, t + 'est'], [1 + t]][1][0];", + {factory->NewStringFromStaticChars("1t")}}}; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(4096); + SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderObjectLiterals) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"return { }.name;", {factory->undefined_value()}}, + {"return { name: 'string', val: 9.2 }.name;", + {factory->NewStringFromStaticChars("string")}}, + {"var a;\n" + REPEAT_256(SPACE, "a = 1.23;\n") + "return { name: 'string', val: 9.2 }.name;", + {factory->NewStringFromStaticChars("string")}}, + {"return { name: 'string', val: 9.2 }['name'];", + {factory->NewStringFromStaticChars("string")}}, + {"var a = 15; return { name: 'string', val: a }.val;", + {factory->NewNumberFromInt(15)}}, + {"var a;" + REPEAT_256(SPACE, "a = 1.23;") + "return { name: 'string', val: a }.val;", + {factory->NewHeapNumber(1.23)}}, + {"var a = 15; var b = 'val'; return { name: 'string', val: a }[b];", + {factory->NewNumberFromInt(15)}}, + {"var a = 5; return { val: a, val: a + 1 }.val;", + {factory->NewNumberFromInt(6)}}, + {"return { func: function() { return 'test' } }.func();", + {factory->NewStringFromStaticChars("test")}}, + {"return { func(a) { return a + 'st'; } }.func('te');", + {factory->NewStringFromStaticChars("test")}}, + {"return { get a() { return 22; } }.a;", {factory->NewNumberFromInt(22)}}, + {"var a = { get b() { return this.x + 't'; },\n" + " set b(val) { this.x = val + 's' } };\n" + "a.b = 'te';\n" + "return a.b;", + {factory->NewStringFromStaticChars("test")}}, + {"var a = 123; return { 1: a }[1];", {factory->NewNumberFromInt(123)}}, + {"return Object.getPrototypeOf({ __proto__: null });", + {factory->null_value()}}, + {"var a = 'test'; return { [a]: 1 }.test;", + {factory->NewNumberFromInt(1)}}, + {"var a = 'test'; return { b: a, [a]: a + 'ing' }['test']", + {factory->NewStringFromStaticChars("testing")}}, + {"var a = 'proto_str';\n" + "var b = { [a]: 1, __proto__: { var : a } };\n" + "return Object.getPrototypeOf(b).var", + {factory->NewStringFromStaticChars("proto_str")}}, + {"var n = 'name';\n" + "return { [n]: 'val', get a() { return 987 } }['a'];", + {factory->NewNumberFromInt(987)}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(4096); + SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, + snippets[i].code_snippet, kFunctionName); + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderIf) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<1> snippets[] = { + {"if (p1 > 1) return 1;\n" + "return -1;", + {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}}, + {"if (p1 > 1) return 1;\n" + "return -1;", + {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(1)}}, + {"if (p1 > 1) { return 1; } else { return -1; }", + {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}}, + {"if (p1 > 1) { return 1; } else { return -1; }", + {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(1)}}, + {"if (p1 > 50) {\n" + " return 1;\n" + "} else if (p1 < 10) {\n" + " return 10;\n" + "} else {\n" + " return -10;\n" + "}", + {factory->NewNumberFromInt(1), factory->NewNumberFromInt(51)}}, + {"if (p1 > 50) {\n" + " return 1;\n" + "} else if (p1 < 10) {\n" + " return 10;\n" + "} else {\n" + " return 100;\n" + "}", + {factory->NewNumberFromInt(10), factory->NewNumberFromInt(9)}}, + {"if (p1 > 50) {\n" + " return 1;\n" + "} else if (p1 < 10) {\n" + " return 10;\n" + "} else {\n" + " return 100;\n" + "}", + {factory->NewNumberFromInt(100), factory->NewNumberFromInt(10)}}, + {"if (p1 >= 0) {\n" + " if (p1 > 10) { return 2; } else { return 1; }\n" + "} else {\n" + " if (p1 < -10) { return -2; } else { return -1; }\n" + "}", + {factory->NewNumberFromInt(2), factory->NewNumberFromInt(100)}}, + {"if (p1 >= 0) {\n" + " if (p1 > 10) { return 2; } else { return 1; }\n" + "} else {\n" + " if (p1 < -10) { return -2; } else { return -1; }\n" + "}", + {factory->NewNumberFromInt(1), factory->NewNumberFromInt(10)}}, + {"if (p1 >= 0) {\n" + " if (p1 > 10) { return 2; } else { return 1; }\n" + "} else {\n" + " if (p1 < -10) { return -2; } else { return -1; }\n" + "}", + {factory->NewNumberFromInt(-2), factory->NewNumberFromInt(-11)}}, + {"if (p1 >= 0) {\n" + " if (p1 > 10) { return 2; } else { return 1; }\n" + "} else {\n" + " if (p1 < -10) { return -2; } else { return -1; }\n" + "}", + {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(-10)}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(2048); + SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderConditionalOperator) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<1> snippets[] = { + {"return (p1 > 1) ? 1 : -1;", + {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}}, + {"return (p1 > 1) ? 1 : -1;", + {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(0)}}, + {"return (p1 > 50) ? 1 : ((p1 < 10) ? 10 : -10);", + {factory->NewNumberFromInt(10), factory->NewNumberFromInt(2)}}, + {"return (p1 > 50) ? 1 : ((p1 < 10) ? 10 : -10);", + {factory->NewNumberFromInt(-10), factory->NewNumberFromInt(20)}}, + }; + + size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); + for (size_t i = 0; i < num_snippets; i++) { + ScopedVector<char> script(2048); + SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderSwitch) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + const char* switch_code = + "switch (p1) {\n" + " case 1: return 0;\n" + " case 2: return 1;\n" + " case 3:\n" + " case 4: return 2;\n" + " case 9: break;\n" + " default: return 3;\n" + "}\n" + "return 9;"; + + ExpectedSnippet<1> snippets[] = { + {switch_code, + {factory->NewNumberFromInt(0), factory->NewNumberFromInt(1)}}, + {switch_code, + {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}}, + {switch_code, + {factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}}, + {switch_code, + {factory->NewNumberFromInt(2), factory->NewNumberFromInt(4)}}, + {switch_code, + {factory->NewNumberFromInt(9), factory->NewNumberFromInt(9)}}, + {switch_code, + {factory->NewNumberFromInt(3), factory->NewNumberFromInt(5)}}, + {switch_code, + {factory->NewNumberFromInt(3), factory->NewNumberFromInt(6)}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + ScopedVector<char> script(2048); + SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0)).ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderNestedSwitch) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + const char* switch_code = + "switch (p1) {\n" + " case 0: {" + " switch (p2) { case 0: return 0; case 1: return 1; case 2: break; }\n" + " return -1;" + " }\n" + " case 1: {" + " switch (p2) { case 0: return 2; case 1: return 3; }\n" + " }\n" + " case 2: break;" + " }\n" + "return -2;"; + + ExpectedSnippet<2> snippets[] = { + {switch_code, + {factory->NewNumberFromInt(0), factory->NewNumberFromInt(0), + factory->NewNumberFromInt(0)}}, + {switch_code, + {factory->NewNumberFromInt(1), factory->NewNumberFromInt(0), + factory->NewNumberFromInt(1)}}, + {switch_code, + {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(0), + factory->NewNumberFromInt(2)}}, + {switch_code, + {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(0), + factory->NewNumberFromInt(3)}}, + {switch_code, + {factory->NewNumberFromInt(2), factory->NewNumberFromInt(1), + factory->NewNumberFromInt(0)}}, + {switch_code, + {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1), + factory->NewNumberFromInt(1)}}, + {switch_code, + {factory->NewNumberFromInt(-2), factory->NewNumberFromInt(1), + factory->NewNumberFromInt(2)}}, + {switch_code, + {factory->NewNumberFromInt(-2), factory->NewNumberFromInt(2), + factory->NewNumberFromInt(0)}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + ScopedVector<char> script(2048); + SNPrintF(script, "function %s(p1, p2) { %s };\n%s(0, 0);", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); + Handle<Object> return_value = + callable(snippets[i].parameter(0), snippets[i].parameter(1)) + .ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderBreakableBlocks) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"var x = 0;\n" + "my_heart: {\n" + " x = x + 1;\n" + " break my_heart;\n" + " x = x + 2;\n" + "}\n" + "return x;\n", + {factory->NewNumberFromInt(1)}}, + {"var sum = 0;\n" + "outta_here: {\n" + " for (var x = 0; x < 10; ++x) {\n" + " for (var y = 0; y < 3; ++y) {\n" + " ++sum;\n" + " if (x + y == 12) { break outta_here; }\n" + " }\n" + " }\n" + "}\n" + "return sum;", + {factory->NewNumber(30)}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderWhile) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"var x = 1; while (x < 1) { x *= 100; } return x;", + {factory->NewNumberFromInt(1)}}, + {"var x = 1, y = 0; while (x < 7) { y += x * x; x += 1; } return y;", + {factory->NewNumberFromInt(91)}}, + {"var x = 1; while (true) { x += 1; if (x == 10) break; } return x;", + {factory->NewNumberFromInt(10)}}, + {"var x = 1; while (false) { x += 1; } return x;", + {factory->NewNumberFromInt(1)}}, + {"var x = 0;\n" + "while (true) {\n" + " while (x < 10) {\n" + " x = x * x + 1;\n" + " }" + " x += 1;\n" + " break;\n" + "}\n" + "return x;", + {factory->NewNumberFromInt(27)}}, + {"var x = 1, y = 0;\n" + "while (x < 7) {\n" + " x += 1;\n" + " if (x == 2) continue;\n" + " if (x == 3) continue;\n" + " y += x * x;\n" + " if (x == 4) break;\n" + "}\n" + "return y;", + {factory->NewNumberFromInt(16)}}}; + + for (size_t i = 0; i < arraysize(snippets); i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderDo) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"var x = 1; do { x *= 100; } while (x < 100); return x;", + {factory->NewNumberFromInt(100)}}, + {"var x = 1; do { x = x * x + 1; } while (x < 7) return x;", + {factory->NewNumberFromInt(26)}}, + {"var x = 1; do { x += 1; } while (false); return x;", + {factory->NewNumberFromInt(2)}}, + {"var x = 1, y = 0;\n" + "do {\n" + " x += 1;\n" + " if (x == 2) continue;\n" + " if (x == 3) continue;\n" + " y += x * x;\n" + " if (x == 4) break;\n" + "} while (x < 7);\n" + "return y;", + {factory->NewNumberFromInt(16)}}}; + + for (size_t i = 0; i < arraysize(snippets); i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderFor) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + + ExpectedSnippet<0> snippets[] = { + {"for (var x = 0;; x = 2 * x + 1) { if (x > 10) return x; }", + {factory->NewNumberFromInt(15)}}, + {"for (var x = 0; true; x = 2 * x + 1) { if (x > 100) return x; }", + {factory->NewNumberFromInt(127)}}, + {"for (var x = 0; false; x = 2 * x + 1) { if (x > 100) return x; } " + "return 0;", + {factory->NewNumberFromInt(0)}}, + {"for (var x = 0; x < 200; x = 2 * x + 1) { x = x; } return x;", + {factory->NewNumberFromInt(255)}}, + {"for (var x = 0; x < 200; x = 2 * x + 1) {} return x;", + {factory->NewNumberFromInt(255)}}, + {"var sum = 0;\n" + "for (var x = 0; x < 200; x += 1) {\n" + " if (x % 2) continue;\n" + " if (sum > 10) break;\n" + " sum += x;\n" + "}\n" + "return sum;", + {factory->NewNumberFromInt(12)}}, + {"var sum = 0;\n" + "for (var w = 0; w < 2; w++) {\n" + " for (var x = 0; x < 200; x += 1) {\n" + " if (x % 2) continue;\n" + " if (x > 4) break;\n" + " sum += x + w;\n" + " }\n" + "}\n" + "return sum;", + {factory->NewNumberFromInt(15)}}, + {"var sum = 0;\n" + "for (var w = 0; w < 2; w++) {\n" + " if (w == 1) break;\n" + " for (var x = 0; x < 200; x += 1) {\n" + " if (x % 2) continue;\n" + " if (x > 4) break;\n" + " sum += x + w;\n" + " }\n" + "}\n" + "return sum;", + {factory->NewNumberFromInt(6)}}, + {"var sum = 0;\n" + "for (var w = 0; w < 3; w++) {\n" + " if (w == 1) continue;\n" + " for (var x = 0; x < 200; x += 1) {\n" + " if (x % 2) continue;\n" + " if (x > 4) break;\n" + " sum += x + w;\n" + " }\n" + "}\n" + "return sum;", + {factory->NewNumberFromInt(18)}}, + {"var sum = 0;\n" + "for (var x = 1; x < 10; x += 2) {\n" + " for (var y = x; y < x + 2; y++) {\n" + " sum += y * y;\n" + " }\n" + "}\n" + "return sum;", + {factory->NewNumberFromInt(385)}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(BytecodeGraphBuilderForIn) { + HandleAndZoneScope scope; + Isolate* isolate = scope.main_isolate(); + Zone* zone = scope.main_zone(); + Factory* factory = isolate->factory(); + ExpectedSnippet<0> snippets[] = { + {"var sum = 0;\n" + "var empty = null;\n" + "for (var x in empty) { sum++; }\n" + "return sum;", + {factory->NewNumberFromInt(0)}}, + {"var sum = 100;\n" + "var empty = 1;\n" + "for (var x in empty) { sum++; }\n" + "return sum;", + {factory->NewNumberFromInt(100)}}, + {"for (var x in [ 10, 20, 30 ]) {}\n" + "return 2;", + {factory->NewNumberFromInt(2)}}, + {"var last = 0;\n" + "for (var x in [ 10, 20, 30 ]) {\n" + " last = x;\n" + "}\n" + "return +last;", + {factory->NewNumberFromInt(2)}}, + {"var first = -1;\n" + "for (var x in [ 10, 20, 30 ]) {\n" + " first = +x;\n" + " if (first > 0) break;\n" + "}\n" + "return first;", + {factory->NewNumberFromInt(1)}}, + {"var first = -1;\n" + "for (var x in [ 10, 20, 30 ]) {\n" + " if (first >= 0) continue;\n" + " first = x;\n" + "}\n" + "return +first;", + {factory->NewNumberFromInt(0)}}, + {"var sum = 0;\n" + "for (var x in [ 10, 20, 30 ]) {\n" + " for (var y in [ 11, 22, 33, 44, 55, 66, 77 ]) {\n" + " sum += 1;\n" + " }\n" + "}\n" + "return sum;", + {factory->NewNumberFromInt(21)}}, + {"var sum = 0;\n" + "for (var x in [ 10, 20, 30 ]) {\n" + " for (var y in [ 11, 22, 33, 44, 55, 66, 77 ]) {\n" + " if (sum == 7) break;\n" + " if (sum == 6) continue;\n" + " sum += 1;\n" + " }\n" + "}\n" + "return sum;", + {factory->NewNumberFromInt(6)}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + ScopedVector<char> script(1024); + SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, + snippets[i].code_snippet, kFunctionName); + + BytecodeGraphTester tester(isolate, zone, script.start()); + auto callable = tester.GetCallable<>(); + Handle<Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*snippets[i].return_value())); + } +} + + +TEST(JumpWithConstantsAndWideConstants) { + HandleAndZoneScope scope; + auto isolate = scope.main_isolate(); + const int kStep = 19; + int start = 7; + for (int constants = start; constants < 256 + 3 * kStep; constants += kStep) { + std::stringstream filler_os; + // Generate a string that consumes constant pool entries and + // spread out branch distances in script below. + for (int i = 0; i < constants; i++) { + filler_os << "var x_ = 'x_" << i << "';\n"; + } + std::string filler(filler_os.str()); + + std::stringstream script_os; + script_os << "function " << kFunctionName << "(a) {\n"; + script_os << " " << filler; + script_os << " for (var i = a; i < 2; i++) {\n"; + script_os << " " << filler; + script_os << " if (i == 0) { " << filler << "i = 10; continue; }\n"; + script_os << " else if (i == a) { " << filler << "i = 12; break; }\n"; + script_os << " else { " << filler << " }\n"; + script_os << " }\n"; + script_os << " return i;\n"; + script_os << "}\n"; + script_os << kFunctionName << "(0);\n"; + std::string script(script_os.str()); + auto factory = isolate->factory(); + auto zone = scope.main_zone(); + for (int a = 0; a < 3; a++) { + BytecodeGraphTester tester(isolate, zone, script.c_str()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_val = + callable(factory->NewNumberFromInt(a)).ToHandleChecked(); + static const int results[] = {11, 12, 2}; + CHECK_EQ(Handle<Smi>::cast(return_val)->value(), results[a]); + } + } +} + } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/compiler/test-run-deopt.cc b/deps/v8/test/cctest/compiler/test-run-deopt.cc index 458fcbb423..8b4c9dccb1 100644 --- a/deps/v8/test/cctest/compiler/test-run-deopt.cc +++ b/deps/v8/test/cctest/compiler/test-run-deopt.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/frames-inl.h" #include "test/cctest/cctest.h" #include "test/cctest/compiler/function-tester.h" diff --git a/deps/v8/test/cctest/compiler/test-run-inlining.cc b/deps/v8/test/cctest/compiler/test-run-inlining.cc index 9e82d550b1..f332d7499b 100644 --- a/deps/v8/test/cctest/compiler/test-run-inlining.cc +++ b/deps/v8/test/cctest/compiler/test-run-inlining.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/frames-inl.h" #include "test/cctest/compiler/function-tester.h" diff --git a/deps/v8/test/cctest/compiler/test-run-intrinsics.cc b/deps/v8/test/cctest/compiler/test-run-intrinsics.cc index fd2b3e6d16..b2017114b4 100644 --- a/deps/v8/test/cctest/compiler/test-run-intrinsics.cc +++ b/deps/v8/test/cctest/compiler/test-run-intrinsics.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "test/cctest/compiler/function-tester.h" namespace v8 { @@ -37,17 +34,6 @@ TEST(ClassOf) { } -TEST(HeapObjectGetMap) { - FunctionTester T("(function(a) { return %_HeapObjectGetMap(a); })", flags); - - Factory* factory = T.main_isolate()->factory(); - T.CheckCall(factory->null_map(), T.null()); - T.CheckCall(factory->undefined_map(), T.undefined()); - T.CheckCall(factory->heap_number_map(), T.Val(3.1415)); - T.CheckCall(factory->symbol_map(), factory->NewSymbol()); -} - - #define COUNTER_NAME "hurz" static int* LookupCounter(const char* name) { @@ -162,19 +148,6 @@ TEST(IsSmi) { } -TEST(MapGetInstanceType) { - FunctionTester T( - "(function(a) { return %_MapGetInstanceType(%_HeapObjectGetMap(a)); })", - flags); - - Factory* factory = T.main_isolate()->factory(); - T.CheckCall(T.Val(ODDBALL_TYPE), T.null()); - T.CheckCall(T.Val(ODDBALL_TYPE), T.undefined()); - T.CheckCall(T.Val(HEAP_NUMBER_TYPE), T.Val(3.1415)); - T.CheckCall(T.Val(SYMBOL_TYPE), factory->NewSymbol()); -} - - TEST(ObjectEquals) { FunctionTester T("(function(a,b) { return %_ObjectEquals(a,b); })", flags); CompileRun("var o = {}"); diff --git a/deps/v8/test/cctest/compiler/test-run-jsbranches.cc b/deps/v8/test/cctest/compiler/test-run-jsbranches.cc index 577a6d1dad..613528d7a0 100644 --- a/deps/v8/test/cctest/compiler/test-run-jsbranches.cc +++ b/deps/v8/test/cctest/compiler/test-run-jsbranches.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "test/cctest/compiler/function-tester.h" namespace v8 { diff --git a/deps/v8/test/cctest/compiler/test-run-jscalls.cc b/deps/v8/test/cctest/compiler/test-run-jscalls.cc index 2688c622e1..474453da7d 100644 --- a/deps/v8/test/cctest/compiler/test-run-jscalls.cc +++ b/deps/v8/test/cctest/compiler/test-run-jscalls.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "test/cctest/compiler/function-tester.h" namespace v8 { @@ -145,7 +142,7 @@ TEST(RuntimeCallCPP2) { TEST(RuntimeCallInline) { FLAG_allow_natives_syntax = true; - FunctionTester T("(function(a) { return %_IsSpecObject(a); })"); + FunctionTester T("(function(a) { return %_IsJSReceiver(a); })"); T.CheckCall(T.false_value(), T.Val(23), T.undefined()); T.CheckCall(T.false_value(), T.Val(4.2), T.undefined()); diff --git a/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc b/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc index 5c56b036ef..37b2a2d243 100644 --- a/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc +++ b/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "test/cctest/compiler/function-tester.h" namespace v8 { diff --git a/deps/v8/test/cctest/compiler/test-run-jsobjects.cc b/deps/v8/test/cctest/compiler/test-run-jsobjects.cc index 5b0fd39283..4bf10ca8fe 100644 --- a/deps/v8/test/cctest/compiler/test-run-jsobjects.cc +++ b/deps/v8/test/cctest/compiler/test-run-jsobjects.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "test/cctest/compiler/function-tester.h" namespace v8 { @@ -38,7 +35,6 @@ TEST(ArgumentsUnmapped) { TEST(ArgumentsRest) { - FLAG_harmony_rest_parameters = true; FunctionTester T("(function(a, ...args) { return args; })"); Handle<Object> arguments; diff --git a/deps/v8/test/cctest/compiler/test-run-jsops.cc b/deps/v8/test/cctest/compiler/test-run-jsops.cc index ff18613b10..9a2c4679a0 100644 --- a/deps/v8/test/cctest/compiler/test-run-jsops.cc +++ b/deps/v8/test/cctest/compiler/test-run-jsops.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "test/cctest/compiler/function-tester.h" namespace v8 { @@ -398,6 +395,7 @@ TEST(GlobalLoad) { TEST(GlobalStoreSloppy) { + FLAG_legacy_const = true; FunctionTester T("(function(a,b) { g = a + b; return g; })"); T.CheckCall(T.Val(33), T.Val(22), T.Val(11)); diff --git a/deps/v8/test/cctest/compiler/test-run-machops.cc b/deps/v8/test/cctest/compiler/test-run-machops.cc index 038fe241eb..11a3582cbb 100644 --- a/deps/v8/test/cctest/compiler/test-run-machops.cc +++ b/deps/v8/test/cctest/compiler/test-run-machops.cc @@ -2,9 +2,6 @@ // source code is governed by a BSD-style license that can be found in the // LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <cmath> #include <functional> #include <limits> @@ -23,8 +20,6 @@ namespace v8 { namespace internal { namespace compiler { -typedef RawMachineAssembler::Label MLabel; - TEST(RunInt32Add) { RawMachineAssemblerTester<int32_t> m; @@ -35,7 +30,7 @@ TEST(RunInt32Add) { TEST(RunWord32Ctz) { - BufferedRawMachineAssemblerTester<int32_t> m(kMachUint32); + BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); if (!m.machine()->Word32Ctz().IsSupported()) { // We can only test the operator if it exists on the testing platform. return; @@ -79,7 +74,7 @@ TEST(RunWord32Ctz) { TEST(RunWord32Clz) { - BufferedRawMachineAssemblerTester<int32_t> m(kMachUint32); + BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); m.Return(m.Word32Clz(m.Parameter(0))); CHECK_EQ(0, m.Call(uint32_t(0x80001000))); @@ -119,7 +114,7 @@ TEST(RunWord32Clz) { TEST(RunWord32Popcnt) { - BufferedRawMachineAssemblerTester<int32_t> m(kMachUint32); + BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); if (!m.machine()->Word32Popcnt().IsSupported()) { // We can only test the operator if it exists on the testing platform. return; @@ -139,7 +134,7 @@ TEST(RunWord32Popcnt) { #if V8_TARGET_ARCH_64_BIT TEST(RunWord64Clz) { - BufferedRawMachineAssemblerTester<int32_t> m(kMachUint64); + BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64()); m.Return(m.Word64Clz(m.Parameter(0))); CHECK_EQ(0, m.Call(uint64_t(0x8000100000000000))); @@ -211,7 +206,7 @@ TEST(RunWord64Clz) { TEST(RunWord64Ctz) { - RawMachineAssemblerTester<int32_t> m(kMachUint64); + RawMachineAssemblerTester<int32_t> m(MachineType::Uint64()); if (!m.machine()->Word64Ctz().IsSupported()) { return; } @@ -287,7 +282,7 @@ TEST(RunWord64Ctz) { TEST(RunWord64Popcnt) { - BufferedRawMachineAssemblerTester<int32_t> m(kMachUint64); + BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64()); if (!m.machine()->Word64Popcnt().IsSupported()) { return; } @@ -323,7 +318,7 @@ static Node* Int32Input(RawMachineAssemblerTester<int32_t>* m, int index) { case 6: return m->Int32Constant(0x01234567); case 7: - return m->Load(kMachInt32, m->PointerConstant(NULL)); + return m->Load(MachineType::Int32(), m->PointerConstant(NULL)); default: return NULL; } @@ -348,7 +343,8 @@ TEST(CodeGenInt32Binop) { for (size_t i = 0; i < arraysize(kOps); ++i) { for (int j = 0; j < 8; j++) { for (int k = 0; k < 8; k++) { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); Node* a = Int32Input(&m, j); Node* b = Int32Input(&m, k); m.Return(m.AddNode(kOps[i], a, b)); @@ -384,7 +380,7 @@ static Node* Int64Input(RawMachineAssemblerTester<int64_t>* m, int index) { case 6: return m->Int64Constant(0x0123456789abcdefLL); case 7: - return m->Load(kMachInt64, m->PointerConstant(NULL)); + return m->Load(MachineType::Int64(), m->PointerConstant(NULL)); default: return NULL; } @@ -408,7 +404,8 @@ TEST(CodeGenInt64Binop) { for (size_t i = 0; i < arraysize(kOps); ++i) { for (int j = 0; j < 8; j++) { for (int k = 0; k < 8; k++) { - RawMachineAssemblerTester<int64_t> m(kMachInt64, kMachInt64); + RawMachineAssemblerTester<int64_t> m(MachineType::Int64(), + MachineType::Int64()); Node* a = Int64Input(&m, j); Node* b = Int64Input(&m, k); m.Return(m.AddNode(kOps[i], a, b)); @@ -419,6 +416,190 @@ TEST(CodeGenInt64Binop) { } +TEST(RunInt64AddWithOverflowP) { + int64_t actual_val = -1; + RawMachineAssemblerTester<int32_t> m; + Int64BinopTester bt(&m); + Node* add = m.Int64AddWithOverflow(bt.param0, bt.param1); + Node* val = m.Projection(0, add); + Node* ovf = m.Projection(1, add); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); + bt.AddReturn(ovf); + FOR_INT64_INPUTS(i) { + FOR_INT64_INPUTS(j) { + int64_t expected_val; + int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val); + CHECK_EQ(expected_ovf, bt.call(*i, *j)); + CHECK_EQ(expected_val, actual_val); + } + } +} + + +TEST(RunInt64AddWithOverflowImm) { + int64_t actual_val = -1, expected_val = 0; + FOR_INT64_INPUTS(i) { + { + RawMachineAssemblerTester<int32_t> m(MachineType::Int64()); + Node* add = m.Int64AddWithOverflow(m.Int64Constant(*i), m.Parameter(0)); + Node* val = m.Projection(0, add); + Node* ovf = m.Projection(1, add); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); + m.Return(ovf); + FOR_INT64_INPUTS(j) { + int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val); + CHECK_EQ(expected_ovf, m.Call(*j)); + CHECK_EQ(expected_val, actual_val); + } + } + { + RawMachineAssemblerTester<int32_t> m(MachineType::Int64()); + Node* add = m.Int64AddWithOverflow(m.Parameter(0), m.Int64Constant(*i)); + Node* val = m.Projection(0, add); + Node* ovf = m.Projection(1, add); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); + m.Return(ovf); + FOR_INT64_INPUTS(j) { + int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val); + CHECK_EQ(expected_ovf, m.Call(*j)); + CHECK_EQ(expected_val, actual_val); + } + } + FOR_INT64_INPUTS(j) { + RawMachineAssemblerTester<int32_t> m; + Node* add = + m.Int64AddWithOverflow(m.Int64Constant(*i), m.Int64Constant(*j)); + Node* val = m.Projection(0, add); + Node* ovf = m.Projection(1, add); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); + m.Return(ovf); + int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val); + CHECK_EQ(expected_ovf, m.Call()); + CHECK_EQ(expected_val, actual_val); + } + } +} + + +TEST(RunInt64AddWithOverflowInBranchP) { + int constant = 911777; + RawMachineLabel blocka, blockb; + RawMachineAssemblerTester<int32_t> m; + Int64BinopTester bt(&m); + Node* add = m.Int64AddWithOverflow(bt.param0, bt.param1); + Node* ovf = m.Projection(1, add); + m.Branch(ovf, &blocka, &blockb); + m.Bind(&blocka); + bt.AddReturn(m.Int64Constant(constant)); + m.Bind(&blockb); + Node* val = m.Projection(0, add); + Node* truncated = m.TruncateInt64ToInt32(val); + bt.AddReturn(truncated); + FOR_INT64_INPUTS(i) { + FOR_INT64_INPUTS(j) { + int32_t expected = constant; + int64_t result; + if (!bits::SignedAddOverflow64(*i, *j, &result)) { + expected = static_cast<int32_t>(result); + } + CHECK_EQ(expected, bt.call(*i, *j)); + } + } +} + + +TEST(RunInt64SubWithOverflowP) { + int64_t actual_val = -1; + RawMachineAssemblerTester<int32_t> m; + Int64BinopTester bt(&m); + Node* add = m.Int64SubWithOverflow(bt.param0, bt.param1); + Node* val = m.Projection(0, add); + Node* ovf = m.Projection(1, add); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); + bt.AddReturn(ovf); + FOR_INT64_INPUTS(i) { + FOR_INT64_INPUTS(j) { + int64_t expected_val; + int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val); + CHECK_EQ(expected_ovf, bt.call(*i, *j)); + CHECK_EQ(expected_val, actual_val); + } + } +} + + +TEST(RunInt64SubWithOverflowImm) { + int64_t actual_val = -1, expected_val = 0; + FOR_INT64_INPUTS(i) { + { + RawMachineAssemblerTester<int32_t> m(MachineType::Int64()); + Node* add = m.Int64SubWithOverflow(m.Int64Constant(*i), m.Parameter(0)); + Node* val = m.Projection(0, add); + Node* ovf = m.Projection(1, add); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); + m.Return(ovf); + FOR_INT64_INPUTS(j) { + int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val); + CHECK_EQ(expected_ovf, m.Call(*j)); + CHECK_EQ(expected_val, actual_val); + } + } + { + RawMachineAssemblerTester<int32_t> m(MachineType::Int64()); + Node* add = m.Int64SubWithOverflow(m.Parameter(0), m.Int64Constant(*i)); + Node* val = m.Projection(0, add); + Node* ovf = m.Projection(1, add); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); + m.Return(ovf); + FOR_INT64_INPUTS(j) { + int expected_ovf = bits::SignedSubOverflow64(*j, *i, &expected_val); + CHECK_EQ(expected_ovf, m.Call(*j)); + CHECK_EQ(expected_val, actual_val); + } + } + FOR_INT64_INPUTS(j) { + RawMachineAssemblerTester<int32_t> m; + Node* add = + m.Int64SubWithOverflow(m.Int64Constant(*i), m.Int64Constant(*j)); + Node* val = m.Projection(0, add); + Node* ovf = m.Projection(1, add); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); + m.Return(ovf); + int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val); + CHECK_EQ(expected_ovf, m.Call()); + CHECK_EQ(expected_val, actual_val); + } + } +} + + +TEST(RunInt64SubWithOverflowInBranchP) { + int constant = 911999; + RawMachineLabel blocka, blockb; + RawMachineAssemblerTester<int32_t> m; + Int64BinopTester bt(&m); + Node* sub = m.Int64SubWithOverflow(bt.param0, bt.param1); + Node* ovf = m.Projection(1, sub); + m.Branch(ovf, &blocka, &blockb); + m.Bind(&blocka); + bt.AddReturn(m.Int64Constant(constant)); + m.Bind(&blockb); + Node* val = m.Projection(0, sub); + Node* truncated = m.TruncateInt64ToInt32(val); + bt.AddReturn(truncated); + FOR_INT64_INPUTS(i) { + FOR_INT64_INPUTS(j) { + int32_t expected = constant; + int64_t result; + if (!bits::SignedSubOverflow64(*i, *j, &result)) { + expected = static_cast<int32_t>(result); + } + CHECK_EQ(expected, static_cast<int32_t>(bt.call(*i, *j))); + } + } +} + + // TODO(titzer): add tests that run 64-bit integer operations. #endif // V8_TARGET_ARCH_64_BIT @@ -427,7 +608,7 @@ TEST(RunGoto) { RawMachineAssemblerTester<int32_t> m; int constant = 99999; - MLabel next; + RawMachineLabel next; m.Goto(&next); m.Bind(&next); m.Return(m.Int32Constant(constant)); @@ -440,7 +621,7 @@ TEST(RunGotoMultiple) { RawMachineAssemblerTester<int32_t> m; int constant = 9999977; - MLabel labels[10]; + RawMachineLabel labels[10]; for (size_t i = 0; i < arraysize(labels); i++) { m.Goto(&labels[i]); m.Bind(&labels[i]); @@ -455,7 +636,7 @@ TEST(RunBranch) { RawMachineAssemblerTester<int32_t> m; int constant = 999777; - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch(m.Int32Constant(0), &blocka, &blockb); m.Bind(&blocka); m.Return(m.Int32Constant(0 - constant)); @@ -471,7 +652,7 @@ TEST(RunDiamond2) { int constant = 995666; - MLabel blocka, blockb, end; + RawMachineLabel blocka, blockb, end; m.Branch(m.Int32Constant(0), &blocka, &blockb); m.Bind(&blocka); m.Goto(&end); @@ -488,7 +669,7 @@ TEST(RunLoop) { RawMachineAssemblerTester<int32_t> m; int constant = 999555; - MLabel header, body, exit; + RawMachineLabel header, body, exit; m.Goto(&header); m.Bind(&header); m.Branch(m.Int32Constant(0), &body, &exit); @@ -503,9 +684,9 @@ TEST(RunLoop) { template <typename R> static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node, - MachineType type, Node* true_node, + MachineRepresentation rep, Node* true_node, Node* false_node) { - MLabel blocka, blockb, end; + RawMachineLabel blocka, blockb, end; m->Branch(cond_node, &blocka, &blockb); m->Bind(&blocka); m->Goto(&end); @@ -513,51 +694,55 @@ static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node, m->Goto(&end); m->Bind(&end); - Node* phi = m->Phi(type, true_node, false_node); + Node* phi = m->Phi(rep, true_node, false_node); m->Return(phi); } TEST(RunDiamondPhiConst) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); int false_val = 0xFF666; int true_val = 0x00DDD; Node* true_node = m.Int32Constant(true_val); Node* false_node = m.Int32Constant(false_val); - BuildDiamondPhi(&m, m.Parameter(0), kMachInt32, true_node, false_node); + BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kWord32, true_node, + false_node); CHECK_EQ(false_val, m.Call(0)); CHECK_EQ(true_val, m.Call(1)); } TEST(RunDiamondPhiNumber) { - RawMachineAssemblerTester<Object*> m(kMachInt32); + RawMachineAssemblerTester<Object*> m(MachineType::Int32()); double false_val = -11.1; double true_val = 200.1; Node* true_node = m.NumberConstant(true_val); Node* false_node = m.NumberConstant(false_val); - BuildDiamondPhi(&m, m.Parameter(0), kMachAnyTagged, true_node, false_node); + BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kTagged, true_node, + false_node); m.CheckNumber(false_val, m.Call(0)); m.CheckNumber(true_val, m.Call(1)); } TEST(RunDiamondPhiString) { - RawMachineAssemblerTester<Object*> m(kMachInt32); + RawMachineAssemblerTester<Object*> m(MachineType::Int32()); const char* false_val = "false"; const char* true_val = "true"; Node* true_node = m.StringConstant(true_val); Node* false_node = m.StringConstant(false_val); - BuildDiamondPhi(&m, m.Parameter(0), kMachAnyTagged, true_node, false_node); + BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kTagged, true_node, + false_node); m.CheckString(false_val, m.Call(0)); m.CheckString(true_val, m.Call(1)); } TEST(RunDiamondPhiParam) { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); - BuildDiamondPhi(&m, m.Parameter(0), kMachInt32, m.Parameter(1), - m.Parameter(2)); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); + BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kWord32, + m.Parameter(1), m.Parameter(2)); int32_t c1 = 0x260cb75a; int32_t c2 = 0xcd3e9c8b; int result = m.Call(0, c1, c2); @@ -577,11 +762,11 @@ TEST(RunLoopPhiConst) { Node* false_node = m.Int32Constant(false_val); // x = false_val; while(false) { x = true_val; } return x; - MLabel body, header, end; + RawMachineLabel body, header, end; m.Goto(&header); m.Bind(&header); - Node* phi = m.Phi(kMachInt32, false_node, true_node); + Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, true_node); m.Branch(cond_node, &body, &end); m.Bind(&body); m.Goto(&header); @@ -593,15 +778,18 @@ TEST(RunLoopPhiConst) { TEST(RunLoopPhiParam) { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); - MLabel blocka, blockb, end; + RawMachineLabel blocka, blockb, end; m.Goto(&blocka); m.Bind(&blocka); - Node* phi = m.Phi(kMachInt32, m.Parameter(1), m.Parameter(2)); - Node* cond = m.Phi(kMachInt32, m.Parameter(0), m.Int32Constant(0)); + Node* phi = + m.Phi(MachineRepresentation::kWord32, m.Parameter(1), m.Parameter(2)); + Node* cond = + m.Phi(MachineRepresentation::kWord32, m.Parameter(0), m.Int32Constant(0)); m.Branch(cond, &blockb, &end); m.Bind(&blockb); @@ -625,13 +813,13 @@ TEST(RunLoopPhiInduction) { int false_val = 0x10777; // x = false_val; while(false) { x++; } return x; - MLabel header, body, end; + RawMachineLabel header, body, end; Node* false_node = m.Int32Constant(false_val); m.Goto(&header); m.Bind(&header); - Node* phi = m.Phi(kMachInt32, false_node, false_node); + Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, false_node); m.Branch(m.Int32Constant(0), &body, &end); m.Bind(&body); @@ -651,13 +839,13 @@ TEST(RunLoopIncrement) { Int32BinopTester bt(&m); // x = 0; while(x ^ param) { x++; } return x; - MLabel header, body, end; + RawMachineLabel header, body, end; Node* zero = m.Int32Constant(0); m.Goto(&header); m.Bind(&header); - Node* phi = m.Phi(kMachInt32, zero, zero); + Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero); m.Branch(m.WordXor(phi, bt.param0), &body, &end); m.Bind(&body); @@ -678,13 +866,13 @@ TEST(RunLoopIncrement2) { Int32BinopTester bt(&m); // x = 0; while(x < param) { x++; } return x; - MLabel header, body, end; + RawMachineLabel header, body, end; Node* zero = m.Int32Constant(0); m.Goto(&header); m.Bind(&header); - Node* phi = m.Phi(kMachInt32, zero, zero); + Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero); m.Branch(m.Int32LessThan(phi, bt.param0), &body, &end); m.Bind(&body); @@ -706,13 +894,13 @@ TEST(RunLoopIncrement3) { Int32BinopTester bt(&m); // x = 0; while(x < param) { x++; } return x; - MLabel header, body, end; + RawMachineLabel header, body, end; Node* zero = m.Int32Constant(0); m.Goto(&header); m.Bind(&header); - Node* phi = m.Phi(kMachInt32, zero, zero); + Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero); m.Branch(m.Uint32LessThan(phi, bt.param0), &body, &end); m.Bind(&body); @@ -734,12 +922,13 @@ TEST(RunLoopDecrement) { Int32BinopTester bt(&m); // x = param; while(x) { x--; } return x; - MLabel header, body, end; + RawMachineLabel header, body, end; m.Goto(&header); m.Bind(&header); - Node* phi = m.Phi(kMachInt32, bt.param0, m.Int32Constant(0)); + Node* phi = + m.Phi(MachineRepresentation::kWord32, bt.param0, m.Int32Constant(0)); m.Branch(phi, &body, &end); m.Bind(&body); @@ -759,14 +948,14 @@ TEST(RunLoopIncrementFloat32) { RawMachineAssemblerTester<int32_t> m; // x = -3.0f; while(x < 10f) { x = x + 0.5f; } return (int) (double) x; - MLabel header, body, end; + RawMachineLabel header, body, end; Node* minus_3 = m.Float32Constant(-3.0f); Node* ten = m.Float32Constant(10.0f); m.Goto(&header); m.Bind(&header); - Node* phi = m.Phi(kMachFloat32, minus_3, ten); + Node* phi = m.Phi(MachineRepresentation::kFloat32, minus_3, ten); m.Branch(m.Float32LessThan(phi, ten), &body, &end); m.Bind(&body); @@ -784,14 +973,14 @@ TEST(RunLoopIncrementFloat64) { RawMachineAssemblerTester<int32_t> m; // x = -3.0; while(x < 10) { x = x + 0.5; } return (int) x; - MLabel header, body, end; + RawMachineLabel header, body, end; Node* minus_3 = m.Float64Constant(-3.0); Node* ten = m.Float64Constant(10.0); m.Goto(&header); m.Bind(&header); - Node* phi = m.Phi(kMachFloat64, minus_3, ten); + Node* phi = m.Phi(MachineRepresentation::kFloat64, minus_3, ten); m.Branch(m.Float64LessThan(phi, ten), &body, &end); m.Bind(&body); @@ -810,8 +999,8 @@ TEST(RunSwitch1) { int constant = 11223344; - MLabel block0, block1, def, end; - MLabel* case_labels[] = {&block0, &block1}; + RawMachineLabel block0, block1, def, end; + RawMachineLabel* case_labels[] = {&block0, &block1}; int32_t case_values[] = {0, 1}; m.Switch(m.Int32Constant(0), &def, case_values, case_labels, arraysize(case_labels)); @@ -829,10 +1018,10 @@ TEST(RunSwitch1) { TEST(RunSwitch2) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); - MLabel blocka, blockb, blockc; - MLabel* case_labels[] = {&blocka, &blockb}; + RawMachineLabel blocka, blockb, blockc; + RawMachineLabel* case_labels[] = {&blocka, &blockb}; int32_t case_values[] = {std::numeric_limits<int32_t>::min(), std::numeric_limits<int32_t>::max()}; m.Switch(m.Parameter(0), &blockc, case_values, case_labels, @@ -853,10 +1042,10 @@ TEST(RunSwitch2) { TEST(RunSwitch3) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); - MLabel blocka, blockb, blockc; - MLabel* case_labels[] = {&blocka, &blockb}; + RawMachineLabel blocka, blockb, blockc; + RawMachineLabel* case_labels[] = {&blocka, &blockb}; int32_t case_values[] = {std::numeric_limits<int32_t>::min() + 0, std::numeric_limits<int32_t>::min() + 1}; m.Switch(m.Parameter(0), &blockc, case_values, case_labels, @@ -877,20 +1066,21 @@ TEST(RunSwitch3) { TEST(RunSwitch4) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); const size_t kNumCases = 512; const size_t kNumValues = kNumCases + 1; int32_t values[kNumValues]; m.main_isolate()->random_number_generator()->NextBytes(values, sizeof(values)); - MLabel end, def; + RawMachineLabel end, def; int32_t case_values[kNumCases]; - MLabel* case_labels[kNumCases]; + RawMachineLabel* case_labels[kNumCases]; Node* results[kNumValues]; for (size_t i = 0; i < kNumCases; ++i) { case_values[i] = static_cast<int32_t>(i); - case_labels[i] = new (m.main_zone()->New(sizeof(MLabel))) MLabel; + case_labels[i] = + new (m.main_zone()->New(sizeof(RawMachineLabel))) RawMachineLabel; } m.Switch(m.Parameter(0), &def, case_values, case_labels, arraysize(case_labels)); @@ -905,7 +1095,8 @@ TEST(RunSwitch4) { m.Bind(&end); const int num_results = static_cast<int>(arraysize(results)); Node* phi = - m.AddNode(m.common()->Phi(kMachInt32, num_results), num_results, results); + m.AddNode(m.common()->Phi(MachineRepresentation::kWord32, num_results), + num_results, results); m.Return(phi); for (size_t i = 0; i < kNumValues; ++i) { @@ -918,7 +1109,7 @@ TEST(RunLoadInt32) { RawMachineAssemblerTester<int32_t> m; int32_t p1 = 0; // loads directly from this location. - m.Return(m.LoadFromPointer(&p1, kMachInt32)); + m.Return(m.LoadFromPointer(&p1, MachineType::Int32())); FOR_INT32_INPUTS(i) { p1 = *i; @@ -938,7 +1129,7 @@ TEST(RunLoadInt32Offset) { int32_t offset = offsets[i]; byte* pointer = reinterpret_cast<byte*>(&p1) - offset; // generate load [#base + #index] - m.Return(m.LoadFromPointer(pointer, kMachInt32, offset)); + m.Return(m.LoadFromPointer(pointer, MachineType::Int32(), offset)); FOR_INT32_INPUTS(j) { p1 = *j; @@ -959,10 +1150,10 @@ TEST(RunLoadStoreFloat32Offset) { byte* from = reinterpret_cast<byte*>(&p1) - offset; byte* to = reinterpret_cast<byte*>(&p2) - offset; // generate load [#base + #index] - Node* load = - m.Load(kMachFloat32, m.PointerConstant(from), m.IntPtrConstant(offset)); - m.Store(kMachFloat32, m.PointerConstant(to), m.IntPtrConstant(offset), load, - kNoWriteBarrier); + Node* load = m.Load(MachineType::Float32(), m.PointerConstant(from), + m.IntPtrConstant(offset)); + m.Store(MachineRepresentation::kFloat32, m.PointerConstant(to), + m.IntPtrConstant(offset), load, kNoWriteBarrier); m.Return(m.Int32Constant(magic)); FOR_FLOAT32_INPUTS(j) { @@ -986,10 +1177,10 @@ TEST(RunLoadStoreFloat64Offset) { byte* from = reinterpret_cast<byte*>(&p1) - offset; byte* to = reinterpret_cast<byte*>(&p2) - offset; // generate load [#base + #index] - Node* load = - m.Load(kMachFloat64, m.PointerConstant(from), m.IntPtrConstant(offset)); - m.Store(kMachFloat64, m.PointerConstant(to), m.IntPtrConstant(offset), load, - kNoWriteBarrier); + Node* load = m.Load(MachineType::Float64(), m.PointerConstant(from), + m.IntPtrConstant(offset)); + m.Store(MachineRepresentation::kFloat64, m.PointerConstant(to), + m.IntPtrConstant(offset), load, kNoWriteBarrier); m.Return(m.Int32Constant(magic)); FOR_FLOAT64_INPUTS(j) { @@ -1020,7 +1211,8 @@ TEST(RunInt32AddP) { TEST(RunInt32AddAndWord32EqualP) { { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); m.Return(m.Int32Add(m.Parameter(0), m.Word32Equal(m.Parameter(1), m.Parameter(2)))); FOR_INT32_INPUTS(i) { @@ -1035,7 +1227,8 @@ TEST(RunInt32AddAndWord32EqualP) { } } { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); m.Return(m.Int32Add(m.Word32Equal(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); FOR_INT32_INPUTS(i) { @@ -1055,7 +1248,8 @@ TEST(RunInt32AddAndWord32EqualP) { TEST(RunInt32AddAndWord32EqualImm) { { FOR_INT32_INPUTS(i) { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); m.Return(m.Int32Add(m.Int32Constant(*i), m.Word32Equal(m.Parameter(0), m.Parameter(1)))); FOR_INT32_INPUTS(j) { @@ -1070,7 +1264,8 @@ TEST(RunInt32AddAndWord32EqualImm) { } { FOR_INT32_INPUTS(i) { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); m.Return(m.Int32Add(m.Word32Equal(m.Int32Constant(*i), m.Parameter(0)), m.Parameter(1))); FOR_INT32_INPUTS(j) { @@ -1088,7 +1283,8 @@ TEST(RunInt32AddAndWord32EqualImm) { TEST(RunInt32AddAndWord32NotEqualP) { { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); m.Return(m.Int32Add(m.Parameter(0), m.Word32NotEqual(m.Parameter(1), m.Parameter(2)))); FOR_INT32_INPUTS(i) { @@ -1103,7 +1299,8 @@ TEST(RunInt32AddAndWord32NotEqualP) { } } { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); m.Return(m.Int32Add(m.Word32NotEqual(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); FOR_INT32_INPUTS(i) { @@ -1123,7 +1320,8 @@ TEST(RunInt32AddAndWord32NotEqualP) { TEST(RunInt32AddAndWord32NotEqualImm) { { FOR_INT32_INPUTS(i) { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); m.Return(m.Int32Add(m.Int32Constant(*i), m.Word32NotEqual(m.Parameter(0), m.Parameter(1)))); FOR_INT32_INPUTS(j) { @@ -1138,7 +1336,8 @@ TEST(RunInt32AddAndWord32NotEqualImm) { } { FOR_INT32_INPUTS(i) { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); m.Return(m.Int32Add(m.Word32NotEqual(m.Int32Constant(*i), m.Parameter(0)), m.Parameter(1))); FOR_INT32_INPUTS(j) { @@ -1156,7 +1355,8 @@ TEST(RunInt32AddAndWord32NotEqualImm) { TEST(RunInt32AddAndWord32SarP) { { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); m.Return(m.Int32Add(m.Parameter(0), m.Word32Sar(m.Parameter(1), m.Parameter(2)))); FOR_UINT32_INPUTS(i) { @@ -1170,7 +1370,8 @@ TEST(RunInt32AddAndWord32SarP) { } } { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32()); m.Return(m.Int32Add(m.Word32Sar(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); FOR_INT32_INPUTS(i) { @@ -1188,7 +1389,8 @@ TEST(RunInt32AddAndWord32SarP) { TEST(RunInt32AddAndWord32ShlP) { { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); m.Return(m.Int32Add(m.Parameter(0), m.Word32Shl(m.Parameter(1), m.Parameter(2)))); FOR_UINT32_INPUTS(i) { @@ -1202,7 +1404,8 @@ TEST(RunInt32AddAndWord32ShlP) { } } { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32()); m.Return(m.Int32Add(m.Word32Shl(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); FOR_INT32_INPUTS(i) { @@ -1220,7 +1423,8 @@ TEST(RunInt32AddAndWord32ShlP) { TEST(RunInt32AddAndWord32ShrP) { { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); m.Return(m.Int32Add(m.Parameter(0), m.Word32Shr(m.Parameter(1), m.Parameter(2)))); FOR_UINT32_INPUTS(i) { @@ -1234,7 +1438,8 @@ TEST(RunInt32AddAndWord32ShrP) { } } { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); m.Return(m.Int32Add(m.Word32Shr(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); FOR_UINT32_INPUTS(i) { @@ -1255,7 +1460,7 @@ TEST(RunInt32AddInBranch) { { RawMachineAssemblerTester<int32_t> m; Int32BinopTester bt(&m); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch( m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)), &blocka, &blockb); @@ -1273,7 +1478,7 @@ TEST(RunInt32AddInBranch) { { RawMachineAssemblerTester<int32_t> m; Int32BinopTester bt(&m); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch( m.Word32NotEqual(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)), &blocka, &blockb); @@ -1290,8 +1495,8 @@ TEST(RunInt32AddInBranch) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); - MLabel blocka, blockb; + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); + RawMachineLabel blocka, blockb; m.Branch(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0)), &blocka, &blockb); @@ -1307,8 +1512,8 @@ TEST(RunInt32AddInBranch) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); - MLabel blocka, blockb; + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); + RawMachineLabel blocka, blockb; m.Branch(m.Word32NotEqual(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0)), &blocka, &blockb); @@ -1328,9 +1533,9 @@ TEST(RunInt32AddInBranch) { m.machine()->Word32Shl(), m.machine()->Word32Shr()}; for (size_t n = 0; n < arraysize(shops); n++) { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, - kMachUint32); - MLabel blocka, blockb; + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); + RawMachineLabel blocka, blockb; m.Branch(m.Word32Equal(m.Int32Add(m.Parameter(0), m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))), @@ -1394,7 +1599,7 @@ TEST(RunInt32AddInComparison) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0))); FOR_UINT32_INPUTS(j) { @@ -1405,7 +1610,7 @@ TEST(RunInt32AddInComparison) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Equal(m.Int32Add(m.Parameter(0), m.Int32Constant(*i)), m.Int32Constant(0))); FOR_UINT32_INPUTS(j) { @@ -1420,8 +1625,8 @@ TEST(RunInt32AddInComparison) { m.machine()->Word32Shl(), m.machine()->Word32Shr()}; for (size_t n = 0; n < arraysize(shops); n++) { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, - kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); m.Return(m.Word32Equal( m.Int32Add(m.Parameter(0), m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))), @@ -1471,7 +1676,7 @@ TEST(RunInt32SubP) { TEST(RunInt32SubImm) { { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0))); FOR_UINT32_INPUTS(j) { uint32_t expected = *i - *j; @@ -1481,7 +1686,7 @@ TEST(RunInt32SubImm) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i))); FOR_UINT32_INPUTS(j) { uint32_t expected = *j - *i; @@ -1494,7 +1699,8 @@ TEST(RunInt32SubImm) { TEST(RunInt32SubAndWord32SarP) { { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); m.Return(m.Int32Sub(m.Parameter(0), m.Word32Sar(m.Parameter(1), m.Parameter(2)))); FOR_UINT32_INPUTS(i) { @@ -1507,7 +1713,8 @@ TEST(RunInt32SubAndWord32SarP) { } } { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32()); m.Return(m.Int32Sub(m.Word32Sar(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); FOR_INT32_INPUTS(i) { @@ -1524,7 +1731,8 @@ TEST(RunInt32SubAndWord32SarP) { TEST(RunInt32SubAndWord32ShlP) { { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); m.Return(m.Int32Sub(m.Parameter(0), m.Word32Shl(m.Parameter(1), m.Parameter(2)))); FOR_UINT32_INPUTS(i) { @@ -1537,7 +1745,8 @@ TEST(RunInt32SubAndWord32ShlP) { } } { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32()); m.Return(m.Int32Sub(m.Word32Shl(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); FOR_INT32_INPUTS(i) { @@ -1555,8 +1764,8 @@ TEST(RunInt32SubAndWord32ShlP) { TEST(RunInt32SubAndWord32ShrP) { { - RawMachineAssemblerTester<uint32_t> m(kMachUint32, kMachUint32, - kMachUint32); + RawMachineAssemblerTester<uint32_t> m( + MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); m.Return(m.Int32Sub(m.Parameter(0), m.Word32Shr(m.Parameter(1), m.Parameter(2)))); FOR_UINT32_INPUTS(i) { @@ -1570,8 +1779,8 @@ TEST(RunInt32SubAndWord32ShrP) { } } { - RawMachineAssemblerTester<uint32_t> m(kMachUint32, kMachUint32, - kMachUint32); + RawMachineAssemblerTester<uint32_t> m( + MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); m.Return(m.Int32Sub(m.Word32Shr(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); FOR_UINT32_INPUTS(i) { @@ -1592,7 +1801,7 @@ TEST(RunInt32SubInBranch) { { RawMachineAssemblerTester<int32_t> m; Int32BinopTester bt(&m); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch( m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)), &blocka, &blockb); @@ -1610,7 +1819,7 @@ TEST(RunInt32SubInBranch) { { RawMachineAssemblerTester<int32_t> m; Int32BinopTester bt(&m); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch( m.Word32NotEqual(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)), &blocka, &blockb); @@ -1627,8 +1836,8 @@ TEST(RunInt32SubInBranch) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); - MLabel blocka, blockb; + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); + RawMachineLabel blocka, blockb; m.Branch(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0)), &blocka, &blockb); @@ -1644,8 +1853,8 @@ TEST(RunInt32SubInBranch) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<int32_t> m(kMachUint32); - MLabel blocka, blockb; + RawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); + RawMachineLabel blocka, blockb; m.Branch(m.Word32NotEqual(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0)), &blocka, &blockb); @@ -1665,9 +1874,9 @@ TEST(RunInt32SubInBranch) { m.machine()->Word32Shl(), m.machine()->Word32Shr()}; for (size_t n = 0; n < arraysize(shops); n++) { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, - kMachUint32); - MLabel blocka, blockb; + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); + RawMachineLabel blocka, blockb; m.Branch(m.Word32Equal(m.Int32Sub(m.Parameter(0), m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))), @@ -1731,7 +1940,7 @@ TEST(RunInt32SubInComparison) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0))); FOR_UINT32_INPUTS(j) { @@ -1742,7 +1951,7 @@ TEST(RunInt32SubInComparison) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Equal(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)), m.Int32Constant(0))); FOR_UINT32_INPUTS(j) { @@ -1757,8 +1966,8 @@ TEST(RunInt32SubInComparison) { m.machine()->Word32Shl(), m.machine()->Word32Shr()}; for (size_t n = 0; n < arraysize(shops); n++) { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, - kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); m.Return(m.Word32Equal( m.Int32Sub(m.Parameter(0), m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))), @@ -1833,7 +2042,7 @@ TEST(RunInt32MulHighP) { TEST(RunInt32MulImm) { { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Int32Mul(m.Int32Constant(*i), m.Parameter(0))); FOR_UINT32_INPUTS(j) { uint32_t expected = *i * *j; @@ -1843,7 +2052,7 @@ TEST(RunInt32MulImm) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant(*i))); FOR_UINT32_INPUTS(j) { uint32_t expected = *j * *i; @@ -1858,7 +2067,7 @@ TEST(RunInt32MulAndInt32AddP) { { FOR_INT32_INPUTS(i) { FOR_INT32_INPUTS(j) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); int32_t p0 = *i; int32_t p1 = *j; m.Return(m.Int32Add(m.Int32Constant(p0), @@ -1872,7 +2081,8 @@ TEST(RunInt32MulAndInt32AddP) { } } { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); m.Return( m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2)))); FOR_INT32_INPUTS(i) { @@ -1888,7 +2098,8 @@ TEST(RunInt32MulAndInt32AddP) { } } { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); m.Return( m.Int32Add(m.Int32Mul(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); FOR_INT32_INPUTS(i) { @@ -1924,7 +2135,8 @@ TEST(RunInt32MulAndInt32AddP) { TEST(RunInt32MulAndInt32SubP) { { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Int32(), MachineType::Int32()); m.Return( m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2)))); FOR_UINT32_INPUTS(i) { @@ -2234,7 +2446,7 @@ TEST(RunWord32AndAndWord32SarP) { TEST(RunWord32AndImm) { { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32And(m.Int32Constant(*i), m.Parameter(0))); FOR_UINT32_INPUTS(j) { uint32_t expected = *i & *j; @@ -2244,7 +2456,7 @@ TEST(RunWord32AndImm) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32And(m.Int32Constant(*i), m.Word32Not(m.Parameter(0)))); FOR_UINT32_INPUTS(j) { uint32_t expected = *i & ~(*j); @@ -2260,7 +2472,7 @@ TEST(RunWord32AndInBranch) { { RawMachineAssemblerTester<int32_t> m; Int32BinopTester bt(&m); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch( m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)), &blocka, &blockb); @@ -2278,7 +2490,7 @@ TEST(RunWord32AndInBranch) { { RawMachineAssemblerTester<int32_t> m; Int32BinopTester bt(&m); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch( m.Word32NotEqual(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)), &blocka, &blockb); @@ -2295,8 +2507,8 @@ TEST(RunWord32AndInBranch) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<int32_t> m(kMachUint32); - MLabel blocka, blockb; + RawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); + RawMachineLabel blocka, blockb; m.Branch(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0)), &blocka, &blockb); @@ -2312,8 +2524,8 @@ TEST(RunWord32AndInBranch) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<int32_t> m(kMachUint32); - MLabel blocka, blockb; + RawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); + RawMachineLabel blocka, blockb; m.Branch( m.Word32NotEqual(m.Word32And(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0)), @@ -2334,9 +2546,9 @@ TEST(RunWord32AndInBranch) { m.machine()->Word32Shl(), m.machine()->Word32Shr()}; for (size_t n = 0; n < arraysize(shops); n++) { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, - kMachUint32); - MLabel blocka, blockb; + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); + RawMachineLabel blocka, blockb; m.Branch(m.Word32Equal(m.Word32And(m.Parameter(0), m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))), @@ -2400,7 +2612,7 @@ TEST(RunWord32AndInComparison) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0))); FOR_UINT32_INPUTS(j) { @@ -2411,7 +2623,7 @@ TEST(RunWord32AndInComparison) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Equal(m.Word32And(m.Parameter(0), m.Int32Constant(*i)), m.Int32Constant(0))); FOR_UINT32_INPUTS(j) { @@ -2463,7 +2675,7 @@ TEST(RunWord32OrP) { TEST(RunWord32OrImm) { { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Or(m.Int32Constant(*i), m.Parameter(0))); FOR_UINT32_INPUTS(j) { uint32_t expected = *i | *j; @@ -2473,7 +2685,7 @@ TEST(RunWord32OrImm) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Or(m.Int32Constant(*i), m.Word32Not(m.Parameter(0)))); FOR_UINT32_INPUTS(j) { uint32_t expected = *i | ~(*j); @@ -2489,7 +2701,7 @@ TEST(RunWord32OrInBranch) { { RawMachineAssemblerTester<int32_t> m; Int32BinopTester bt(&m); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch( m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)), &blocka, &blockb); @@ -2507,7 +2719,7 @@ TEST(RunWord32OrInBranch) { { RawMachineAssemblerTester<int32_t> m; Int32BinopTester bt(&m); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch( m.Word32NotEqual(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)), &blocka, &blockb); @@ -2524,8 +2736,8 @@ TEST(RunWord32OrInBranch) { } { FOR_INT32_INPUTS(i) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); - MLabel blocka, blockb; + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); + RawMachineLabel blocka, blockb; m.Branch(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0)), &blocka, &blockb); @@ -2541,8 +2753,8 @@ TEST(RunWord32OrInBranch) { } { FOR_INT32_INPUTS(i) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); - MLabel blocka, blockb; + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); + RawMachineLabel blocka, blockb; m.Branch(m.Word32NotEqual(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0)), &blocka, &blockb); @@ -2562,9 +2774,9 @@ TEST(RunWord32OrInBranch) { m.machine()->Word32Shl(), m.machine()->Word32Shr()}; for (size_t n = 0; n < arraysize(shops); n++) { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, - kMachUint32); - MLabel blocka, blockb; + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); + RawMachineLabel blocka, blockb; m.Branch(m.Word32Equal(m.Word32Or(m.Parameter(0), m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))), @@ -2628,7 +2840,7 @@ TEST(RunWord32OrInComparison) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0))); FOR_UINT32_INPUTS(j) { @@ -2639,7 +2851,7 @@ TEST(RunWord32OrInComparison) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Equal(m.Word32Or(m.Parameter(0), m.Int32Constant(*i)), m.Int32Constant(0))); FOR_UINT32_INPUTS(j) { @@ -2654,7 +2866,7 @@ TEST(RunWord32OrInComparison) { TEST(RunWord32XorP) { { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0))); FOR_UINT32_INPUTS(j) { uint32_t expected = *i ^ *j; @@ -2697,7 +2909,7 @@ TEST(RunWord32XorP) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Xor(m.Int32Constant(*i), m.Word32Not(m.Parameter(0)))); FOR_UINT32_INPUTS(j) { uint32_t expected = *i ^ ~(*j); @@ -2713,7 +2925,7 @@ TEST(RunWord32XorInBranch) { { RawMachineAssemblerTester<int32_t> m; Uint32BinopTester bt(&m); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch( m.Word32Equal(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)), &blocka, &blockb); @@ -2731,7 +2943,7 @@ TEST(RunWord32XorInBranch) { { RawMachineAssemblerTester<int32_t> m; Uint32BinopTester bt(&m); - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; m.Branch( m.Word32NotEqual(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)), &blocka, &blockb); @@ -2748,8 +2960,8 @@ TEST(RunWord32XorInBranch) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); - MLabel blocka, blockb; + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); + RawMachineLabel blocka, blockb; m.Branch(m.Word32Equal(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0)), &blocka, &blockb); @@ -2765,8 +2977,8 @@ TEST(RunWord32XorInBranch) { } { FOR_UINT32_INPUTS(i) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); - MLabel blocka, blockb; + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); + RawMachineLabel blocka, blockb; m.Branch( m.Word32NotEqual(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)), m.Int32Constant(0)), @@ -2787,9 +2999,9 @@ TEST(RunWord32XorInBranch) { m.machine()->Word32Shl(), m.machine()->Word32Shr()}; for (size_t n = 0; n < arraysize(shops); n++) { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, - kMachUint32); - MLabel blocka, blockb; + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); + RawMachineLabel blocka, blockb; m.Branch(m.Word32Equal(m.Word32Xor(m.Parameter(0), m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))), @@ -2829,7 +3041,7 @@ TEST(RunWord32XorInBranch) { TEST(RunWord32ShlP) { { FOR_UINT32_SHIFTS(shift) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift))); FOR_UINT32_INPUTS(j) { uint32_t expected = *j << shift; @@ -2878,7 +3090,7 @@ TEST(RunWord32ShlInComparison) { } { FOR_UINT32_SHIFTS(shift) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return( m.Word32Equal(m.Int32Constant(0), m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)))); @@ -2890,7 +3102,7 @@ TEST(RunWord32ShlInComparison) { } { FOR_UINT32_SHIFTS(shift) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return( m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)), m.Int32Constant(0))); @@ -2906,7 +3118,7 @@ TEST(RunWord32ShlInComparison) { TEST(RunWord32ShrP) { { FOR_UINT32_SHIFTS(shift) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift))); FOR_UINT32_INPUTS(j) { uint32_t expected = *j >> shift; @@ -2956,7 +3168,7 @@ TEST(RunWord32ShrInComparison) { } { FOR_UINT32_SHIFTS(shift) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return( m.Word32Equal(m.Int32Constant(0), m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)))); @@ -2968,7 +3180,7 @@ TEST(RunWord32ShrInComparison) { } { FOR_UINT32_SHIFTS(shift) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return( m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)), m.Int32Constant(0))); @@ -2984,7 +3196,7 @@ TEST(RunWord32ShrInComparison) { TEST(RunWord32SarP) { { FOR_INT32_SHIFTS(shift) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); m.Return(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift))); FOR_INT32_INPUTS(j) { int32_t expected = *j >> shift; @@ -3034,7 +3246,7 @@ TEST(RunWord32SarInComparison) { } { FOR_INT32_SHIFTS(shift) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); m.Return( m.Word32Equal(m.Int32Constant(0), m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)))); @@ -3046,7 +3258,7 @@ TEST(RunWord32SarInComparison) { } { FOR_INT32_SHIFTS(shift) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); m.Return( m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)), m.Int32Constant(0))); @@ -3062,7 +3274,7 @@ TEST(RunWord32SarInComparison) { TEST(RunWord32RorP) { { FOR_UINT32_SHIFTS(shift) { - RawMachineAssemblerTester<int32_t> m(kMachUint32); + RawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); m.Return(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift))); FOR_UINT32_INPUTS(j) { int32_t expected = bits::RotateRight32(*j, shift); @@ -3111,7 +3323,7 @@ TEST(RunWord32RorInComparison) { } { FOR_UINT32_SHIFTS(shift) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return( m.Word32Equal(m.Int32Constant(0), m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)))); @@ -3123,7 +3335,7 @@ TEST(RunWord32RorInComparison) { } { FOR_UINT32_SHIFTS(shift) { - RawMachineAssemblerTester<uint32_t> m(kMachUint32); + RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); m.Return( m.Word32Equal(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)), m.Int32Constant(0))); @@ -3137,7 +3349,7 @@ TEST(RunWord32RorInComparison) { TEST(RunWord32NotP) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); m.Return(m.Word32Not(m.Parameter(0))); FOR_INT32_INPUTS(i) { int expected = ~(*i); @@ -3147,7 +3359,7 @@ TEST(RunWord32NotP) { TEST(RunInt32NegP) { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); m.Return(m.Int32Neg(m.Parameter(0))); FOR_INT32_INPUTS(i) { int expected = -*i; @@ -3158,7 +3370,8 @@ TEST(RunInt32NegP) { TEST(RunWord32EqualAndWord32SarP) { { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Int32(), MachineType::Uint32()); m.Return(m.Word32Equal(m.Parameter(0), m.Word32Sar(m.Parameter(1), m.Parameter(2)))); FOR_INT32_INPUTS(i) { @@ -3171,7 +3384,8 @@ TEST(RunWord32EqualAndWord32SarP) { } } { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachUint32, kMachInt32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Int32(), MachineType::Uint32(), MachineType::Int32()); m.Return(m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); FOR_INT32_INPUTS(i) { @@ -3188,7 +3402,8 @@ TEST(RunWord32EqualAndWord32SarP) { TEST(RunWord32EqualAndWord32ShlP) { { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); m.Return(m.Word32Equal(m.Parameter(0), m.Word32Shl(m.Parameter(1), m.Parameter(2)))); FOR_UINT32_INPUTS(i) { @@ -3201,7 +3416,8 @@ TEST(RunWord32EqualAndWord32ShlP) { } } { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); m.Return(m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); FOR_UINT32_INPUTS(i) { @@ -3218,7 +3434,8 @@ TEST(RunWord32EqualAndWord32ShlP) { TEST(RunWord32EqualAndWord32ShrP) { { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); m.Return(m.Word32Equal(m.Parameter(0), m.Word32Shr(m.Parameter(1), m.Parameter(2)))); FOR_UINT32_INPUTS(i) { @@ -3231,7 +3448,8 @@ TEST(RunWord32EqualAndWord32ShrP) { } } { - RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachUint32, kMachUint32); + RawMachineAssemblerTester<int32_t> m( + MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); m.Return(m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); FOR_UINT32_INPUTS(i) { @@ -3248,7 +3466,8 @@ TEST(RunWord32EqualAndWord32ShrP) { TEST(RunDeadNodes) { for (int i = 0; true; i++) { - RawMachineAssemblerTester<int32_t> m(i == 5 ? kMachInt32 : kMachNone); + RawMachineAssemblerTester<int32_t> m(i == 5 ? MachineType::Int32() + : MachineType::None()); int constant = 0x55 + i; switch (i) { case 0: @@ -3264,7 +3483,7 @@ TEST(RunDeadNodes) { m.PointerConstant(&constant); break; case 4: - m.LoadFromPointer(&constant, kMachInt32); + m.LoadFromPointer(&constant, MachineType::Int32()); break; case 5: m.Parameter(0); @@ -3299,7 +3518,8 @@ TEST(RunDeadInt32Binops) { m.machine()->Uint32LessThanOrEqual()}; for (size_t i = 0; i < arraysize(kOps); ++i) { - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); int32_t constant = static_cast<int32_t>(0x55555 + i); m.AddNode(kOps[i], m.Parameter(0), m.Parameter(1)); m.Return(m.Int32Constant(constant)); @@ -3337,16 +3557,16 @@ static void RunLoadImmIndex(MachineType rep) { TEST(RunLoadImmIndex) { - RunLoadImmIndex<int8_t>(kMachInt8); - RunLoadImmIndex<uint8_t>(kMachUint8); - RunLoadImmIndex<int16_t>(kMachInt16); - RunLoadImmIndex<uint16_t>(kMachUint16); - RunLoadImmIndex<int32_t>(kMachInt32); - RunLoadImmIndex<uint32_t>(kMachUint32); - RunLoadImmIndex<int32_t*>(kMachAnyTagged); + RunLoadImmIndex<int8_t>(MachineType::Int8()); + RunLoadImmIndex<uint8_t>(MachineType::Uint8()); + RunLoadImmIndex<int16_t>(MachineType::Int16()); + RunLoadImmIndex<uint16_t>(MachineType::Uint16()); + RunLoadImmIndex<int32_t>(MachineType::Int32()); + RunLoadImmIndex<uint32_t>(MachineType::Uint32()); + RunLoadImmIndex<int32_t*>(MachineType::AnyTagged()); // TODO(titzer): test kRepBit loads - // TODO(titzer): test kMachFloat64 loads + // TODO(titzer): test MachineType::Float64() loads // TODO(titzer): test various indexing modes. } @@ -3370,7 +3590,7 @@ static void RunLoadStore(MachineType rep) { Node* index0 = m.IntPtrConstant(x * sizeof(buffer[0])); Node* load = m.Load(rep, base, index0); Node* index1 = m.IntPtrConstant(y * sizeof(buffer[0])); - m.Store(rep, base, index1, load, kNoWriteBarrier); + m.Store(rep.representation(), base, index1, load, kNoWriteBarrier); m.Return(m.Int32Constant(OK)); CHECK(buffer[x] != buffer[y]); @@ -3381,20 +3601,21 @@ static void RunLoadStore(MachineType rep) { TEST(RunLoadStore) { - RunLoadStore<int8_t>(kMachInt8); - RunLoadStore<uint8_t>(kMachUint8); - RunLoadStore<int16_t>(kMachInt16); - RunLoadStore<uint16_t>(kMachUint16); - RunLoadStore<int32_t>(kMachInt32); - RunLoadStore<uint32_t>(kMachUint32); - RunLoadStore<void*>(kMachAnyTagged); - RunLoadStore<float>(kMachFloat32); - RunLoadStore<double>(kMachFloat64); + RunLoadStore<int8_t>(MachineType::Int8()); + RunLoadStore<uint8_t>(MachineType::Uint8()); + RunLoadStore<int16_t>(MachineType::Int16()); + RunLoadStore<uint16_t>(MachineType::Uint16()); + RunLoadStore<int32_t>(MachineType::Int32()); + RunLoadStore<uint32_t>(MachineType::Uint32()); + RunLoadStore<void*>(MachineType::AnyTagged()); + RunLoadStore<float>(MachineType::Float32()); + RunLoadStore<double>(MachineType::Float64()); } TEST(RunFloat32Add) { - BufferedRawMachineAssemblerTester<float> m(kMachFloat32, kMachFloat32); + BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(), + MachineType::Float32()); m.Return(m.Float32Add(m.Parameter(0), m.Parameter(1))); FOR_FLOAT32_INPUTS(i) { @@ -3407,7 +3628,8 @@ TEST(RunFloat32Add) { TEST(RunFloat32Sub) { - BufferedRawMachineAssemblerTester<float> m(kMachFloat32, kMachFloat32); + BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(), + MachineType::Float32()); m.Return(m.Float32Sub(m.Parameter(0), m.Parameter(1))); FOR_FLOAT32_INPUTS(i) { @@ -3420,7 +3642,8 @@ TEST(RunFloat32Sub) { TEST(RunFloat32Mul) { - BufferedRawMachineAssemblerTester<float> m(kMachFloat32, kMachFloat32); + BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(), + MachineType::Float32()); m.Return(m.Float32Mul(m.Parameter(0), m.Parameter(1))); FOR_FLOAT32_INPUTS(i) { @@ -3433,7 +3656,8 @@ TEST(RunFloat32Mul) { TEST(RunFloat32Div) { - BufferedRawMachineAssemblerTester<float> m(kMachFloat32, kMachFloat32); + BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(), + MachineType::Float32()); m.Return(m.Float32Div(m.Parameter(0), m.Parameter(1))); FOR_FLOAT32_INPUTS(i) { @@ -3446,27 +3670,36 @@ TEST(RunFloat32Div) { TEST(RunFloat64Add) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64, kMachFloat64); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), + MachineType::Float64()); m.Return(m.Float64Add(m.Parameter(0), m.Parameter(1))); FOR_FLOAT64_INPUTS(i) { - FOR_FLOAT64_INPUTS(j) { CheckDoubleEq(*i + *j, m.Call(*i, *j)); } + FOR_FLOAT64_INPUTS(j) { + volatile double expected = *i + *j; + CheckDoubleEq(expected, m.Call(*i, *j)); + } } } TEST(RunFloat64Sub) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64, kMachFloat64); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), + MachineType::Float64()); m.Return(m.Float64Sub(m.Parameter(0), m.Parameter(1))); FOR_FLOAT64_INPUTS(i) { - FOR_FLOAT64_INPUTS(j) { CheckDoubleEq(*i - *j, m.Call(*i, *j)); } + FOR_FLOAT64_INPUTS(j) { + volatile double expected = *i - *j; + CheckDoubleEq(expected, m.Call(*i, *j)); + } } } TEST(RunFloat64Mul) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64, kMachFloat64); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), + MachineType::Float64()); m.Return(m.Float64Mul(m.Parameter(0), m.Parameter(1))); FOR_FLOAT64_INPUTS(i) { @@ -3479,7 +3712,8 @@ TEST(RunFloat64Mul) { TEST(RunFloat64Div) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64, kMachFloat64); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), + MachineType::Float64()); m.Return(m.Float64Div(m.Parameter(0), m.Parameter(1))); FOR_FLOAT64_INPUTS(i) { @@ -3492,7 +3726,8 @@ TEST(RunFloat64Div) { TEST(RunFloat64Mod) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64, kMachFloat64); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), + MachineType::Float64()); m.Return(m.Float64Mod(m.Parameter(0), m.Parameter(1))); FOR_FLOAT64_INPUTS(i) { @@ -3646,7 +3881,7 @@ TEST(RunFloat32SubP) { TEST(RunFloat32SubImm1) { FOR_FLOAT32_INPUTS(i) { - BufferedRawMachineAssemblerTester<float> m(kMachFloat32); + BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); m.Return(m.Float32Sub(m.Float32Constant(*i), m.Parameter(0))); FOR_FLOAT32_INPUTS(j) { @@ -3659,7 +3894,7 @@ TEST(RunFloat32SubImm1) { TEST(RunFloat32SubImm2) { FOR_FLOAT32_INPUTS(i) { - BufferedRawMachineAssemblerTester<float> m(kMachFloat32); + BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); m.Return(m.Float32Sub(m.Parameter(0), m.Float32Constant(*i))); FOR_FLOAT32_INPUTS(j) { @@ -3672,7 +3907,7 @@ TEST(RunFloat32SubImm2) { TEST(RunFloat64SubImm1) { FOR_FLOAT64_INPUTS(i) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); m.Return(m.Float64Sub(m.Float64Constant(*i), m.Parameter(0))); FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*i - *j, m.Call(*j)); } @@ -3682,7 +3917,7 @@ TEST(RunFloat64SubImm1) { TEST(RunFloat64SubImm2) { FOR_FLOAT64_INPUTS(i) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); m.Return(m.Float64Sub(m.Parameter(0), m.Float64Constant(*i))); FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*j - *i, m.Call(*j)); } @@ -3736,8 +3971,8 @@ TEST(RunFloat64MulP) { TEST(RunFloat64MulAndFloat64Add1) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64, kMachFloat64, - kMachFloat64); + BufferedRawMachineAssemblerTester<double> m( + MachineType::Float64(), MachineType::Float64(), MachineType::Float64()); m.Return(m.Float64Add(m.Float64Mul(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); @@ -3752,8 +3987,8 @@ TEST(RunFloat64MulAndFloat64Add1) { TEST(RunFloat64MulAndFloat64Add2) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64, kMachFloat64, - kMachFloat64); + BufferedRawMachineAssemblerTester<double> m( + MachineType::Float64(), MachineType::Float64(), MachineType::Float64()); m.Return(m.Float64Add(m.Parameter(0), m.Float64Mul(m.Parameter(1), m.Parameter(2)))); @@ -3768,8 +4003,8 @@ TEST(RunFloat64MulAndFloat64Add2) { TEST(RunFloat64MulAndFloat64Sub1) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64, kMachFloat64, - kMachFloat64); + BufferedRawMachineAssemblerTester<double> m( + MachineType::Float64(), MachineType::Float64(), MachineType::Float64()); m.Return(m.Float64Sub(m.Float64Mul(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); @@ -3784,8 +4019,8 @@ TEST(RunFloat64MulAndFloat64Sub1) { TEST(RunFloat64MulAndFloat64Sub2) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64, kMachFloat64, - kMachFloat64); + BufferedRawMachineAssemblerTester<double> m( + MachineType::Float64(), MachineType::Float64(), MachineType::Float64()); m.Return(m.Float64Sub(m.Parameter(0), m.Float64Mul(m.Parameter(1), m.Parameter(2)))); @@ -3801,7 +4036,7 @@ TEST(RunFloat64MulAndFloat64Sub2) { TEST(RunFloat64MulImm1) { FOR_FLOAT64_INPUTS(i) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); m.Return(m.Float64Mul(m.Float64Constant(*i), m.Parameter(0))); FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*i * *j, m.Call(*j)); } @@ -3811,7 +4046,7 @@ TEST(RunFloat64MulImm1) { TEST(RunFloat64MulImm2) { FOR_FLOAT64_INPUTS(i) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); m.Return(m.Float64Mul(m.Parameter(0), m.Float64Constant(*i))); FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*j * *i, m.Call(*j)); } @@ -3874,7 +4109,7 @@ TEST(RunChangeInt32ToFloat64_A) { TEST(RunChangeInt32ToFloat64_B) { - BufferedRawMachineAssemblerTester<double> m(kMachInt32); + BufferedRawMachineAssemblerTester<double> m(MachineType::Int32()); m.Return(m.ChangeInt32ToFloat64(m.Parameter(0))); FOR_INT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); } @@ -3882,7 +4117,7 @@ TEST(RunChangeInt32ToFloat64_B) { TEST(RunChangeUint32ToFloat64) { - BufferedRawMachineAssemblerTester<double> m(kMachUint32); + BufferedRawMachineAssemblerTester<double> m(MachineType::Uint32()); m.Return(m.ChangeUint32ToFloat64(m.Parameter(0))); FOR_UINT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); } @@ -3898,7 +4133,7 @@ TEST(RunChangeFloat64ToInt32_A) { TEST(RunChangeFloat64ToInt32_B) { - BufferedRawMachineAssemblerTester<int32_t> m(kMachFloat64); + BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Float64()); m.Return(m.ChangeFloat64ToInt32(m.Parameter(0))); // Note we don't check fractional inputs, or inputs outside the range of @@ -3916,7 +4151,7 @@ TEST(RunChangeFloat64ToInt32_B) { TEST(RunChangeFloat64ToUint32) { - BufferedRawMachineAssemblerTester<uint32_t> m(kMachFloat64); + BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64()); m.Return(m.ChangeFloat64ToUint32(m.Parameter(0))); { @@ -3935,7 +4170,7 @@ TEST(RunChangeFloat64ToUint32) { TEST(RunTruncateFloat64ToFloat32) { - BufferedRawMachineAssemblerTester<float> m(kMachFloat64); + BufferedRawMachineAssemblerTester<float> m(MachineType::Float64()); m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0))); @@ -3967,11 +4202,11 @@ TEST(RunLoopPhiInduction2) { int false_val = 0x10777; // x = false_val; while(false) { x++; } return x; - MLabel header, body, end; + RawMachineLabel header, body, end; Node* false_node = m.Int32Constant(false_val); m.Goto(&header); m.Bind(&header); - Node* phi = m.Phi(kMachInt32, false_node, false_node); + Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, false_node); m.Branch(m.Int32Constant(0), &body, &end); m.Bind(&body); Node* add = m.Int32Add(phi, m.Int32Constant(1)); @@ -3991,7 +4226,7 @@ TEST(RunFloatDiamond) { float buffer = 0.1f; float constant = 99.99f; - MLabel blocka, blockb, end; + RawMachineLabel blocka, blockb, end; Node* k1 = m.Float32Constant(constant); Node* k2 = m.Float32Constant(0 - constant); m.Branch(m.Int32Constant(0), &blocka, &blockb); @@ -4000,9 +4235,9 @@ TEST(RunFloatDiamond) { m.Bind(&blockb); m.Goto(&end); m.Bind(&end); - Node* phi = m.Phi(kMachFloat32, k2, k1); - m.Store(kMachFloat32, m.PointerConstant(&buffer), m.IntPtrConstant(0), phi, - kNoWriteBarrier); + Node* phi = m.Phi(MachineRepresentation::kFloat32, k2, k1); + m.Store(MachineRepresentation::kFloat32, m.PointerConstant(&buffer), + m.IntPtrConstant(0), phi, kNoWriteBarrier); m.Return(m.Int32Constant(magic)); CHECK_EQ(magic, m.Call()); @@ -4017,7 +4252,7 @@ TEST(RunDoubleDiamond) { double buffer = 0.1; double constant = 99.99; - MLabel blocka, blockb, end; + RawMachineLabel blocka, blockb, end; Node* k1 = m.Float64Constant(constant); Node* k2 = m.Float64Constant(0 - constant); m.Branch(m.Int32Constant(0), &blocka, &blockb); @@ -4026,9 +4261,9 @@ TEST(RunDoubleDiamond) { m.Bind(&blockb); m.Goto(&end); m.Bind(&end); - Node* phi = m.Phi(kMachFloat64, k2, k1); - m.Store(kMachFloat64, m.PointerConstant(&buffer), m.Int32Constant(0), phi, - kNoWriteBarrier); + Node* phi = m.Phi(MachineRepresentation::kFloat64, k2, k1); + m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer), + m.Int32Constant(0), phi, kNoWriteBarrier); m.Return(m.Int32Constant(magic)); CHECK_EQ(magic, m.Call()); @@ -4044,7 +4279,7 @@ TEST(RunRefDiamond) { CcTest::i_isolate()->factory()->InternalizeUtf8String("A"); String* buffer; - MLabel blocka, blockb, end; + RawMachineLabel blocka, blockb, end; Node* k1 = m.StringConstant("A"); Node* k2 = m.StringConstant("B"); m.Branch(m.Int32Constant(0), &blocka, &blockb); @@ -4053,9 +4288,9 @@ TEST(RunRefDiamond) { m.Bind(&blockb); m.Goto(&end); m.Bind(&end); - Node* phi = m.Phi(kMachAnyTagged, k2, k1); - m.Store(kMachAnyTagged, m.PointerConstant(&buffer), m.Int32Constant(0), phi, - kNoWriteBarrier); + Node* phi = m.Phi(MachineRepresentation::kTagged, k2, k1); + m.Store(MachineRepresentation::kTagged, m.PointerConstant(&buffer), + m.Int32Constant(0), phi, kNoWriteBarrier); m.Return(m.Int32Constant(magic)); CHECK_EQ(magic, m.Call()); @@ -4073,7 +4308,7 @@ TEST(RunDoubleRefDiamond) { CcTest::i_isolate()->factory()->InternalizeUtf8String("AX"); String* rbuffer; - MLabel blocka, blockb, end; + RawMachineLabel blocka, blockb, end; Node* d1 = m.Float64Constant(dconstant); Node* d2 = m.Float64Constant(0 - dconstant); Node* r1 = m.StringConstant("AX"); @@ -4084,12 +4319,12 @@ TEST(RunDoubleRefDiamond) { m.Bind(&blockb); m.Goto(&end); m.Bind(&end); - Node* dphi = m.Phi(kMachFloat64, d2, d1); - Node* rphi = m.Phi(kMachAnyTagged, r2, r1); - m.Store(kMachFloat64, m.PointerConstant(&dbuffer), m.Int32Constant(0), dphi, - kNoWriteBarrier); - m.Store(kMachAnyTagged, m.PointerConstant(&rbuffer), m.Int32Constant(0), rphi, - kNoWriteBarrier); + Node* dphi = m.Phi(MachineRepresentation::kFloat64, d2, d1); + Node* rphi = m.Phi(MachineRepresentation::kTagged, r2, r1); + m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer), + m.Int32Constant(0), dphi, kNoWriteBarrier); + m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer), + m.Int32Constant(0), rphi, kNoWriteBarrier); m.Return(m.Int32Constant(magic)); CHECK_EQ(magic, m.Call()); @@ -4108,7 +4343,7 @@ TEST(RunDoubleRefDoubleDiamond) { CcTest::i_isolate()->factory()->InternalizeUtf8String("AD"); String* rbuffer; - MLabel blocka, blockb, mid, blockd, blocke, end; + RawMachineLabel blocka, blockb, mid, blockd, blocke, end; Node* d1 = m.Float64Constant(dconstant); Node* d2 = m.Float64Constant(0 - dconstant); Node* r1 = m.StringConstant("AD"); @@ -4119,8 +4354,8 @@ TEST(RunDoubleRefDoubleDiamond) { m.Bind(&blockb); m.Goto(&mid); m.Bind(&mid); - Node* dphi1 = m.Phi(kMachFloat64, d2, d1); - Node* rphi1 = m.Phi(kMachAnyTagged, r2, r1); + Node* dphi1 = m.Phi(MachineRepresentation::kFloat64, d2, d1); + Node* rphi1 = m.Phi(MachineRepresentation::kTagged, r2, r1); m.Branch(m.Int32Constant(0), &blockd, &blocke); m.Bind(&blockd); @@ -4128,13 +4363,13 @@ TEST(RunDoubleRefDoubleDiamond) { m.Bind(&blocke); m.Goto(&end); m.Bind(&end); - Node* dphi2 = m.Phi(kMachFloat64, d1, dphi1); - Node* rphi2 = m.Phi(kMachAnyTagged, r1, rphi1); + Node* dphi2 = m.Phi(MachineRepresentation::kFloat64, d1, dphi1); + Node* rphi2 = m.Phi(MachineRepresentation::kTagged, r1, rphi1); - m.Store(kMachFloat64, m.PointerConstant(&dbuffer), m.Int32Constant(0), dphi2, - kNoWriteBarrier); - m.Store(kMachAnyTagged, m.PointerConstant(&rbuffer), m.Int32Constant(0), - rphi2, kNoWriteBarrier); + m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer), + m.Int32Constant(0), dphi2, kNoWriteBarrier); + m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer), + m.Int32Constant(0), rphi2, kNoWriteBarrier); m.Return(m.Int32Constant(magic)); CHECK_EQ(magic, m.Call()); @@ -4145,7 +4380,7 @@ TEST(RunDoubleRefDoubleDiamond) { TEST(RunDoubleLoopPhi) { RawMachineAssemblerTester<int32_t> m; - MLabel header, body, end; + RawMachineLabel header, body, end; int magic = 99773; double buffer = 0.99; @@ -4156,14 +4391,14 @@ TEST(RunDoubleLoopPhi) { m.Goto(&header); m.Bind(&header); - Node* phi = m.Phi(kMachFloat64, dk, dk); + Node* phi = m.Phi(MachineRepresentation::kFloat64, dk, dk); phi->ReplaceInput(1, phi); m.Branch(zero, &body, &end); m.Bind(&body); m.Goto(&header); m.Bind(&end); - m.Store(kMachFloat64, m.PointerConstant(&buffer), m.Int32Constant(0), phi, - kNoWriteBarrier); + m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer), + m.Int32Constant(0), phi, kNoWriteBarrier); m.Return(m.Int32Constant(magic)); CHECK_EQ(magic, m.Call()); @@ -4177,13 +4412,13 @@ TEST(RunCountToTenAccRaw) { Node* ten = m.Int32Constant(10); Node* one = m.Int32Constant(1); - MLabel header, body, body_cont, end; + RawMachineLabel header, body, body_cont, end; m.Goto(&header); m.Bind(&header); - Node* i = m.Phi(kMachInt32, zero, zero); - Node* j = m.Phi(kMachInt32, zero, zero); + Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero); + Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero); m.Goto(&body); m.Bind(&body); @@ -4210,14 +4445,14 @@ TEST(RunCountToTenAccRaw2) { Node* ten = m.Int32Constant(10); Node* one = m.Int32Constant(1); - MLabel header, body, body_cont, end; + RawMachineLabel header, body, body_cont, end; m.Goto(&header); m.Bind(&header); - Node* i = m.Phi(kMachInt32, zero, zero); - Node* j = m.Phi(kMachInt32, zero, zero); - Node* k = m.Phi(kMachInt32, zero, zero); + Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero); + Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero); + Node* k = m.Phi(MachineRepresentation::kWord32, zero, zero); m.Goto(&body); m.Bind(&body); @@ -4244,14 +4479,22 @@ TEST(RunAddTree) { int32_t inputs[] = {11, 12, 13, 14, 15, 16, 17, 18}; Node* base = m.PointerConstant(inputs); - Node* n0 = m.Load(kMachInt32, base, m.Int32Constant(0 * sizeof(int32_t))); - Node* n1 = m.Load(kMachInt32, base, m.Int32Constant(1 * sizeof(int32_t))); - Node* n2 = m.Load(kMachInt32, base, m.Int32Constant(2 * sizeof(int32_t))); - Node* n3 = m.Load(kMachInt32, base, m.Int32Constant(3 * sizeof(int32_t))); - Node* n4 = m.Load(kMachInt32, base, m.Int32Constant(4 * sizeof(int32_t))); - Node* n5 = m.Load(kMachInt32, base, m.Int32Constant(5 * sizeof(int32_t))); - Node* n6 = m.Load(kMachInt32, base, m.Int32Constant(6 * sizeof(int32_t))); - Node* n7 = m.Load(kMachInt32, base, m.Int32Constant(7 * sizeof(int32_t))); + Node* n0 = + m.Load(MachineType::Int32(), base, m.Int32Constant(0 * sizeof(int32_t))); + Node* n1 = + m.Load(MachineType::Int32(), base, m.Int32Constant(1 * sizeof(int32_t))); + Node* n2 = + m.Load(MachineType::Int32(), base, m.Int32Constant(2 * sizeof(int32_t))); + Node* n3 = + m.Load(MachineType::Int32(), base, m.Int32Constant(3 * sizeof(int32_t))); + Node* n4 = + m.Load(MachineType::Int32(), base, m.Int32Constant(4 * sizeof(int32_t))); + Node* n5 = + m.Load(MachineType::Int32(), base, m.Int32Constant(5 * sizeof(int32_t))); + Node* n6 = + m.Load(MachineType::Int32(), base, m.Int32Constant(6 * sizeof(int32_t))); + Node* n7 = + m.Load(MachineType::Int32(), base, m.Int32Constant(7 * sizeof(int32_t))); Node* i1 = m.Int32Add(n0, n1); Node* i2 = m.Int32Add(n2, n3); @@ -4283,10 +4526,12 @@ static int Float64CompareHelper(RawMachineAssemblerTester<int32_t>* m, CHECK(x < y); bool load_a = node_type / 2 == 1; bool load_b = node_type % 2 == 1; - Node* a = load_a ? m->Load(kMachFloat64, m->PointerConstant(&buffer[0])) - : m->Float64Constant(x); - Node* b = load_b ? m->Load(kMachFloat64, m->PointerConstant(&buffer[1])) - : m->Float64Constant(y); + Node* a = + load_a ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[0])) + : m->Float64Constant(x); + Node* b = + load_b ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[1])) + : m->Float64Constant(y); Node* cmp = NULL; bool expected = false; switch (test_case) { @@ -4413,8 +4658,8 @@ TEST(RunFloat64Equal) { double input_b = 0.0; RawMachineAssemblerTester<int32_t> m; - Node* a = m.LoadFromPointer(&input_a, kMachFloat64); - Node* b = m.LoadFromPointer(&input_b, kMachFloat64); + Node* a = m.LoadFromPointer(&input_a, MachineType::Float64()); + Node* b = m.LoadFromPointer(&input_b, MachineType::Float64()); m.Return(m.Float64Equal(a, b)); CompareWrapper cmp(IrOpcode::kFloat64Equal); @@ -4434,8 +4679,8 @@ TEST(RunFloat64LessThan) { double input_b = 0.0; RawMachineAssemblerTester<int32_t> m; - Node* a = m.LoadFromPointer(&input_a, kMachFloat64); - Node* b = m.LoadFromPointer(&input_b, kMachFloat64); + Node* a = m.LoadFromPointer(&input_a, MachineType::Float64()); + Node* b = m.LoadFromPointer(&input_b, MachineType::Float64()); m.Return(m.Float64LessThan(a, b)); CompareWrapper cmp(IrOpcode::kFloat64LessThan); @@ -4450,14 +4695,14 @@ TEST(RunFloat64LessThan) { } -template <typename IntType, MachineType kRepresentation> -static void LoadStoreTruncation() { +template <typename IntType> +static void LoadStoreTruncation(MachineType kRepresentation) { IntType input; RawMachineAssemblerTester<int32_t> m; Node* a = m.LoadFromPointer(&input, kRepresentation); Node* ap1 = m.Int32Add(a, m.Int32Constant(1)); - m.StoreToPointer(&input, kRepresentation, ap1); + m.StoreToPointer(&input, kRepresentation.representation(), ap1); m.Return(ap1); const IntType max = std::numeric_limits<IntType>::max(); @@ -4484,14 +4729,15 @@ static void LoadStoreTruncation() { TEST(RunLoadStoreTruncation) { - LoadStoreTruncation<int8_t, kMachInt8>(); - LoadStoreTruncation<int16_t, kMachInt16>(); + LoadStoreTruncation<int8_t>(MachineType::Int8()); + LoadStoreTruncation<int16_t>(MachineType::Int16()); } static void IntPtrCompare(intptr_t left, intptr_t right) { for (int test = 0; test < 7; test++) { - RawMachineAssemblerTester<bool> m(kMachPtr, kMachPtr); + RawMachineAssemblerTester<bool> m(MachineType::Pointer(), + MachineType::Pointer()); Node* p0 = m.Parameter(0); Node* p1 = m.Parameter(1); Node* res = NULL; @@ -4560,7 +4806,8 @@ TEST(RunTestIntPtrArithmetic) { Node* output = m.PointerConstant(&outputs[kInputSize - 1]); Node* elem_size = m.IntPtrConstant(sizeof(inputs[0])); for (int i = 0; i < kInputSize; i++) { - m.Store(kMachInt32, output, m.Load(kMachInt32, input), kNoWriteBarrier); + m.Store(MachineRepresentation::kWord32, output, + m.Load(MachineType::Int32(), input), kNoWriteBarrier); input = m.IntPtrAdd(input, elem_size); output = m.IntPtrSub(output, elem_size); } @@ -4585,7 +4832,7 @@ TEST(RunSpillLotsOfThings) { accs[i] = acc; } for (int i = 0; i < kInputSize; i++) { - m.StoreToPointer(&outputs[i], kMachInt32, accs[i]); + m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]); } m.Return(one); m.Call(); @@ -4598,7 +4845,8 @@ TEST(RunSpillLotsOfThings) { TEST(RunSpillConstantsAndParameters) { static const int kInputSize = 1000; static const int32_t kBase = 987; - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); int32_t outputs[kInputSize]; Node* csts[kInputSize]; Node* accs[kInputSize]; @@ -4611,7 +4859,7 @@ TEST(RunSpillConstantsAndParameters) { accs[i] = acc; } for (int i = 0; i < kInputSize; i++) { - m.StoreToPointer(&outputs[i], kMachInt32, accs[i]); + m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]); } m.Return(m.Int32Add(acc, m.Int32Add(m.Parameter(0), m.Parameter(1)))); FOR_INT32_INPUTS(i) { @@ -4632,7 +4880,7 @@ TEST(RunSpillConstantsAndParameters) { TEST(RunNewSpaceConstantsInPhi) { - RawMachineAssemblerTester<Object*> m(kMachInt32); + RawMachineAssemblerTester<Object*> m(MachineType::Int32()); Isolate* isolate = CcTest::i_isolate(); Handle<HeapNumber> true_val = isolate->factory()->NewHeapNumber(11.2); @@ -4640,7 +4888,7 @@ TEST(RunNewSpaceConstantsInPhi) { Node* true_node = m.HeapConstant(true_val); Node* false_node = m.HeapConstant(false_val); - MLabel blocka, blockb, end; + RawMachineLabel blocka, blockb, end; m.Branch(m.Parameter(0), &blocka, &blockb); m.Bind(&blocka); m.Goto(&end); @@ -4648,7 +4896,7 @@ TEST(RunNewSpaceConstantsInPhi) { m.Goto(&end); m.Bind(&end); - Node* phi = m.Phi(kMachAnyTagged, true_node, false_node); + Node* phi = m.Phi(MachineRepresentation::kTagged, true_node, false_node); m.Return(phi); CHECK_EQ(*false_val, m.Call(0)); @@ -4663,7 +4911,7 @@ TEST(RunInt32AddWithOverflowP) { Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1); Node* val = m.Projection(0, add); Node* ovf = m.Projection(1, add); - m.StoreToPointer(&actual_val, kMachInt32, val); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); bt.AddReturn(ovf); FOR_INT32_INPUTS(i) { FOR_INT32_INPUTS(j) { @@ -4680,11 +4928,11 @@ TEST(RunInt32AddWithOverflowImm) { int32_t actual_val = -1, expected_val = 0; FOR_INT32_INPUTS(i) { { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); Node* add = m.Int32AddWithOverflow(m.Int32Constant(*i), m.Parameter(0)); Node* val = m.Projection(0, add); Node* ovf = m.Projection(1, add); - m.StoreToPointer(&actual_val, kMachInt32, val); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); m.Return(ovf); FOR_INT32_INPUTS(j) { int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); @@ -4693,11 +4941,11 @@ TEST(RunInt32AddWithOverflowImm) { } } { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); Node* add = m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(*i)); Node* val = m.Projection(0, add); Node* ovf = m.Projection(1, add); - m.StoreToPointer(&actual_val, kMachInt32, val); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); m.Return(ovf); FOR_INT32_INPUTS(j) { int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); @@ -4711,7 +4959,7 @@ TEST(RunInt32AddWithOverflowImm) { m.Int32AddWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j)); Node* val = m.Projection(0, add); Node* ovf = m.Projection(1, add); - m.StoreToPointer(&actual_val, kMachInt32, val); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); m.Return(ovf); int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); CHECK_EQ(expected_ovf, m.Call()); @@ -4723,7 +4971,7 @@ TEST(RunInt32AddWithOverflowImm) { TEST(RunInt32AddWithOverflowInBranchP) { int constant = 911777; - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; RawMachineAssemblerTester<int32_t> m; Int32BinopTester bt(&m); Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1); @@ -4751,7 +4999,7 @@ TEST(RunInt32SubWithOverflowP) { Node* add = m.Int32SubWithOverflow(bt.param0, bt.param1); Node* val = m.Projection(0, add); Node* ovf = m.Projection(1, add); - m.StoreToPointer(&actual_val, kMachInt32, val); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); bt.AddReturn(ovf); FOR_INT32_INPUTS(i) { FOR_INT32_INPUTS(j) { @@ -4768,11 +5016,11 @@ TEST(RunInt32SubWithOverflowImm) { int32_t actual_val = -1, expected_val = 0; FOR_INT32_INPUTS(i) { { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); Node* add = m.Int32SubWithOverflow(m.Int32Constant(*i), m.Parameter(0)); Node* val = m.Projection(0, add); Node* ovf = m.Projection(1, add); - m.StoreToPointer(&actual_val, kMachInt32, val); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); m.Return(ovf); FOR_INT32_INPUTS(j) { int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val); @@ -4781,11 +5029,11 @@ TEST(RunInt32SubWithOverflowImm) { } } { - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); Node* add = m.Int32SubWithOverflow(m.Parameter(0), m.Int32Constant(*i)); Node* val = m.Projection(0, add); Node* ovf = m.Projection(1, add); - m.StoreToPointer(&actual_val, kMachInt32, val); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); m.Return(ovf); FOR_INT32_INPUTS(j) { int expected_ovf = bits::SignedSubOverflow32(*j, *i, &expected_val); @@ -4799,7 +5047,7 @@ TEST(RunInt32SubWithOverflowImm) { m.Int32SubWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j)); Node* val = m.Projection(0, add); Node* ovf = m.Projection(1, add); - m.StoreToPointer(&actual_val, kMachInt32, val); + m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); m.Return(ovf); int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val); CHECK_EQ(expected_ovf, m.Call()); @@ -4811,7 +5059,7 @@ TEST(RunInt32SubWithOverflowImm) { TEST(RunInt32SubWithOverflowInBranchP) { int constant = 911999; - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; RawMachineAssemblerTester<int32_t> m; Int32BinopTester bt(&m); Node* sub = m.Int32SubWithOverflow(bt.param0, bt.param1); @@ -4834,10 +5082,10 @@ TEST(RunInt32SubWithOverflowInBranchP) { TEST(RunWord64EqualInBranchP) { int64_t input; - MLabel blocka, blockb; + RawMachineLabel blocka, blockb; RawMachineAssemblerTester<int64_t> m; if (!m.machine()->Is64()) return; - Node* value = m.LoadFromPointer(&input, kMachInt64); + Node* value = m.LoadFromPointer(&input, MachineType::Int64()); m.Branch(m.Word64Equal(value, m.Int64Constant(0)), &blocka, &blockb); m.Bind(&blocka); m.Return(m.Int32Constant(1)); @@ -4855,8 +5103,9 @@ TEST(RunWord64EqualInBranchP) { TEST(RunChangeInt32ToInt64P) { if (kPointerSize < 8) return; int64_t actual = -1; - RawMachineAssemblerTester<int32_t> m(kMachInt32); - m.StoreToPointer(&actual, kMachInt64, m.ChangeInt32ToInt64(m.Parameter(0))); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); + m.StoreToPointer(&actual, MachineRepresentation::kWord64, + m.ChangeInt32ToInt64(m.Parameter(0))); m.Return(m.Int32Constant(0)); FOR_INT32_INPUTS(i) { int64_t expected = *i; @@ -4869,8 +5118,8 @@ TEST(RunChangeInt32ToInt64P) { TEST(RunChangeUint32ToUint64P) { if (kPointerSize < 8) return; int64_t actual = -1; - RawMachineAssemblerTester<int32_t> m(kMachUint32); - m.StoreToPointer(&actual, kMachUint64, + RawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); + m.StoreToPointer(&actual, MachineRepresentation::kWord64, m.ChangeUint32ToUint64(m.Parameter(0))); m.Return(m.Int32Constant(0)); FOR_UINT32_INPUTS(i) { @@ -4885,7 +5134,8 @@ TEST(RunTruncateInt64ToInt32P) { if (kPointerSize < 8) return; int64_t expected = -1; RawMachineAssemblerTester<int32_t> m; - m.Return(m.TruncateInt64ToInt32(m.LoadFromPointer(&expected, kMachInt64))); + m.Return(m.TruncateInt64ToInt32( + m.LoadFromPointer(&expected, MachineType::Int64()))); FOR_UINT32_INPUTS(i) { FOR_UINT32_INPUTS(j) { expected = (static_cast<uint64_t>(*j) << 32) | *i; @@ -4956,8 +5206,9 @@ TEST(RunTruncateFloat64ToInt32P) { {-1.7976931348623157e+308, 0}}; double input = -1.0; RawMachineAssemblerTester<int32_t> m; - m.Return(m.TruncateFloat64ToInt32(TruncationMode::kJavaScript, - m.LoadFromPointer(&input, kMachFloat64))); + m.Return(m.TruncateFloat64ToInt32( + TruncationMode::kJavaScript, + m.LoadFromPointer(&input, MachineType::Float64()))); for (size_t i = 0; i < arraysize(kValues); ++i) { input = kValues[i].from; uint64_t expected = static_cast<int64_t>(kValues[i].raw); @@ -4967,7 +5218,7 @@ TEST(RunTruncateFloat64ToInt32P) { TEST(RunChangeFloat32ToFloat64) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat32); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float32()); m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0))); @@ -4985,7 +5236,7 @@ TEST(RunFloat32Constant) { TEST(RunFloat64ExtractLowWord32) { - BufferedRawMachineAssemblerTester<uint32_t> m(kMachFloat64); + BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64()); m.Return(m.Float64ExtractLowWord32(m.Parameter(0))); FOR_FLOAT64_INPUTS(i) { uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i)); @@ -4995,7 +5246,7 @@ TEST(RunFloat64ExtractLowWord32) { TEST(RunFloat64ExtractHighWord32) { - BufferedRawMachineAssemblerTester<uint32_t> m(kMachFloat64); + BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64()); m.Return(m.Float64ExtractHighWord32(m.Parameter(0))); FOR_FLOAT64_INPUTS(i) { uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i) >> 32); @@ -5005,7 +5256,8 @@ TEST(RunFloat64ExtractHighWord32) { TEST(RunFloat64InsertLowWord32) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64, kMachInt32); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), + MachineType::Int32()); m.Return(m.Float64InsertLowWord32(m.Parameter(0), m.Parameter(1))); FOR_FLOAT64_INPUTS(i) { FOR_INT32_INPUTS(j) { @@ -5019,7 +5271,8 @@ TEST(RunFloat64InsertLowWord32) { TEST(RunFloat64InsertHighWord32) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64, kMachUint32); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), + MachineType::Uint32()); m.Return(m.Float64InsertHighWord32(m.Parameter(0), m.Parameter(1))); FOR_FLOAT64_INPUTS(i) { FOR_UINT32_INPUTS(j) { @@ -5033,14 +5286,14 @@ TEST(RunFloat64InsertHighWord32) { TEST(RunFloat32Abs) { - BufferedRawMachineAssemblerTester<float> m(kMachFloat32); + BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); m.Return(m.Float32Abs(m.Parameter(0))); FOR_FLOAT32_INPUTS(i) { CheckFloatEq(std::abs(*i), m.Call(*i)); } } TEST(RunFloat64Abs) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); m.Return(m.Float64Abs(m.Parameter(0))); FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(std::abs(*i), m.Call(*i)); } } @@ -5144,68 +5397,101 @@ static double kValues[] = {0.1, -two_52 + 1 - 0.7}; +TEST(RunFloat32RoundDown) { + BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); + if (!m.machine()->Float32RoundDown().IsSupported()) return; + + m.Return(m.Float32RoundDown(m.Parameter(0))); + + FOR_FLOAT32_INPUTS(i) { CheckFloatEq(floorf(*i), m.Call(*i)); } +} + + TEST(RunFloat64RoundDown1) { - BufferedRawMachineAssemblerTester<double> m(kMachFloat64); + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); if (!m.machine()->Float64RoundDown().IsSupported()) return; m.Return(m.Float64RoundDown(m.Parameter(0))); - FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(std::floor(*i), m.Call(*i)); } + FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(floor(*i), m.Call(*i)); } } TEST(RunFloat64RoundDown2) { - double input = -1.0; - double result = 0.0; - RawMachineAssemblerTester<int32_t> m; + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); if (!m.machine()->Float64RoundDown().IsSupported()) return; - m.StoreToPointer(&result, kMachFloat64, - m.Float64Sub(m.Float64Constant(-0.0), - m.Float64RoundDown(m.Float64Sub( - m.Float64Constant(-0.0), - m.LoadFromPointer(&input, kMachFloat64))))); - m.Return(m.Int32Constant(0)); + m.Return(m.Float64Sub(m.Float64Constant(-0.0), + m.Float64RoundDown(m.Float64Sub(m.Float64Constant(-0.0), + m.Parameter(0))))); + for (size_t i = 0; i < arraysize(kValues); ++i) { - input = kValues[i]; - CHECK_EQ(0, m.Call()); - double expected = std::ceil(kValues[i]); - CHECK_EQ(expected, result); + CHECK_EQ(ceil(kValues[i]), m.Call(kValues[i])); } } +TEST(RunFloat32RoundUp) { + BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); + if (!m.machine()->Float32RoundUp().IsSupported()) return; + m.Return(m.Float32RoundUp(m.Parameter(0))); + + FOR_FLOAT32_INPUTS(i) { CheckFloatEq(ceilf(*i), m.Call(*i)); } +} + + +TEST(RunFloat64RoundUp) { + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); + if (!m.machine()->Float64RoundUp().IsSupported()) return; + m.Return(m.Float64RoundUp(m.Parameter(0))); + + FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(ceil(*i), m.Call(*i)); } +} + + +TEST(RunFloat32RoundTiesEven) { + BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); + if (!m.machine()->Float32RoundTiesEven().IsSupported()) return; + m.Return(m.Float32RoundTiesEven(m.Parameter(0))); + + FOR_FLOAT32_INPUTS(i) { CheckFloatEq(nearbyint(*i), m.Call(*i)); } +} + + +TEST(RunFloat64RoundTiesEven) { + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); + if (!m.machine()->Float64RoundTiesEven().IsSupported()) return; + m.Return(m.Float64RoundTiesEven(m.Parameter(0))); + + FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(nearbyint(*i), m.Call(*i)); } +} + + +TEST(RunFloat32RoundTruncate) { + BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); + if (!m.machine()->Float32RoundTruncate().IsSupported()) return; + + m.Return(m.Float32RoundTruncate(m.Parameter(0))); + + FOR_FLOAT32_INPUTS(i) { CheckFloatEq(truncf(*i), m.Call(*i)); } +} + + TEST(RunFloat64RoundTruncate) { - double input = -1.0; - double result = 0.0; - RawMachineAssemblerTester<int32_t> m; + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); if (!m.machine()->Float64RoundTruncate().IsSupported()) return; - m.StoreToPointer( - &result, kMachFloat64, - m.Float64RoundTruncate(m.LoadFromPointer(&input, kMachFloat64))); - m.Return(m.Int32Constant(0)); + m.Return(m.Float64RoundTruncate(m.Parameter(0))); for (size_t i = 0; i < arraysize(kValues); ++i) { - input = kValues[i]; - CHECK_EQ(0, m.Call()); - double expected = trunc(kValues[i]); - CHECK_EQ(expected, result); + CHECK_EQ(trunc(kValues[i]), m.Call(kValues[i])); } } TEST(RunFloat64RoundTiesAway) { - double input = -1.0; - double result = 0.0; - RawMachineAssemblerTester<int32_t> m; + BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); if (!m.machine()->Float64RoundTiesAway().IsSupported()) return; - m.StoreToPointer( - &result, kMachFloat64, - m.Float64RoundTiesAway(m.LoadFromPointer(&input, kMachFloat64))); - m.Return(m.Int32Constant(0)); + m.Return(m.Float64RoundTiesAway(m.Parameter(0))); for (size_t i = 0; i < arraysize(kValues); ++i) { - input = kValues[i]; - CHECK_EQ(0, m.Call()); - double expected = round(kValues[i]); - CHECK_EQ(expected, result); + CHECK_EQ(round(kValues[i]), m.Call(kValues[i])); } } @@ -5237,17 +5523,18 @@ int32_t foo8(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f, TEST(RunCallCFunction0) { auto* foo0_ptr = &foo0; RawMachineAssemblerTester<int32_t> m; - Node* function = m.LoadFromPointer(&foo0_ptr, kMachPtr); - m.Return(m.CallCFunction0(kMachInt32, function)); + Node* function = m.LoadFromPointer(&foo0_ptr, MachineType::Pointer()); + m.Return(m.CallCFunction0(MachineType::Int32(), function)); CHECK_EQ(kMagicFoo0, m.Call()); } TEST(RunCallCFunction1) { auto* foo1_ptr = &foo1; - RawMachineAssemblerTester<int32_t> m(kMachInt32); - Node* function = m.LoadFromPointer(&foo1_ptr, kMachPtr); - m.Return(m.CallCFunction1(kMachInt32, kMachInt32, function, m.Parameter(0))); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); + Node* function = m.LoadFromPointer(&foo1_ptr, MachineType::Pointer()); + m.Return(m.CallCFunction1(MachineType::Int32(), MachineType::Int32(), + function, m.Parameter(0))); FOR_INT32_INPUTS(i) { int32_t const expected = *i; CHECK_EQ(expected, m.Call(expected)); @@ -5257,10 +5544,12 @@ TEST(RunCallCFunction1) { TEST(RunCallCFunction2) { auto* foo2_ptr = &foo2; - RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32); - Node* function = m.LoadFromPointer(&foo2_ptr, kMachPtr); - m.Return(m.CallCFunction2(kMachInt32, kMachInt32, kMachInt32, function, - m.Parameter(0), m.Parameter(1))); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), + MachineType::Int32()); + Node* function = m.LoadFromPointer(&foo2_ptr, MachineType::Pointer()); + m.Return(m.CallCFunction2(MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), function, m.Parameter(0), + m.Parameter(1))); FOR_INT32_INPUTS(i) { int32_t const x = *i; FOR_INT32_INPUTS(j) { @@ -5273,13 +5562,14 @@ TEST(RunCallCFunction2) { TEST(RunCallCFunction8) { auto* foo8_ptr = &foo8; - RawMachineAssemblerTester<int32_t> m(kMachInt32); - Node* function = m.LoadFromPointer(&foo8_ptr, kMachPtr); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); + Node* function = m.LoadFromPointer(&foo8_ptr, MachineType::Pointer()); Node* param = m.Parameter(0); - m.Return(m.CallCFunction8(kMachInt32, kMachInt32, kMachInt32, kMachInt32, - kMachInt32, kMachInt32, kMachInt32, kMachInt32, - kMachInt32, function, param, param, param, param, - param, param, param, param)); + m.Return(m.CallCFunction8( + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + function, param, param, param, param, param, param, param, param)); FOR_INT32_INPUTS(i) { int32_t const x = *i; CHECK_EQ(x * 8, m.Call(x)); @@ -5291,12 +5581,12 @@ TEST(RunCallCFunction8) { // TODO(titzer): run int64 tests on all platforms when supported. TEST(RunCheckedLoadInt64) { int64_t buffer[] = {0x66bbccddeeff0011LL, 0x1122334455667788LL}; - RawMachineAssemblerTester<int64_t> m(kMachInt32); + RawMachineAssemblerTester<int64_t> m(MachineType::Int32()); Node* base = m.PointerConstant(buffer); Node* index = m.Parameter(0); Node* length = m.Int32Constant(16); - Node* load = - m.AddNode(m.machine()->CheckedLoad(kMachInt64), base, index, length); + Node* load = m.AddNode(m.machine()->CheckedLoad(MachineType::Int64()), base, + index, length); m.Return(load); CHECK_EQ(buffer[0], m.Call(0)); @@ -5309,13 +5599,14 @@ TEST(RunCheckedStoreInt64) { const int64_t write = 0x5566778899aabbLL; const int64_t before = 0x33bbccddeeff0011LL; int64_t buffer[] = {before, before}; - RawMachineAssemblerTester<int32_t> m(kMachInt32); + RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); Node* base = m.PointerConstant(buffer); Node* index = m.Parameter(0); Node* length = m.Int32Constant(16); Node* value = m.Int64Constant(write); - Node* store = m.AddNode(m.machine()->CheckedStore(kMachInt64), base, index, - length, value); + Node* store = + m.AddNode(m.machine()->CheckedStore(MachineRepresentation::kWord64), base, + index, length, value); USE(store); m.Return(m.Int32Constant(11)); @@ -5338,8 +5629,8 @@ TEST(RunBitcastInt64ToFloat64) { double output = 0.0; RawMachineAssemblerTester<int32_t> m; m.StoreToPointer( - &output, kMachFloat64, - m.BitcastInt64ToFloat64(m.LoadFromPointer(&input, kMachInt64))); + &output, MachineRepresentation::kFloat64, + m.BitcastInt64ToFloat64(m.LoadFromPointer(&input, MachineType::Int64()))); m.Return(m.Int32Constant(11)); FOR_INT64_INPUTS(i) { input = *i; @@ -5351,43 +5642,357 @@ TEST(RunBitcastInt64ToFloat64) { TEST(RunBitcastFloat64ToInt64) { - double input = 0; - int64_t output = 0; - RawMachineAssemblerTester<int32_t> m; - m.StoreToPointer( - &output, kMachInt64, - m.BitcastFloat64ToInt64(m.LoadFromPointer(&input, kMachFloat64))); - m.Return(m.Int32Constant(11)); + BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64()); + + m.Return(m.BitcastFloat64ToInt64(m.Parameter(0))); + FOR_FLOAT64_INPUTS(i) { CHECK_EQ(bit_cast<int64_t>(*i), m.Call(*i)); } +} + + +TEST(RunTryTruncateFloat32ToInt64WithoutCheck) { + BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32()); + m.Return(m.TryTruncateFloat32ToInt64(m.Parameter(0))); + + FOR_INT64_INPUTS(i) { + float input = static_cast<float>(*i); + if (input < static_cast<float>(INT64_MAX) && + input >= static_cast<float>(INT64_MIN)) { + CHECK_EQ(static_cast<int64_t>(input), m.Call(input)); + } + } +} + + +TEST(RunTryTruncateFloat32ToInt64WithCheck) { + int64_t success = 0; + BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32()); + Node* trunc = m.TryTruncateFloat32ToInt64(m.Parameter(0)); + Node* val = m.Projection(0, trunc); + Node* check = m.Projection(1, trunc); + m.StoreToPointer(&success, MachineRepresentation::kWord64, check); + m.Return(val); + + FOR_FLOAT32_INPUTS(i) { + if (*i < static_cast<float>(INT64_MAX) && + *i >= static_cast<float>(INT64_MIN)) { + CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i)); + CHECK_NE(0, success); + } else { + m.Call(*i); + CHECK_EQ(0, success); + } + } +} + + +TEST(RunTryTruncateFloat64ToInt64WithoutCheck) { + BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64()); + m.Return(m.TryTruncateFloat64ToInt64(m.Parameter(0))); + + FOR_INT64_INPUTS(i) { + double input = static_cast<double>(*i); + CHECK_EQ(static_cast<int64_t>(input), m.Call(input)); + } +} + + +TEST(RunTryTruncateFloat64ToInt64WithCheck) { + int64_t success = 0; + BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64()); + Node* trunc = m.TryTruncateFloat64ToInt64(m.Parameter(0)); + Node* val = m.Projection(0, trunc); + Node* check = m.Projection(1, trunc); + m.StoreToPointer(&success, MachineRepresentation::kWord64, check); + m.Return(val); + FOR_FLOAT64_INPUTS(i) { - input = *i; - CHECK_EQ(11, m.Call()); - double expected = bit_cast<int64_t>(input); - CHECK_EQ(expected, output); + if (*i < static_cast<double>(INT64_MAX) && + *i >= static_cast<double>(INT64_MIN)) { + // Conversions within this range should succeed. + CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i)); + CHECK_NE(0, success); + } else { + m.Call(*i); + CHECK_EQ(0, success); + } + } +} + + +TEST(RunTryTruncateFloat32ToUint64WithoutCheck) { + BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32()); + m.Return(m.TryTruncateFloat32ToUint64(m.Parameter(0))); + + FOR_UINT64_INPUTS(i) { + float input = static_cast<float>(*i); + // This condition on 'input' is required because + // static_cast<float>(UINT64_MAX) results in a value outside uint64 range. + if (input < static_cast<float>(UINT64_MAX)) { + CHECK_EQ(static_cast<uint64_t>(input), m.Call(input)); + } + } +} + + +TEST(RunTryTruncateFloat32ToUint64WithCheck) { + int64_t success = 0; + BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32()); + Node* trunc = m.TryTruncateFloat32ToUint64(m.Parameter(0)); + Node* val = m.Projection(0, trunc); + Node* check = m.Projection(1, trunc); + m.StoreToPointer(&success, MachineRepresentation::kWord64, check); + m.Return(val); + + FOR_FLOAT32_INPUTS(i) { + if (*i < static_cast<float>(UINT64_MAX) && *i > -1.0) { + // Conversions within this range should succeed. + CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i)); + CHECK_NE(0, success); + } else { + m.Call(*i); + CHECK_EQ(0, success); + } + } +} + + +TEST(RunTryTruncateFloat64ToUint64WithoutCheck) { + BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float64()); + m.Return(m.TruncateFloat64ToUint64(m.Parameter(0))); + + FOR_UINT64_INPUTS(j) { + double input = static_cast<double>(*j); + + if (input < static_cast<float>(UINT64_MAX)) { + CHECK_EQ(static_cast<uint64_t>(input), m.Call(input)); + } + } +} + + +TEST(RunTryTruncateFloat64ToUint64WithCheck) { + int64_t success = 0; + BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64()); + Node* trunc = m.TryTruncateFloat64ToUint64(m.Parameter(0)); + Node* val = m.Projection(0, trunc); + Node* check = m.Projection(1, trunc); + m.StoreToPointer(&success, MachineRepresentation::kWord64, check); + m.Return(val); + + FOR_FLOAT64_INPUTS(i) { + if (*i < 18446744073709551616.0 && *i > -1) { + // Conversions within this range should succeed. + CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i)); + CHECK_NE(0, success); + } else { + m.Call(*i); + CHECK_EQ(0, success); + } } } TEST(RunRoundInt64ToFloat32) { - BufferedRawMachineAssemblerTester<float> m(kMachInt64); + BufferedRawMachineAssemblerTester<float> m(MachineType::Int64()); m.Return(m.RoundInt64ToFloat32(m.Parameter(0))); FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), m.Call(*i)); } } TEST(RunRoundInt64ToFloat64) { - BufferedRawMachineAssemblerTester<double> m(kMachInt64); + BufferedRawMachineAssemblerTester<double> m(MachineType::Int64()); m.Return(m.RoundInt64ToFloat64(m.Parameter(0))); FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), m.Call(*i)); } } +TEST(RunRoundUint64ToFloat64) { + struct { + uint64_t input; + uint64_t expected; + } values[] = {{0x0, 0x0}, + {0x1, 0x3ff0000000000000}, + {0xffffffff, 0x41efffffffe00000}, + {0x1b09788b, 0x41bb09788b000000}, + {0x4c5fce8, 0x419317f3a0000000}, + {0xcc0de5bf, 0x41e981bcb7e00000}, + {0x2, 0x4000000000000000}, + {0x3, 0x4008000000000000}, + {0x4, 0x4010000000000000}, + {0x5, 0x4014000000000000}, + {0x8, 0x4020000000000000}, + {0x9, 0x4022000000000000}, + {0xffffffffffffffff, 0x43f0000000000000}, + {0xfffffffffffffffe, 0x43f0000000000000}, + {0xfffffffffffffffd, 0x43f0000000000000}, + {0x100000000, 0x41f0000000000000}, + {0xffffffff00000000, 0x43efffffffe00000}, + {0x1b09788b00000000, 0x43bb09788b000000}, + {0x4c5fce800000000, 0x439317f3a0000000}, + {0xcc0de5bf00000000, 0x43e981bcb7e00000}, + {0x200000000, 0x4200000000000000}, + {0x300000000, 0x4208000000000000}, + {0x400000000, 0x4210000000000000}, + {0x500000000, 0x4214000000000000}, + {0x800000000, 0x4220000000000000}, + {0x900000000, 0x4222000000000000}, + {0x273a798e187937a3, 0x43c39d3cc70c3c9c}, + {0xece3af835495a16b, 0x43ed9c75f06a92b4}, + {0xb668ecc11223344, 0x43a6cd1d98224467}, + {0x9e, 0x4063c00000000000}, + {0x43, 0x4050c00000000000}, + {0xaf73, 0x40e5ee6000000000}, + {0x116b, 0x40b16b0000000000}, + {0x658ecc, 0x415963b300000000}, + {0x2b3b4c, 0x41459da600000000}, + {0x88776655, 0x41e10eeccaa00000}, + {0x70000000, 0x41dc000000000000}, + {0x7200000, 0x419c800000000000}, + {0x7fffffff, 0x41dfffffffc00000}, + {0x56123761, 0x41d5848dd8400000}, + {0x7fffff00, 0x41dfffffc0000000}, + {0x761c4761eeeeeeee, 0x43dd8711d87bbbbc}, + {0x80000000eeeeeeee, 0x43e00000001dddde}, + {0x88888888dddddddd, 0x43e11111111bbbbc}, + {0xa0000000dddddddd, 0x43e40000001bbbbc}, + {0xddddddddaaaaaaaa, 0x43ebbbbbbbb55555}, + {0xe0000000aaaaaaaa, 0x43ec000000155555}, + {0xeeeeeeeeeeeeeeee, 0x43edddddddddddde}, + {0xfffffffdeeeeeeee, 0x43efffffffbdddde}, + {0xf0000000dddddddd, 0x43ee0000001bbbbc}, + {0x7fffffdddddddd, 0x435ffffff7777777}, + {0x3fffffaaaaaaaa, 0x434fffffd5555555}, + {0x1fffffaaaaaaaa, 0x433fffffaaaaaaaa}, + {0xfffff, 0x412ffffe00000000}, + {0x7ffff, 0x411ffffc00000000}, + {0x3ffff, 0x410ffff800000000}, + {0x1ffff, 0x40fffff000000000}, + {0xffff, 0x40efffe000000000}, + {0x7fff, 0x40dfffc000000000}, + {0x3fff, 0x40cfff8000000000}, + {0x1fff, 0x40bfff0000000000}, + {0xfff, 0x40affe0000000000}, + {0x7ff, 0x409ffc0000000000}, + {0x3ff, 0x408ff80000000000}, + {0x1ff, 0x407ff00000000000}, + {0x3fffffffffff, 0x42cfffffffffff80}, + {0x1fffffffffff, 0x42bfffffffffff00}, + {0xfffffffffff, 0x42affffffffffe00}, + {0x7ffffffffff, 0x429ffffffffffc00}, + {0x3ffffffffff, 0x428ffffffffff800}, + {0x1ffffffffff, 0x427ffffffffff000}, + {0x8000008000000000, 0x43e0000010000000}, + {0x8000008000000001, 0x43e0000010000000}, + {0x8000000000000400, 0x43e0000000000000}, + {0x8000000000000401, 0x43e0000000000001}}; + + BufferedRawMachineAssemblerTester<double> m(MachineType::Uint64()); + m.Return(m.RoundUint64ToFloat64(m.Parameter(0))); + + for (size_t i = 0; i < arraysize(values); i++) { + CHECK_EQ(bit_cast<double>(values[i].expected), m.Call(values[i].input)); + } +} + + +TEST(RunRoundUint64ToFloat32) { + struct { + uint64_t input; + uint32_t expected; + } values[] = {{0x0, 0x0}, + {0x1, 0x3f800000}, + {0xffffffff, 0x4f800000}, + {0x1b09788b, 0x4dd84bc4}, + {0x4c5fce8, 0x4c98bf9d}, + {0xcc0de5bf, 0x4f4c0de6}, + {0x2, 0x40000000}, + {0x3, 0x40400000}, + {0x4, 0x40800000}, + {0x5, 0x40a00000}, + {0x8, 0x41000000}, + {0x9, 0x41100000}, + {0xffffffffffffffff, 0x5f800000}, + {0xfffffffffffffffe, 0x5f800000}, + {0xfffffffffffffffd, 0x5f800000}, + {0x0, 0x0}, + {0x100000000, 0x4f800000}, + {0xffffffff00000000, 0x5f800000}, + {0x1b09788b00000000, 0x5dd84bc4}, + {0x4c5fce800000000, 0x5c98bf9d}, + {0xcc0de5bf00000000, 0x5f4c0de6}, + {0x200000000, 0x50000000}, + {0x300000000, 0x50400000}, + {0x400000000, 0x50800000}, + {0x500000000, 0x50a00000}, + {0x800000000, 0x51000000}, + {0x900000000, 0x51100000}, + {0x273a798e187937a3, 0x5e1ce9e6}, + {0xece3af835495a16b, 0x5f6ce3b0}, + {0xb668ecc11223344, 0x5d3668ed}, + {0x9e, 0x431e0000}, + {0x43, 0x42860000}, + {0xaf73, 0x472f7300}, + {0x116b, 0x458b5800}, + {0x658ecc, 0x4acb1d98}, + {0x2b3b4c, 0x4a2ced30}, + {0x88776655, 0x4f087766}, + {0x70000000, 0x4ee00000}, + {0x7200000, 0x4ce40000}, + {0x7fffffff, 0x4f000000}, + {0x56123761, 0x4eac246f}, + {0x7fffff00, 0x4efffffe}, + {0x761c4761eeeeeeee, 0x5eec388f}, + {0x80000000eeeeeeee, 0x5f000000}, + {0x88888888dddddddd, 0x5f088889}, + {0xa0000000dddddddd, 0x5f200000}, + {0xddddddddaaaaaaaa, 0x5f5dddde}, + {0xe0000000aaaaaaaa, 0x5f600000}, + {0xeeeeeeeeeeeeeeee, 0x5f6eeeef}, + {0xfffffffdeeeeeeee, 0x5f800000}, + {0xf0000000dddddddd, 0x5f700000}, + {0x7fffffdddddddd, 0x5b000000}, + {0x3fffffaaaaaaaa, 0x5a7fffff}, + {0x1fffffaaaaaaaa, 0x59fffffd}, + {0xfffff, 0x497ffff0}, + {0x7ffff, 0x48ffffe0}, + {0x3ffff, 0x487fffc0}, + {0x1ffff, 0x47ffff80}, + {0xffff, 0x477fff00}, + {0x7fff, 0x46fffe00}, + {0x3fff, 0x467ffc00}, + {0x1fff, 0x45fff800}, + {0xfff, 0x457ff000}, + {0x7ff, 0x44ffe000}, + {0x3ff, 0x447fc000}, + {0x1ff, 0x43ff8000}, + {0x3fffffffffff, 0x56800000}, + {0x1fffffffffff, 0x56000000}, + {0xfffffffffff, 0x55800000}, + {0x7ffffffffff, 0x55000000}, + {0x3ffffffffff, 0x54800000}, + {0x1ffffffffff, 0x54000000}, + {0x8000008000000000, 0x5f000000}, + {0x8000008000000001, 0x5f000001}, + {0x8000000000000400, 0x5f000000}, + {0x8000000000000401, 0x5f000000}}; + + BufferedRawMachineAssemblerTester<float> m(MachineType::Uint64()); + m.Return(m.RoundUint64ToFloat32(m.Parameter(0))); + + for (size_t i = 0; i < arraysize(values); i++) { + CHECK_EQ(bit_cast<float>(values[i].expected), m.Call(values[i].input)); + } +} + + #endif TEST(RunBitcastFloat32ToInt32) { float input = 32.25; RawMachineAssemblerTester<int32_t> m; - m.Return(m.BitcastFloat32ToInt32(m.LoadFromPointer(&input, kMachFloat32))); + m.Return(m.BitcastFloat32ToInt32( + m.LoadFromPointer(&input, MachineType::Float32()))); FOR_FLOAT32_INPUTS(i) { input = *i; int32_t expected = bit_cast<int32_t>(input); @@ -5401,8 +6006,8 @@ TEST(RunBitcastInt32ToFloat32) { float output = 0.0; RawMachineAssemblerTester<int32_t> m; m.StoreToPointer( - &output, kMachFloat32, - m.BitcastInt32ToFloat32(m.LoadFromPointer(&input, kMachInt32))); + &output, MachineRepresentation::kFloat32, + m.BitcastInt32ToFloat32(m.LoadFromPointer(&input, MachineType::Int32()))); m.Return(m.Int32Constant(11)); FOR_INT32_INPUTS(i) { input = *i; @@ -5424,10 +6029,10 @@ TEST(RunComputedCodeObject) { b.End(); Handle<Code> code_b = b.GetCode(); - RawMachineAssemblerTester<int32_t> r(kMachInt32); - RawMachineAssembler::Label tlabel; - RawMachineAssembler::Label flabel; - RawMachineAssembler::Label merge; + RawMachineAssemblerTester<int32_t> r(MachineType::Int32()); + RawMachineLabel tlabel; + RawMachineLabel flabel; + RawMachineLabel merge; r.Branch(r.Parameter(0), &tlabel, &flabel); r.Bind(&tlabel); Node* fa = r.HeapConstant(code_a); @@ -5436,7 +6041,7 @@ TEST(RunComputedCodeObject) { Node* fb = r.HeapConstant(code_b); r.Goto(&merge); r.Bind(&merge); - Node* phi = r.Phi(kMachInt32, fa, fb); + Node* phi = r.Phi(MachineRepresentation::kWord32, fa, fb); // TODO(titzer): all this descriptor hackery is just to call the above // functions as code objects instead of direct addresses. @@ -5446,7 +6051,7 @@ TEST(RunComputedCodeObject) { Signature<LinkageLocation> loc(1, 0, ret); CallDescriptor* desc = new (r.zone()) CallDescriptor( // -- CallDescriptor::kCallCodeObject, // kind - kMachAnyTagged, // target_type + MachineType::AnyTagged(), // target_type c->GetInputLocation(0), // target_loc &sig, // machine_sig &loc, // location_sig diff --git a/deps/v8/test/cctest/compiler/test-run-native-calls.cc b/deps/v8/test/cctest/compiler/test-run-native-calls.cc index 3c64bc1295..791b0d7ae5 100644 --- a/deps/v8/test/cctest/compiler/test-run-native-calls.cc +++ b/deps/v8/test/cctest/compiler/test-run-native-calls.cc @@ -2,14 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #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 "src/machine-type.h" #include "src/register-configuration.h" #include "test/cctest/cctest.h" @@ -21,15 +18,6 @@ namespace v8 { namespace internal { namespace 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; @@ -145,7 +133,7 @@ struct Allocator { int stack_offset; LinkageLocation Next(MachineType type) { - if (IsFloatingPoint(type)) { + if (IsFloatingPoint(type.representation())) { // Allocate a floating point register/stack location. if (fp_offset < fp_count) { return LinkageLocation::ForRegister(fp_regs[fp_offset++]); @@ -165,16 +153,11 @@ struct Allocator { } } } - 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) + int size = IsFloatingPoint(type.representation()) ? kDoubleSize - : ElementSizeOf(type); + : (1 << ElementSizeLog2Of(type.representation())); return size <= kPointerSize ? 1 : size / kPointerSize; } void Reset() { @@ -210,7 +193,7 @@ class RegisterConfig { const RegList kCalleeSaveRegisters = 0; const RegList kCalleeSaveFPRegisters = 0; - MachineType target_type = compiler::kMachAnyTagged; + MachineType target_type = MachineType::AnyTagged(); LinkageLocation target_loc = LinkageLocation::ForAnyRegister(); int stack_param_count = params.stack_offset; return new (zone) CallDescriptor( // -- @@ -223,7 +206,7 @@ class RegisterConfig { compiler::Operator::kNoProperties, // properties kCalleeSaveRegisters, // callee-saved registers kCalleeSaveFPRegisters, // callee-saved fp regs - CallDescriptor::kNoFlags, // flags + CallDescriptor::kUseNativeStack, // flags "c-call"); } @@ -235,17 +218,28 @@ class RegisterConfig { 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}; + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32()}; // For making uniform int32 signatures shorter. @@ -364,8 +358,8 @@ class ArgsBuffer { Node* StoreOutput(RawMachineAssembler& raw, Node* value) { Node* base = raw.PointerConstant(&output); Node* offset = raw.Int32Constant(0); - return raw.Store(MachineTypeForC<CType>(), base, offset, value, - kNoWriteBarrier); + return raw.Store(MachineTypeForC<CType>().representation(), base, offset, + value, kNoWriteBarrier); } // Computes the next set of inputs by updating the {input} array. @@ -561,8 +555,6 @@ static void TestInt32Sub(CallDescriptor* desc) { static void CopyTwentyInt32(CallDescriptor* desc) { - if (DISABLE_NATIVE_STACK_PARAMS) return; - const int kNumParams = 20; int32_t input[kNumParams]; int32_t output[kNumParams]; @@ -577,7 +569,8 @@ static void CopyTwentyInt32(CallDescriptor* 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), kNoWriteBarrier); + raw.Store(MachineRepresentation::kWord32, base, offset, raw.Parameter(i), + kNoWriteBarrier); } raw.Return(raw.Int32Constant(42)); inner = CompileGraph("CopyTwentyInt32", desc, &graph, raw.Export()); @@ -596,7 +589,7 @@ static void CopyTwentyInt32(CallDescriptor* desc) { 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); + args[i] = raw.Load(MachineType::Int32(), base, offset); } Node* call = raw.CallN(desc, target, args); @@ -674,7 +667,6 @@ 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()) { @@ -692,7 +684,6 @@ TEST(Run_Int32Sub_all_allocatable_single) { TEST(Run_CopyTwentyInt32_all_allocatable_pairs) { - if (DISABLE_NATIVE_STACK_PARAMS) return; Int32Signature sig(20); RegisterPairs pairs; while (pairs.More()) { @@ -745,7 +736,6 @@ static int32_t Compute_Int32_WeightedSum(CallDescriptor* desc, int32_t* input) { static void Test_Int32_WeightedSum_of_size(int count) { - if (DISABLE_NATIVE_STACK_PARAMS) return; Int32Signature sig(count); for (int p0 = 0; p0 < Register::kNumRegisters; p0++) { if (Register::from_code(p0).IsAllocatable()) { @@ -807,8 +797,6 @@ static void RunSelect(CallDescriptor* desc) { template <int which> void Test_Int32_Select() { - if (DISABLE_NATIVE_STACK_PARAMS) return; - int parray[] = { RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN) ->GetAllocatableGeneralCode(0)}; @@ -932,7 +920,6 @@ TEST(Float64Select_registers) { TEST(Float32Select_stack_params_return_reg) { - if (DISABLE_NATIVE_STACK_PARAMS) return; int rarray[] = { RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN) ->GetAllocatableDoubleCode(0)}; @@ -955,7 +942,6 @@ TEST(Float32Select_stack_params_return_reg) { TEST(Float64Select_stack_params_return_reg) { - if (DISABLE_NATIVE_STACK_PARAMS) return; int rarray[] = { RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN) ->GetAllocatableDoubleCode(0)}; @@ -1010,8 +996,6 @@ static void Build_Select_With_Call(CallDescriptor* desc, TEST(Float64StackParamsToStackParams) { - if (DISABLE_NATIVE_STACK_PARAMS) return; - int rarray[] = { RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN) ->GetAllocatableDoubleCode(0)}; @@ -1032,7 +1016,6 @@ TEST(Float64StackParamsToStackParams) { void MixedParamTest(int start) { - if (DISABLE_NATIVE_STACK_PARAMS) return; if (RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN) ->num_double_registers() < 2) return; @@ -1040,16 +1023,21 @@ void MixedParamTest(int start) { // TODO(titzer): mix in 64-bit types on all platforms when supported. #if V8_TARGET_ARCH_32_BIT static MachineType types[] = { - kMachInt32, kMachFloat32, kMachFloat64, kMachInt32, kMachFloat64, - kMachFloat32, kMachFloat32, kMachFloat64, kMachInt32, kMachFloat32, - kMachInt32, kMachFloat64, kMachFloat64, kMachFloat32, kMachInt32, - kMachFloat64, kMachInt32, kMachFloat32}; + MachineType::Int32(), MachineType::Float32(), MachineType::Float64(), + MachineType::Int32(), MachineType::Float64(), MachineType::Float32(), + MachineType::Float32(), MachineType::Float64(), MachineType::Int32(), + MachineType::Float32(), MachineType::Int32(), MachineType::Float64(), + MachineType::Float64(), MachineType::Float32(), MachineType::Int32(), + MachineType::Float64(), MachineType::Int32(), MachineType::Float32()}; #else static MachineType types[] = { - kMachInt32, kMachInt64, kMachFloat32, kMachFloat64, kMachInt32, - kMachFloat64, kMachFloat32, kMachInt64, kMachFloat64, kMachInt32, - kMachFloat32, kMachInt32, kMachFloat64, kMachFloat64, kMachInt64, - kMachInt32, kMachFloat64, kMachInt32, kMachFloat32}; + MachineType::Int32(), MachineType::Int64(), MachineType::Float32(), + MachineType::Float64(), MachineType::Int32(), MachineType::Float64(), + MachineType::Float32(), MachineType::Int64(), MachineType::Int64(), + MachineType::Float32(), MachineType::Float32(), MachineType::Int32(), + MachineType::Float64(), MachineType::Float64(), MachineType::Int64(), + MachineType::Int32(), MachineType::Float64(), MachineType::Int32(), + MachineType::Float32()}; #endif Isolate* isolate = CcTest::InitIsolateOnce(); @@ -1118,22 +1106,22 @@ void MixedParamTest(int start) { for (int i = 0; i < num_params; i++) { MachineType param_type = sig->GetParam(i); Node* konst = nullptr; - if (param_type == kMachInt32) { + if (param_type == MachineType::Int32()) { int32_t value[] = {static_cast<int32_t>(constant)}; konst = raw.Int32Constant(value[0]); if (i == which) memcpy(bytes, value, expected_size = 4); } - if (param_type == kMachInt64) { + if (param_type == MachineType::Int64()) { int64_t value[] = {static_cast<int64_t>(constant)}; konst = raw.Int64Constant(value[0]); if (i == which) memcpy(bytes, value, expected_size = 8); } - if (param_type == kMachFloat32) { + if (param_type == MachineType::Float32()) { float32 value[] = {static_cast<float32>(constant)}; konst = raw.Float32Constant(value[0]); if (i == which) memcpy(bytes, value, expected_size = 4); } - if (param_type == kMachFloat64) { + if (param_type == MachineType::Float64()) { float64 value[] = {static_cast<float64>(constant)}; konst = raw.Float64Constant(value[0]); if (i == which) memcpy(bytes, value, expected_size = 8); @@ -1145,7 +1133,8 @@ void MixedParamTest(int start) { } Node* call = raw.CallN(desc, target, args); - Node* store = raw.StoreToPointer(output, sig->GetReturn(), call); + Node* store = + raw.StoreToPointer(output, sig->GetReturn().representation(), call); USE(store); expected_ret = static_cast<int32_t>(constant); raw.Return(raw.Int32Constant(expected_ret)); diff --git a/deps/v8/test/cctest/compiler/test-run-properties.cc b/deps/v8/test/cctest/compiler/test-run-properties.cc index 2a592300e7..3c42102529 100644 --- a/deps/v8/test/cctest/compiler/test-run-properties.cc +++ b/deps/v8/test/cctest/compiler/test-run-properties.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "test/cctest/compiler/function-tester.h" namespace v8 { diff --git a/deps/v8/test/cctest/compiler/test-run-stackcheck.cc b/deps/v8/test/cctest/compiler/test-run-stackcheck.cc index bba411d283..52556ac87f 100644 --- a/deps/v8/test/cctest/compiler/test-run-stackcheck.cc +++ b/deps/v8/test/cctest/compiler/test-run-stackcheck.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "test/cctest/compiler/function-tester.h" namespace v8 { diff --git a/deps/v8/test/cctest/compiler/test-run-stubs.cc b/deps/v8/test/cctest/compiler/test-run-stubs.cc index c4751c0e28..7a2a09405c 100644 --- a/deps/v8/test/cctest/compiler/test-run-stubs.cc +++ b/deps/v8/test/cctest/compiler/test-run-stubs.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/bootstrapper.h" #include "src/code-stubs.h" #include "src/compiler/common-operator.h" @@ -14,7 +11,7 @@ #include "src/compiler/linkage.h" #include "src/compiler/machine-operator.h" #include "src/compiler/pipeline.h" -#include "src/parser.h" +#include "src/parsing/parser.h" #include "test/cctest/compiler/function-tester.h" namespace v8 { @@ -22,55 +19,13 @@ namespace internal { namespace compiler { -TEST(RunOptimizedMathFloorStub) { - HandleAndZoneScope scope; - Isolate* isolate = scope.main_isolate(); - - // Create code and an accompanying descriptor. - 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); - CommonOperatorBuilder common(zone); - JSOperatorBuilder javascript(zone); - MachineOperatorBuilder machine(zone); - JSGraph js(isolate, &graph, &common, &javascript, nullptr, &machine); - - // FunctionTester (ab)uses a 2-argument function - Node* start = graph.NewNode(common.Start(4)); - // Parameter 0 is the number to round - Node* numberParam = graph.NewNode(common.Parameter(1), start); - Node* theCode = graph.NewNode(common.HeapConstant(code)); - Node* vector = graph.NewNode(common.HeapConstant(tv)); - Node* dummyContext = graph.NewNode(common.NumberConstant(0.0)); - 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); - graph.SetEnd(end); - FunctionTester ft(&graph); - - Handle<Object> value = ft.Val(1.5); - Handle<Object> result = ft.Call(value, value).ToHandleChecked(); - CHECK_EQ(1, Smi::cast(*result)->value()); -} - - -TEST(RunStringLengthTFStub) { +TEST(RunStringLengthStub) { HandleAndZoneScope scope; Isolate* isolate = scope.main_isolate(); Zone* zone = scope.main_zone(); // Create code and an accompanying descriptor. - StringLengthTFStub stub(isolate); + StringLengthStub stub(isolate); Handle<Code> code = stub.GenerateCode(); CompilationInfo info(&stub, isolate, zone); CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info); @@ -94,7 +49,7 @@ TEST(RunStringLengthTFStub) { Node* end = graph.NewNode(common.End(1), ret); graph.SetStart(start); graph.SetEnd(end); - FunctionTester ft(&graph); + FunctionTester ft(&graph, 4); // Actuall call through to the stub, verifying its result. const char* testString = "Und das Lamm schrie HURZ!"; @@ -109,42 +64,6 @@ TEST(RunStringLengthTFStub) { } -TEST(RunStringAddTFStub) { - HandleAndZoneScope scope; - Isolate* isolate = scope.main_isolate(); - Zone* zone = scope.main_zone(); - - // Create code and an accompanying descriptor. - StringAddTFStub stub(isolate, STRING_ADD_CHECK_BOTH, NOT_TENURED); - Handle<Code> code = stub.GenerateCode(); - CompilationInfo info(&stub, isolate, zone); - CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info); - - // Create a function to call the code using the descriptor. - Graph graph(zone); - CommonOperatorBuilder common(zone); - // FunctionTester (ab)uses a 2-argument function - Node* start = graph.NewNode(common.Start(4)); - // Parameter 0 is the receiver - Node* leftParam = graph.NewNode(common.Parameter(1), start); - Node* rightParam = graph.NewNode(common.Parameter(2), start); - Node* theCode = graph.NewNode(common.HeapConstant(code)); - Node* dummyContext = graph.NewNode(common.NumberConstant(0.0)); - Node* call = graph.NewNode(common.Call(descriptor), theCode, leftParam, - rightParam, dummyContext, start, start); - Node* ret = graph.NewNode(common.Return(), call, call, start); - Node* end = graph.NewNode(common.End(1), ret); - graph.SetStart(start); - graph.SetEnd(end); - FunctionTester ft(&graph); - - // Actuall call through to the stub, verifying its result. - Handle<String> leftArg = ft.Val("links"); - Handle<String> rightArg = ft.Val("rechts"); - Handle<Object> result = ft.Call(leftArg, rightArg).ToHandleChecked(); - CHECK(String::Equals(ft.Val("linksrechts"), Handle<String>::cast(result))); -} - } // namespace compiler } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/compiler/test-run-variables.cc b/deps/v8/test/cctest/compiler/test-run-variables.cc index 4f587ef085..f856368509 100644 --- a/deps/v8/test/cctest/compiler/test-run-variables.cc +++ b/deps/v8/test/cctest/compiler/test-run-variables.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "test/cctest/compiler/function-tester.h" namespace v8 { @@ -51,6 +48,7 @@ static const char* bind_tests[] = { static void RunVariableTests(const char* source, const char* tests[]) { + i::FLAG_legacy_const = true; EmbeddedVector<char, 512> buffer; for (int i = 0; tests[i] != NULL; i += 3) { diff --git a/deps/v8/test/cctest/compiler/test-simplified-lowering.cc b/deps/v8/test/cctest/compiler/test-simplified-lowering.cc index 20bfc0f731..1b752edd3c 100644 --- a/deps/v8/test/cctest/compiler/test-simplified-lowering.cc +++ b/deps/v8/test/cctest/compiler/test-simplified-lowering.cc @@ -2,11 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <limits> +#include "src/ast/scopes.h" #include "src/compiler/access-builder.h" #include "src/compiler/change-lowering.h" #include "src/compiler/control-builders.h" @@ -20,9 +18,8 @@ #include "src/compiler/typer.h" #include "src/compiler/verifier.h" #include "src/execution.h" -#include "src/parser.h" -#include "src/rewriter.h" -#include "src/scopes.h" +#include "src/parsing/parser.h" +#include "src/parsing/rewriter.h" #include "test/cctest/cctest.h" #include "test/cctest/compiler/codegen-tester.h" #include "test/cctest/compiler/function-tester.h" @@ -36,8 +33,8 @@ namespace compiler { template <typename ReturnType> class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> { public: - SimplifiedLoweringTester(MachineType p0 = kMachNone, - MachineType p1 = kMachNone) + SimplifiedLoweringTester(MachineType p0 = MachineType::None(), + MachineType p1 = MachineType::None()) : GraphBuilderTester<ReturnType>(p0, p1), typer(this->isolate(), this->graph()), javascript(this->zone()), @@ -83,7 +80,7 @@ class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> { T* CallWithPotentialGC() { // TODO(titzer): we wrap the code in a JSFunction here to reuse the // JSEntryStub; that could be done with a special prologue or other stub. - Handle<JSFunction> fun = FunctionTester::ForMachineGraph(this->graph()); + Handle<JSFunction> fun = FunctionTester::ForMachineGraph(this->graph(), 0); Handle<Object>* args = NULL; MaybeHandle<Object> result = Execution::Call( this->isolate(), fun, factory()->undefined_value(), 0, args); @@ -103,15 +100,15 @@ TEST(RunNumberToInt32_float64) { int32_t result; SimplifiedLoweringTester<Object*> t; FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), - kMachFloat64}; + MachineType::Float64()}; Node* loaded = t.LoadField(load, t.PointerConstant(&input)); NodeProperties::SetType(loaded, Type::Number()); Node* convert = t.NumberToInt32(loaded); FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Signed32(), - kMachInt32}; + MachineType::Int32()}; t.StoreField(store, t.PointerConstant(&result), convert); t.Return(t.jsgraph.TrueConstant()); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); FOR_FLOAT64_INPUTS(i) { @@ -130,15 +127,15 @@ TEST(RunNumberToUint32_float64) { uint32_t result; SimplifiedLoweringTester<Object*> t; FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), - kMachFloat64}; + MachineType::Float64()}; Node* loaded = t.LoadField(load, t.PointerConstant(&input)); NodeProperties::SetType(loaded, Type::Number()); Node* convert = t.NumberToUint32(loaded); FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Unsigned32(), - kMachUint32}; + MachineType::Uint32()}; t.StoreField(store, t.PointerConstant(&result), convert); t.Return(t.jsgraph.TrueConstant()); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); FOR_FLOAT64_INPUTS(i) { @@ -160,12 +157,12 @@ static Handle<JSObject> TestObject() { TEST(RunLoadMap) { - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); FieldAccess access = AccessBuilder::ForMap(); Node* load = t.LoadField(access, t.Parameter(0)); t.Return(load); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); Handle<JSObject> src = TestObject(); @@ -176,12 +173,13 @@ TEST(RunLoadMap) { TEST(RunStoreMap) { - SimplifiedLoweringTester<int32_t> t(kMachAnyTagged, kMachAnyTagged); + SimplifiedLoweringTester<int32_t> t(MachineType::AnyTagged(), + MachineType::AnyTagged()); FieldAccess access = AccessBuilder::ForMap(); t.StoreField(access, t.Parameter(1), t.Parameter(0)); t.Return(t.jsgraph.TrueConstant()); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); Handle<JSObject> src = TestObject(); @@ -194,12 +192,12 @@ TEST(RunStoreMap) { TEST(RunLoadProperties) { - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); FieldAccess access = AccessBuilder::ForJSObjectProperties(); Node* load = t.LoadField(access, t.Parameter(0)); t.Return(load); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); Handle<JSObject> src = TestObject(); @@ -210,13 +208,14 @@ TEST(RunLoadProperties) { TEST(RunLoadStoreMap) { - SimplifiedLoweringTester<Object*> t(kMachAnyTagged, kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged(), + MachineType::AnyTagged()); FieldAccess access = AccessBuilder::ForMap(); Node* load = t.LoadField(access, t.Parameter(0)); t.StoreField(access, t.Parameter(1), load); t.Return(load); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); Handle<JSObject> src = TestObject(); @@ -231,13 +230,13 @@ TEST(RunLoadStoreMap) { TEST(RunLoadStoreFixedArrayIndex) { - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); ElementAccess access = AccessBuilder::ForFixedArrayElement(); Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); t.Return(load); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); Handle<FixedArray> array = t.factory()->NewFixedArray(2); @@ -253,7 +252,7 @@ TEST(RunLoadStoreFixedArrayIndex) { TEST(RunLoadStoreArrayBuffer) { - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); const int index = 12; const int array_length = 2 * index; ElementAccess buffer_access = @@ -266,7 +265,7 @@ TEST(RunLoadStoreArrayBuffer) { load); t.Return(t.jsgraph.TrueConstant()); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer(); @@ -293,12 +292,12 @@ TEST(RunLoadFieldFromUntaggedBase) { for (size_t i = 0; i < arraysize(smis); i++) { int offset = static_cast<int>(i * sizeof(Smi*)); FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), - Type::Integral32(), kMachAnyTagged}; + Type::Integral32(), MachineType::AnyTagged()}; SimplifiedLoweringTester<Object*> t; Node* load = t.LoadField(access, t.PointerConstant(smis)); t.Return(load); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); for (int j = -5; j <= 5; j++) { Smi* expected = Smi::FromInt(j); @@ -315,13 +314,13 @@ TEST(RunStoreFieldToUntaggedBase) { for (size_t i = 0; i < arraysize(smis); i++) { int offset = static_cast<int>(i * sizeof(Smi*)); FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), - Type::Integral32(), kMachAnyTagged}; + Type::Integral32(), MachineType::AnyTagged()}; - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); Node* p0 = t.Parameter(0); t.StoreField(access, t.PointerConstant(smis), p0); t.Return(p0); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); for (int j = -5; j <= 5; j++) { Smi* expected = Smi::FromInt(j); @@ -341,13 +340,13 @@ TEST(RunLoadElementFromUntaggedBase) { for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index int offset = static_cast<int>(i * sizeof(Smi*)); ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), - kMachAnyTagged}; + MachineType::AnyTagged()}; SimplifiedLoweringTester<Object*> t; Node* load = t.LoadElement(access, t.PointerConstant(smis), t.Int32Constant(static_cast<int>(j))); t.Return(load); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); for (int k = -5; k <= 5; k++) { Smi* expected = Smi::FromInt(k); @@ -367,14 +366,14 @@ TEST(RunStoreElementFromUntaggedBase) { for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index int offset = static_cast<int>(i * sizeof(Smi*)); ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), - kMachAnyTagged}; + MachineType::AnyTagged()}; - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); Node* p0 = t.Parameter(0); t.StoreElement(access, t.PointerConstant(smis), t.Int32Constant(static_cast<int>(j)), p0); t.Return(p0); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); for (int k = -5; k <= 5; k++) { Smi* expected = Smi::FromInt(k); @@ -439,7 +438,7 @@ class AccessTester : public HandleAndZoneScope { Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index)); t.StoreElement(access, ptr, t.Int32Constant(to_index), load); t.Return(t.jsgraph.TrueConstant()); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); Object* result = t.Call(); @@ -459,7 +458,7 @@ class AccessTester : public HandleAndZoneScope { Node* load = t.LoadField(from_access, ptr); t.StoreField(to_access, ptr, load); t.Return(t.jsgraph.TrueConstant()); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); Object* result = t.Call(); @@ -595,19 +594,19 @@ static void RunAccessTest(MachineType rep, E* original_elements, size_t num) { TEST(RunAccessTests_uint8) { uint8_t data[] = {0x07, 0x16, 0x25, 0x34, 0x43, 0x99, 0xab, 0x78, 0x89, 0x19, 0x2b, 0x38}; - RunAccessTest<uint8_t>(kMachInt8, data, arraysize(data)); + RunAccessTest<uint8_t>(MachineType::Int8(), data, arraysize(data)); } TEST(RunAccessTests_uint16) { uint16_t data[] = {0x071a, 0x162b, 0x253c, 0x344d, 0x435e, 0x7777}; - RunAccessTest<uint16_t>(kMachInt16, data, arraysize(data)); + RunAccessTest<uint16_t>(MachineType::Int16(), data, arraysize(data)); } TEST(RunAccessTests_int32) { int32_t data[] = {-211, 211, 628347, 2000000000, -2000000000, -1, -100000034}; - RunAccessTest<int32_t>(kMachInt32, data, arraysize(data)); + RunAccessTest<int32_t>(MachineType::Int32(), data, arraysize(data)); } @@ -621,13 +620,13 @@ TEST(RunAccessTests_int64) { V8_2PART_INT64(0x30313233, 34353637), V8_2PART_INT64(0xa0a1a2a3, a4a5a6a7), V8_2PART_INT64(0xf0f1f2f3, f4f5f6f7)}; - RunAccessTest<int64_t>(kMachInt64, data, arraysize(data)); + RunAccessTest<int64_t>(MachineType::Int64(), data, arraysize(data)); } TEST(RunAccessTests_float64) { double data[] = {1.25, -1.25, 2.75, 11.0, 11100.8}; - RunAccessTest<double>(kMachFloat64, data, arraysize(data)); + RunAccessTest<double>(MachineType::Float64(), data, arraysize(data)); } @@ -635,7 +634,7 @@ TEST(RunAccessTests_Smi) { Smi* data[] = {Smi::FromInt(-1), Smi::FromInt(-9), Smi::FromInt(0), Smi::FromInt(666), Smi::FromInt(77777), Smi::FromInt(Smi::kMaxValue)}; - RunAccessTest<Smi*>(kMachAnyTagged, data, arraysize(data)); + RunAccessTest<Smi*>(MachineType::AnyTagged(), data, arraysize(data)); } @@ -651,7 +650,7 @@ TEST(RunAllocate) { t.StoreField(access, alloc, map); t.Return(alloc); - t.LowerAllNodes(); + t.LowerAllNodesAndLowerChanges(); t.GenerateCode(); HeapObject* result = t.CallWithPotentialGC<HeapObject>(); @@ -682,7 +681,7 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { javascript(main_zone()), jsgraph(main_isolate(), graph(), common(), &javascript, simplified(), machine()) { - start = graph()->NewNode(common()->Start(2)); + start = graph()->NewNode(common()->Start(4)); graph()->SetStart(start); ret = graph()->NewNode(common()->Return(), jsgraph.Constant(0), start, start); @@ -723,6 +722,17 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { SimplifiedLowering(&jsgraph, jsgraph.zone(), &table).LowerAllNodes(); } + void LowerAllNodesAndLowerChanges() { + SourcePositionTable table(jsgraph.graph()); + SimplifiedLowering(&jsgraph, jsgraph.zone(), &table).LowerAllNodes(); + + ChangeLowering lowering(&jsgraph); + GraphReducer reducer(this->zone(), this->graph()); + reducer.AddReducer(&lowering); + reducer.ReduceGraph(); + Verifier::Run(this->graph()); + } + // Inserts the node as the return value of the graph. Node* Return(Node* node) { ret->ReplaceInput(0, node); @@ -733,44 +743,43 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { void Effect(Node* node) { ret->ReplaceInput(1, node); } Node* ExampleWithOutput(MachineType type) { - // TODO(titzer): use parameters with guaranteed representations. - if (type & kTypeInt32) { + if (type.semantic() == MachineSemantic::kInt32) { return graph()->NewNode(machine()->Int32Add(), jsgraph.Int32Constant(1), jsgraph.Int32Constant(1)); - } else if (type & kTypeUint32) { + } else if (type.semantic() == MachineSemantic::kUint32) { return graph()->NewNode(machine()->Word32Shr(), jsgraph.Int32Constant(1), jsgraph.Int32Constant(1)); - } else if (type & kRepFloat64) { + } else if (type.representation() == MachineRepresentation::kFloat64) { return graph()->NewNode(machine()->Float64Add(), jsgraph.Float64Constant(1), jsgraph.Float64Constant(1)); - } else if (type & kRepBit) { + } else if (type.representation() == MachineRepresentation::kBit) { return graph()->NewNode(machine()->Word32Equal(), jsgraph.Int32Constant(1), jsgraph.Int32Constant(1)); - } else if (type & kRepWord64) { + } else if (type.representation() == MachineRepresentation::kWord64) { return graph()->NewNode(machine()->Int64Add(), Int64Constant(1), Int64Constant(1)); } else { - CHECK(type & kRepTagged); + CHECK(type.representation() == MachineRepresentation::kTagged); return p0; } } Node* Use(Node* node, MachineType type) { - if (type & kTypeInt32) { + if (type.semantic() == MachineSemantic::kInt32) { return graph()->NewNode(machine()->Int32LessThan(), node, jsgraph.Int32Constant(1)); - } else if (type & kTypeUint32) { + } else if (type.semantic() == MachineSemantic::kUint32) { return graph()->NewNode(machine()->Uint32LessThan(), node, jsgraph.Int32Constant(1)); - } else if (type & kRepFloat64) { + } else if (type.representation() == MachineRepresentation::kFloat64) { return graph()->NewNode(machine()->Float64Add(), node, jsgraph.Float64Constant(1)); - } else if (type & kRepWord64) { + } else if (type.representation() == MachineRepresentation::kWord64) { return graph()->NewNode(machine()->Int64LessThan(), node, Int64Constant(1)); - } else if (type & kRepWord32) { + } else if (type.representation() == MachineRepresentation::kWord32) { return graph()->NewNode(machine()->Word32Equal(), node, jsgraph.Int32Constant(1)); } else { @@ -802,7 +811,7 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders { TEST(LowerBooleanNot_bit_bit) { // BooleanNot(x: kRepBit) used as kRepBit TestingGraph t(Type::Boolean()); - Node* b = t.ExampleWithOutput(kRepBit); + Node* b = t.ExampleWithOutput(MachineType::Bool()); Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b); Node* use = t.Branch(inv); t.Lower(); @@ -817,9 +826,9 @@ TEST(LowerBooleanNot_bit_bit) { TEST(LowerBooleanNot_bit_tagged) { // BooleanNot(x: kRepBit) used as kRepTagged TestingGraph t(Type::Boolean()); - Node* b = t.ExampleWithOutput(kRepBit); + Node* b = t.ExampleWithOutput(MachineType::Bool()); Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b); - Node* use = t.Use(inv, kRepTagged); + Node* use = t.Use(inv, MachineType::AnyTagged()); t.Return(use); t.Lower(); CHECK_EQ(IrOpcode::kChangeBitToBool, use->InputAt(0)->opcode()); @@ -851,7 +860,7 @@ TEST(LowerBooleanNot_tagged_tagged) { TestingGraph t(Type::Boolean()); Node* b = t.p0; Node* inv = t.graph()->NewNode(t.simplified()->BooleanNot(), b); - Node* use = t.Use(inv, kRepTagged); + Node* use = t.Use(inv, MachineType::AnyTagged()); t.Return(use); t.Lower(); CHECK_EQ(IrOpcode::kChangeBitToBool, use->InputAt(0)->opcode()); @@ -864,11 +873,11 @@ TEST(LowerBooleanNot_tagged_tagged) { TEST(LowerBooleanToNumber_bit_int32) { - // BooleanToNumber(x: kRepBit) used as kMachInt32 + // BooleanToNumber(x: kRepBit) used as MachineType::Int32() TestingGraph t(Type::Boolean()); - Node* b = t.ExampleWithOutput(kRepBit); + Node* b = t.ExampleWithOutput(MachineType::Bool()); Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b); - Node* use = t.Use(cnv, kMachInt32); + Node* use = t.Use(cnv, MachineType::Int32()); t.Return(use); t.Lower(); CHECK_EQ(b, use->InputAt(0)); @@ -876,11 +885,11 @@ TEST(LowerBooleanToNumber_bit_int32) { TEST(LowerBooleanToNumber_tagged_int32) { - // BooleanToNumber(x: kRepTagged) used as kMachInt32 + // BooleanToNumber(x: kRepTagged) used as MachineType::Int32() TestingGraph t(Type::Boolean()); Node* b = t.p0; Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b); - Node* use = t.Use(cnv, kMachInt32); + Node* use = t.Use(cnv, MachineType::Int32()); t.Return(use); t.Lower(); CHECK_EQ(t.machine()->WordEqual()->opcode(), cnv->opcode()); @@ -891,28 +900,28 @@ TEST(LowerBooleanToNumber_tagged_int32) { TEST(LowerBooleanToNumber_bit_tagged) { - // BooleanToNumber(x: kRepBit) used as kMachAnyTagged + // BooleanToNumber(x: kRepBit) used as MachineType::AnyTagged() TestingGraph t(Type::Boolean()); - Node* b = t.ExampleWithOutput(kRepBit); + Node* b = t.ExampleWithOutput(MachineType::Bool()); Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b); - Node* use = t.Use(cnv, kMachAnyTagged); + Node* use = t.Use(cnv, MachineType::AnyTagged()); t.Return(use); t.Lower(); CHECK_EQ(b, use->InputAt(0)->InputAt(0)); - CHECK_EQ(IrOpcode::kChangeInt32ToTagged, use->InputAt(0)->opcode()); + CHECK_EQ(IrOpcode::kChangeUint32ToTagged, use->InputAt(0)->opcode()); } TEST(LowerBooleanToNumber_tagged_tagged) { - // BooleanToNumber(x: kRepTagged) used as kMachAnyTagged + // BooleanToNumber(x: kRepTagged) used as MachineType::AnyTagged() TestingGraph t(Type::Boolean()); Node* b = t.p0; Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b); - Node* use = t.Use(cnv, kMachAnyTagged); + Node* use = t.Use(cnv, MachineType::AnyTagged()); t.Return(use); t.Lower(); CHECK_EQ(cnv, use->InputAt(0)->InputAt(0)); - CHECK_EQ(IrOpcode::kChangeInt32ToTagged, use->InputAt(0)->opcode()); + CHECK_EQ(IrOpcode::kChangeUint32ToTagged, use->InputAt(0)->opcode()); CHECK_EQ(t.machine()->WordEqual()->opcode(), cnv->opcode()); CHECK(b == cnv->InputAt(0) || b == cnv->InputAt(1)); Node* c = t.jsgraph.TrueConstant(); @@ -1034,33 +1043,11 @@ static void CheckChangeOf(IrOpcode::Value change, Node* of, Node* node) { } -TEST(LowerNumberToInt32_to_nop) { - // NumberToInt32(x: kRepTagged | kTypeInt32) used as kRepTagged - TestingGraph t(Type::Signed32()); - Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0); - Node* use = t.Use(trunc, kRepTagged); - t.Return(use); - t.Lower(); - CHECK_EQ(t.p0, use->InputAt(0)); -} - - -TEST(LowerNumberToInt32_to_ChangeTaggedToFloat64) { - // NumberToInt32(x: kRepTagged | kTypeInt32) used as kRepFloat64 - TestingGraph t(Type::Signed32()); - Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0); - Node* use = t.Use(trunc, kRepFloat64); - t.Return(use); - t.Lower(); - CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p0, use->InputAt(0)); -} - - TEST(LowerNumberToInt32_to_ChangeTaggedToInt32) { // NumberToInt32(x: kRepTagged | kTypeInt32) used as kRepWord32 TestingGraph t(Type::Signed32()); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0); - Node* use = t.Use(trunc, kTypeInt32); + Node* use = t.Use(trunc, MachineType::Int32()); t.Return(use); t.Lower(); CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p0, use->InputAt(0)); @@ -1068,11 +1055,11 @@ TEST(LowerNumberToInt32_to_ChangeTaggedToInt32) { TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32) { - // NumberToInt32(x: kRepFloat64) used as kMachInt32 + // NumberToInt32(x: kRepFloat64) used as MachineType::Int32() TestingGraph t(Type::Number()); - Node* p0 = t.ExampleWithOutput(kMachFloat64); + Node* p0 = t.ExampleWithOutput(MachineType::Float64()); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), p0); - Node* use = t.Use(trunc, kMachInt32); + Node* use = t.Use(trunc, MachineType::Int32()); t.Return(use); t.Lower(); CheckChangeOf(IrOpcode::kTruncateFloat64ToInt32, p0, use->InputAt(0)); @@ -1080,10 +1067,10 @@ TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32) { TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32_with_change) { - // NumberToInt32(x: kTypeNumber | kRepTagged) used as kMachInt32 + // NumberToInt32(x: kTypeNumber | kRepTagged) used as MachineType::Int32() TestingGraph t(Type::Number()); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), t.p0); - Node* use = t.Use(trunc, kMachInt32); + Node* use = t.Use(trunc, MachineType::Int32()); t.Return(use); t.Lower(); Node* node = use->InputAt(0); @@ -1094,33 +1081,11 @@ TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32_with_change) { } -TEST(LowerNumberToUint32_to_nop) { - // NumberToUint32(x: kRepTagged | kTypeUint32) used as kRepTagged - TestingGraph t(Type::Unsigned32()); - Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0); - Node* use = t.Use(trunc, kRepTagged); - t.Return(use); - t.Lower(); - CHECK_EQ(t.p0, use->InputAt(0)); -} - - -TEST(LowerNumberToUint32_to_ChangeTaggedToFloat64) { - // NumberToUint32(x: kRepTagged | kTypeUint32) used as kRepWord32 - TestingGraph t(Type::Unsigned32()); - Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0); - Node* use = t.Use(trunc, kRepFloat64); - t.Return(use); - t.Lower(); - CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p0, use->InputAt(0)); -} - - TEST(LowerNumberToUint32_to_ChangeTaggedToUint32) { // NumberToUint32(x: kRepTagged | kTypeUint32) used as kRepWord32 TestingGraph t(Type::Unsigned32()); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0); - Node* use = t.Use(trunc, kTypeUint32); + Node* use = t.Use(trunc, MachineType::Uint32()); t.Return(use); t.Lower(); CheckChangeOf(IrOpcode::kChangeTaggedToUint32, t.p0, use->InputAt(0)); @@ -1128,13 +1093,13 @@ TEST(LowerNumberToUint32_to_ChangeTaggedToUint32) { TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32) { - // NumberToUint32(x: kRepFloat64) used as kMachUint32 + // NumberToUint32(x: kRepFloat64) used as MachineType::Uint32() TestingGraph t(Type::Number()); - Node* p0 = t.ExampleWithOutput(kMachFloat64); + Node* p0 = t.ExampleWithOutput(MachineType::Float64()); // TODO(titzer): run the typer here, or attach machine type to param. NodeProperties::SetType(p0, Type::Number()); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), p0); - Node* use = t.Use(trunc, kMachUint32); + Node* use = t.Use(trunc, MachineType::Uint32()); t.Return(use); t.Lower(); CheckChangeOf(IrOpcode::kTruncateFloat64ToInt32, p0, use->InputAt(0)); @@ -1142,10 +1107,10 @@ TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32) { TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32_with_change) { - // NumberToInt32(x: kTypeNumber | kRepTagged) used as kMachUint32 + // NumberToInt32(x: kTypeNumber | kRepTagged) used as MachineType::Uint32() TestingGraph t(Type::Number()); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), t.p0); - Node* use = t.Use(trunc, kMachUint32); + Node* use = t.Use(trunc, MachineType::Uint32()); t.Return(use); t.Lower(); Node* node = use->InputAt(0); @@ -1159,9 +1124,9 @@ TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32_with_change) { TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32_uint32) { // NumberToUint32(x: kRepFloat64) used as kRepWord32 TestingGraph t(Type::Unsigned32()); - Node* input = t.ExampleWithOutput(kMachFloat64); + Node* input = t.ExampleWithOutput(MachineType::Float64()); Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), input); - Node* use = t.Use(trunc, kRepWord32); + Node* use = t.Use(trunc, MachineType::RepWord32()); t.Return(use); t.Lower(); CheckChangeOf(IrOpcode::kTruncateFloat64ToInt32, input, use->InputAt(0)); @@ -1192,10 +1157,11 @@ TEST(LowerStringOps_to_call_and_compare) { } -void CheckChangeInsertion(IrOpcode::Value expected, MachineType from, - MachineType to) { + void CheckChangeInsertion(IrOpcode::Value expected, MachineType from, + MachineType to, Type* type = Type::Any()) { TestingGraph t(Type::Any()); Node* in = t.ExampleWithOutput(from); + NodeProperties::SetType(in, type); Node* use = t.Use(in, to); t.Return(use); t.Lower(); @@ -1205,27 +1171,33 @@ void CheckChangeInsertion(IrOpcode::Value expected, MachineType from, TEST(InsertBasicChanges) { - CheckChangeInsertion(IrOpcode::kChangeFloat64ToInt32, kRepFloat64, - kTypeInt32); - CheckChangeInsertion(IrOpcode::kChangeFloat64ToUint32, kRepFloat64, - kTypeUint32); - CheckChangeInsertion(IrOpcode::kChangeTaggedToInt32, kRepTagged, kTypeInt32); - CheckChangeInsertion(IrOpcode::kChangeTaggedToUint32, kRepTagged, - kTypeUint32); - - CheckChangeInsertion(IrOpcode::kChangeFloat64ToTagged, kRepFloat64, - kRepTagged); - CheckChangeInsertion(IrOpcode::kChangeTaggedToFloat64, kRepTagged, - kRepFloat64); - - CheckChangeInsertion(IrOpcode::kChangeInt32ToFloat64, kTypeInt32, - kRepFloat64); - CheckChangeInsertion(IrOpcode::kChangeInt32ToTagged, kTypeInt32, kRepTagged); - - CheckChangeInsertion(IrOpcode::kChangeUint32ToFloat64, kTypeUint32, - kRepFloat64); - CheckChangeInsertion(IrOpcode::kChangeUint32ToTagged, kTypeUint32, - kRepTagged); + CheckChangeInsertion(IrOpcode::kChangeFloat64ToInt32, MachineType::Float64(), + MachineType::Int32(), Type::Signed32()); + CheckChangeInsertion(IrOpcode::kChangeFloat64ToUint32, MachineType::Float64(), + MachineType::Uint32(), Type::Unsigned32()); + CheckChangeInsertion(IrOpcode::kTruncateFloat64ToInt32, + MachineType::Float64(), MachineType::Uint32(), + Type::Integral32()); + CheckChangeInsertion(IrOpcode::kChangeTaggedToInt32, MachineType::AnyTagged(), + MachineType::Int32(), Type::Signed32()); + CheckChangeInsertion(IrOpcode::kChangeTaggedToUint32, + MachineType::AnyTagged(), MachineType::Uint32(), + Type::Unsigned32()); + + CheckChangeInsertion(IrOpcode::kChangeFloat64ToTagged, MachineType::Float64(), + MachineType::AnyTagged()); + CheckChangeInsertion(IrOpcode::kChangeTaggedToFloat64, + MachineType::AnyTagged(), MachineType::Float64()); + + CheckChangeInsertion(IrOpcode::kChangeInt32ToFloat64, MachineType::Int32(), + MachineType::Float64()); + CheckChangeInsertion(IrOpcode::kChangeInt32ToTagged, MachineType::Int32(), + MachineType::AnyTagged()); + + CheckChangeInsertion(IrOpcode::kChangeUint32ToFloat64, MachineType::Uint32(), + MachineType::Float64()); + CheckChangeInsertion(IrOpcode::kChangeUint32ToTagged, MachineType::Uint32(), + MachineType::AnyTagged()); } @@ -1338,7 +1310,8 @@ Node* CheckElementAccessArithmetic(ElementAccess access, Node* load_or_store) { CHECK_EQ(IrOpcode::kInt32Add, mindex.node()->opcode()); CHECK(mindex.right().Is(access.header_size - access.tag())); - const int element_size_shift = ElementSizeLog2Of(access.machine_type); + const int element_size_shift = + ElementSizeLog2Of(access.machine_type.representation()); if (element_size_shift) { Int32BinopMatcher shl(mindex.left().node()); CHECK_EQ(IrOpcode::kWord32Shl, shl.node()->opcode()); @@ -1350,9 +1323,10 @@ Node* CheckElementAccessArithmetic(ElementAccess access, Node* load_or_store) { } -const MachineType kMachineReps[] = {kMachInt8, kMachInt16, kMachInt32, - kMachUint32, kMachInt64, kMachFloat64, - kMachAnyTagged}; +const MachineType kMachineReps[] = { + MachineType::Int8(), MachineType::Int16(), MachineType::Int32(), + MachineType::Uint32(), MachineType::Int64(), MachineType::Float64(), + MachineType::AnyTagged()}; } // namespace @@ -1368,12 +1342,12 @@ TEST(LowerLoadField_to_load) { t.start, t.start); Node* use = t.Use(load, kMachineReps[i]); t.Return(use); - t.Lower(); + t.LowerAllNodesAndLowerChanges(); CHECK_EQ(IrOpcode::kLoad, load->opcode()); CHECK_EQ(t.p0, load->InputAt(0)); CheckFieldAccessArithmetic(access, load); - MachineType rep = OpParameter<MachineType>(load); + MachineType rep = LoadRepresentationOf(load->op()); CHECK_EQ(kMachineReps[i], rep); } } @@ -1392,16 +1366,16 @@ TEST(LowerStoreField_to_store) { Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, val, t.start, t.start); t.Effect(store); - t.Lower(); + t.LowerAllNodesAndLowerChanges(); CHECK_EQ(IrOpcode::kStore, store->opcode()); CHECK_EQ(val, store->InputAt(2)); CheckFieldAccessArithmetic(access, store); - StoreRepresentation rep = OpParameter<StoreRepresentation>(store); - if (kMachineReps[i] & kRepTagged) { + StoreRepresentation rep = StoreRepresentationOf(store->op()); + if (kMachineReps[i].representation() == MachineRepresentation::kTagged) { CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind()); } - CHECK_EQ(kMachineReps[i], rep.machine_type()); + CHECK_EQ(kMachineReps[i].representation(), rep.representation()); } } { @@ -1410,14 +1384,15 @@ TEST(LowerStoreField_to_store) { TestingGraph t(Type::Any(), Type::Intersect(Type::SignedSmall(), Type::TaggedSigned(), z)); FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, - Handle<Name>::null(), Type::Any(), kMachAnyTagged}; + Handle<Name>::null(), Type::Any(), + MachineType::AnyTagged()}; Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, t.p1, t.start, t.start); t.Effect(store); - t.Lower(); + t.LowerAllNodesAndLowerChanges(); CHECK_EQ(IrOpcode::kStore, store->opcode()); CHECK_EQ(t.p1, store->InputAt(2)); - StoreRepresentation rep = OpParameter<StoreRepresentation>(store); + StoreRepresentation rep = StoreRepresentationOf(store->op()); CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); } } @@ -1434,12 +1409,12 @@ TEST(LowerLoadElement_to_load) { t.p1, t.start, t.start); Node* use = t.Use(load, kMachineReps[i]); t.Return(use); - t.Lower(); + t.LowerAllNodesAndLowerChanges(); CHECK_EQ(IrOpcode::kLoad, load->opcode()); CHECK_EQ(t.p0, load->InputAt(0)); CheckElementAccessArithmetic(access, load); - MachineType rep = OpParameter<MachineType>(load); + MachineType rep = LoadRepresentationOf(load->op()); CHECK_EQ(kMachineReps[i], rep); } } @@ -1457,16 +1432,16 @@ TEST(LowerStoreElement_to_store) { Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1, val, t.start, t.start); t.Effect(store); - t.Lower(); + t.LowerAllNodesAndLowerChanges(); CHECK_EQ(IrOpcode::kStore, store->opcode()); CHECK_EQ(val, store->InputAt(2)); CheckElementAccessArithmetic(access, store); - StoreRepresentation rep = OpParameter<StoreRepresentation>(store); - if (kMachineReps[i] & kRepTagged) { + StoreRepresentation rep = StoreRepresentationOf(store->op()); + if (kMachineReps[i].representation() == MachineRepresentation::kTagged) { CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind()); } - CHECK_EQ(kMachineReps[i], rep.machine_type()); + CHECK_EQ(kMachineReps[i].representation(), rep.representation()); } } { @@ -1476,14 +1451,14 @@ TEST(LowerStoreElement_to_store) { Type::Any(), Type::Signed32(), Type::Intersect(Type::SignedSmall(), Type::TaggedSigned(), z)); ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, - Type::Any(), kMachAnyTagged}; + Type::Any(), MachineType::AnyTagged()}; Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1, t.p2, t.start, t.start); t.Effect(store); - t.Lower(); + t.LowerAllNodesAndLowerChanges(); CHECK_EQ(IrOpcode::kStore, store->opcode()); CHECK_EQ(t.p2, store->InputAt(2)); - StoreRepresentation rep = OpParameter<StoreRepresentation>(store); + StoreRepresentation rep = StoreRepresentationOf(store->op()); CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); } } @@ -1494,17 +1469,15 @@ TEST(InsertChangeForLoadElementIndex) { // Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k)) TestingGraph t(Type::Any(), Type::Signed32()); ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), - kMachAnyTagged}; + MachineType::AnyTagged()}; Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, t.p1, t.start, t.start); t.Return(load); t.Lower(); - CHECK_EQ(IrOpcode::kLoad, load->opcode()); + CHECK_EQ(IrOpcode::kLoadElement, load->opcode()); CHECK_EQ(t.p0, load->InputAt(0)); - - Node* index = CheckElementAccessArithmetic(access, load); - CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index); + CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, load->InputAt(1)); } @@ -1513,18 +1486,16 @@ TEST(InsertChangeForStoreElementIndex) { // Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k), val) TestingGraph t(Type::Any(), Type::Signed32()); ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), - kMachAnyTagged}; + MachineType::AnyTagged()}; Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1, t.jsgraph.TrueConstant(), t.start, t.start); t.Effect(store); t.Lower(); - CHECK_EQ(IrOpcode::kStore, store->opcode()); + CHECK_EQ(IrOpcode::kStoreElement, store->opcode()); CHECK_EQ(t.p0, store->InputAt(0)); - - Node* index = CheckElementAccessArithmetic(access, store); - CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index); + CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, store->InputAt(1)); } @@ -1532,13 +1503,13 @@ TEST(InsertChangeForLoadElement) { // TODO(titzer): test all load/store representation change insertions. TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), - kMachFloat64}; + MachineType::Float64()}; Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, t.p1, t.start, t.start); t.Return(load); t.Lower(); - CHECK_EQ(IrOpcode::kLoad, load->opcode()); + CHECK_EQ(IrOpcode::kLoadElement, load->opcode()); CHECK_EQ(t.p0, load->InputAt(0)); CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); } @@ -1548,13 +1519,14 @@ TEST(InsertChangeForLoadField) { // TODO(titzer): test all load/store representation change insertions. TestingGraph t(Type::Any(), Type::Signed32()); FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, - Handle<Name>::null(), Type::Any(), kMachFloat64}; + Handle<Name>::null(), Type::Any(), + MachineType::Float64()}; Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start, t.start); t.Return(load); t.Lower(); - CHECK_EQ(IrOpcode::kLoad, load->opcode()); + CHECK_EQ(IrOpcode::kLoadField, load->opcode()); CHECK_EQ(t.p0, load->InputAt(0)); CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); } @@ -1564,7 +1536,7 @@ TEST(InsertChangeForStoreElement) { // TODO(titzer): test all load/store representation change insertions. TestingGraph t(Type::Any(), Type::Signed32()); ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), - kMachFloat64}; + MachineType::Float64()}; Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, @@ -1572,7 +1544,7 @@ TEST(InsertChangeForStoreElement) { t.Effect(store); t.Lower(); - CHECK_EQ(IrOpcode::kStore, store->opcode()); + CHECK_EQ(IrOpcode::kStoreElement, store->opcode()); CHECK_EQ(t.p0, store->InputAt(0)); CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); } @@ -1582,23 +1554,24 @@ TEST(InsertChangeForStoreField) { // TODO(titzer): test all load/store representation change insertions. TestingGraph t(Type::Any(), Type::Signed32()); FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, - Handle<Name>::null(), Type::Any(), kMachFloat64}; + Handle<Name>::null(), Type::Any(), + MachineType::Float64()}; Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, t.p1, t.start, t.start); t.Effect(store); t.Lower(); - CHECK_EQ(IrOpcode::kStore, store->opcode()); + CHECK_EQ(IrOpcode::kStoreField, store->opcode()); CHECK_EQ(t.p0, store->InputAt(0)); - CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); + CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(1)); } TEST(UpdatePhi) { TestingGraph t(Type::Any(), Type::Signed32()); - static const MachineType kMachineTypes[] = {kMachInt32, kMachUint32, - kMachFloat64}; + static const MachineType kMachineTypes[] = { + MachineType::Int32(), MachineType::Uint32(), MachineType::Float64()}; Type* kTypes[] = {Type::Signed32(), Type::Unsigned32(), Type::Number()}; for (size_t i = 0; i < arraysize(kMachineTypes); i++) { @@ -1609,47 +1582,31 @@ TEST(UpdatePhi) { t.start, t.start); Node* load1 = t.graph()->NewNode(t.simplified()->LoadField(access), t.p1, t.start, t.start); - Node* phi = t.graph()->NewNode(t.common()->Phi(kMachAnyTagged, 2), load0, - load1, t.start); + Node* phi = + t.graph()->NewNode(t.common()->Phi(MachineRepresentation::kTagged, 2), + load0, load1, t.start); t.Return(t.Use(phi, kMachineTypes[i])); t.Lower(); CHECK_EQ(IrOpcode::kPhi, phi->opcode()); - CHECK_EQ(RepresentationOf(kMachineTypes[i]), - RepresentationOf(OpParameter<MachineType>(phi))); + CHECK_EQ(kMachineTypes[i].representation(), PhiRepresentationOf(phi->op())); } } TEST(RunNumberDivide_minus_1_TruncatingToInt32) { - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); Node* num = t.NumberToInt32(t.Parameter(0)); Node* div = t.NumberDivide(num, t.jsgraph.Constant(-1)); Node* trunc = t.NumberToInt32(div); t.Return(trunc); - t.LowerAllNodesAndLowerChanges(); - t.GenerateCode(); - - FOR_INT32_INPUTS(i) { - int32_t x = 0 - *i; - t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); - } -} - - -TEST(NumberMultiply_TruncatingToInt32) { - int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000}; - - for (size_t i = 0; i < arraysize(constants); i++) { - TestingGraph t(Type::Signed32()); - Node* k = t.jsgraph.Constant(constants[i]); - Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k); - Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mul); - t.Return(trunc); - t.Lower(); + t.LowerAllNodesAndLowerChanges(); + t.GenerateCode(); - CHECK_EQ(IrOpcode::kInt32Mul, mul->opcode()); + FOR_INT32_INPUTS(i) { + int32_t x = 0 - *i; + t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); } } @@ -1659,7 +1616,7 @@ TEST(RunNumberMultiply_TruncatingToInt32) { for (size_t i = 0; i < arraysize(constants); i++) { double k = static_cast<double>(constants[i]); - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); Node* num = t.NumberToInt32(t.Parameter(0)); Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k)); Node* trunc = t.NumberToInt32(mul); @@ -1681,7 +1638,7 @@ TEST(RunNumberMultiply_TruncatingToUint32) { for (size_t i = 0; i < arraysize(constants); i++) { double k = static_cast<double>(constants[i]); - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); Node* num = t.NumberToUint32(t.Parameter(0)); Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k)); Node* trunc = t.NumberToUint32(mul); @@ -1699,7 +1656,7 @@ TEST(RunNumberMultiply_TruncatingToUint32) { TEST(RunNumberDivide_2_TruncatingToUint32) { - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); Node* num = t.NumberToUint32(t.Parameter(0)); Node* div = t.NumberDivide(num, t.jsgraph.Constant(2)); Node* trunc = t.NumberToUint32(div); @@ -1745,7 +1702,7 @@ TEST(NumberDivide_TruncatingToInt32) { TestingGraph t(Type::Signed32()); Node* k = t.jsgraph.Constant(constants[i]); Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); - Node* use = t.Use(div, kMachInt32); + Node* use = t.Use(div, MachineType::Int32()); t.Return(use); t.Lower(); @@ -1759,7 +1716,7 @@ TEST(RunNumberDivide_TruncatingToInt32) { for (size_t i = 0; i < arraysize(constants); i++) { int32_t k = constants[i]; - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); Node* num = t.NumberToInt32(t.Parameter(0)); Node* div = t.NumberDivide(num, t.jsgraph.Constant(k)); Node* trunc = t.NumberToInt32(div); @@ -1784,7 +1741,7 @@ TEST(NumberDivide_TruncatingToUint32) { TestingGraph t(Type::Unsigned32()); Node* k = t.jsgraph.Constant(constants[i]); Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); - Node* use = t.Use(div, kMachUint32); + Node* use = t.Use(div, MachineType::Uint32()); t.Return(use); t.Lower(); @@ -1798,7 +1755,7 @@ TEST(RunNumberDivide_TruncatingToUint32) { for (size_t i = 0; i < arraysize(constants); i++) { uint32_t k = constants[i]; - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); Node* num = t.NumberToUint32(t.Parameter(0)); Node* div = t.NumberDivide(num, t.jsgraph.Constant(static_cast<double>(k))); Node* trunc = t.NumberToUint32(div); @@ -1820,7 +1777,7 @@ TEST(NumberDivide_BadConstants) { TestingGraph t(Type::Signed32()); Node* k = t.jsgraph.Constant(-1); Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); - Node* use = t.Use(div, kMachInt32); + Node* use = t.Use(div, MachineType::Int32()); t.Return(use); t.Lower(); @@ -1831,7 +1788,7 @@ TEST(NumberDivide_BadConstants) { TestingGraph t(Type::Signed32()); Node* k = t.jsgraph.Constant(0); Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); - Node* use = t.Use(div, kMachInt32); + Node* use = t.Use(div, MachineType::Int32()); t.Return(use); t.Lower(); @@ -1843,7 +1800,7 @@ TEST(NumberDivide_BadConstants) { TestingGraph t(Type::Unsigned32()); Node* k = t.jsgraph.Constant(0); Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k); - Node* use = t.Use(div, kMachUint32); + Node* use = t.Use(div, MachineType::Uint32()); t.Return(use); t.Lower(); @@ -1860,7 +1817,7 @@ TEST(NumberModulus_TruncatingToInt32) { TestingGraph t(Type::Signed32()); Node* k = t.jsgraph.Constant(constants[i]); Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k); - Node* use = t.Use(mod, kMachInt32); + Node* use = t.Use(mod, MachineType::Int32()); t.Return(use); t.Lower(); @@ -1874,7 +1831,7 @@ TEST(RunNumberModulus_TruncatingToInt32) { for (size_t i = 0; i < arraysize(constants); i++) { int32_t k = constants[i]; - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); Node* num = t.NumberToInt32(t.Parameter(0)); Node* mod = t.NumberModulus(num, t.jsgraph.Constant(k)); Node* trunc = t.NumberToInt32(mod); @@ -1913,7 +1870,7 @@ TEST(RunNumberModulus_TruncatingToUint32) { for (size_t i = 0; i < arraysize(constants); i++) { uint32_t k = constants[i]; - SimplifiedLoweringTester<Object*> t(kMachAnyTagged); + SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); Node* num = t.NumberToUint32(t.Parameter(0)); Node* mod = t.NumberModulus(num, t.jsgraph.Constant(static_cast<double>(k))); @@ -1948,7 +1905,7 @@ TEST(NumberModulus_Int32) { TEST(NumberModulus_Uint32) { const double kConstants[] = {2, 100, 1000, 1024, 2048}; - const MachineType kTypes[] = {kMachInt32, kMachUint32}; + const MachineType kTypes[] = {MachineType::Int32(), MachineType::Uint32()}; for (auto const type : kTypes) { for (auto const c : kConstants) { @@ -1973,18 +1930,20 @@ TEST(PhiRepresentation) { Type* arg1; Type* arg2; MachineType use; - MachineTypeUnion expected; + MachineRepresentation expected; }; TestData test_data[] = { - {Type::Signed32(), Type::Unsigned32(), kMachInt32, - kRepWord32 | kTypeNumber}, - {Type::Signed32(), Type::Unsigned32(), kMachUint32, - kRepWord32 | kTypeNumber}, - {Type::Signed32(), Type::Signed32(), kMachInt32, kMachInt32}, - {Type::Unsigned32(), Type::Unsigned32(), kMachInt32, kMachUint32}, - {Type::Number(), Type::Signed32(), kMachInt32, kMachFloat64}, - {Type::Signed32(), Type::String(), kMachInt32, kMachAnyTagged}}; + {Type::Signed32(), Type::Unsigned32(), MachineType::Int32(), + MachineRepresentation::kWord32}, + {Type::Signed32(), Type::Unsigned32(), MachineType::Uint32(), + MachineRepresentation::kWord32}, + {Type::Signed32(), Type::Signed32(), MachineType::Int32(), + MachineRepresentation::kWord32}, + {Type::Unsigned32(), Type::Unsigned32(), MachineType::Int32(), + MachineRepresentation::kWord32}, + {Type::Number(), Type::Signed32(), MachineType::Int32(), + MachineRepresentation::kWord32}}; for (auto const d : test_data) { TestingGraph t(d.arg1, d.arg2, Type::Boolean()); @@ -1994,8 +1953,8 @@ TEST(PhiRepresentation) { Node* fb = t.graph()->NewNode(t.common()->IfFalse(), br); Node* m = t.graph()->NewNode(t.common()->Merge(2), tb, fb); - Node* phi = - t.graph()->NewNode(t.common()->Phi(kMachAnyTagged, 2), t.p0, t.p1, m); + Node* phi = t.graph()->NewNode( + t.common()->Phi(MachineRepresentation::kTagged, 2), t.p0, t.p1, m); Type* phi_type = Type::Union(d.arg1, d.arg2, z); NodeProperties::SetType(phi, phi_type); @@ -2004,7 +1963,7 @@ TEST(PhiRepresentation) { t.Return(use); t.Lower(); - CHECK_EQ(d.expected, OpParameter<MachineType>(phi)); + CHECK_EQ(d.expected, PhiRepresentationOf(phi->op())); } } diff --git a/deps/v8/test/cctest/compiler/value-helper.h b/deps/v8/test/cctest/compiler/value-helper.h index 20be67a975..cbde9a7417 100644 --- a/deps/v8/test/cctest/compiler/value-helper.h +++ b/deps/v8/test/cctest/compiler/value-helper.h @@ -5,6 +5,8 @@ #ifndef V8_CCTEST_COMPILER_VALUE_HELPER_H_ #define V8_CCTEST_COMPILER_VALUE_HELPER_H_ +#include <stdint.h> + #include "src/compiler/common-operator.h" #include "src/compiler/node.h" #include "src/compiler/node-matchers.h" @@ -59,53 +61,164 @@ class ValueHelper { } static std::vector<float> float32_vector() { + static const float nan = std::numeric_limits<float>::quiet_NaN(); static const float kValues[] = { - -std::numeric_limits<float>::infinity(), -2.70497e+38f, -1.4698e+37f, - -1.22813e+35f, -1.20555e+35f, -1.34584e+34f, - -1.0079e+32f, -6.49364e+26f, -3.06077e+25f, - -1.46821e+25f, -1.17658e+23f, -1.9617e+22f, - -2.7357e+20f, -1.48708e+13f, -1.89633e+12f, - -4.66622e+11f, -2.22581e+11f, -1.45381e+10f, - -1.3956e+09f, -1.32951e+09f, -1.30721e+09f, - -1.19756e+09f, -9.26822e+08f, -6.35647e+08f, - -4.00037e+08f, -1.81227e+08f, -5.09256e+07f, - -964300.0f, -192446.0f, -28455.0f, - -27194.0f, -26401.0f, -20575.0f, - -17069.0f, -9167.0f, -960.178f, - -113.0f, -62.0f, -15.0f, - -7.0f, -0.0256635f, -4.60374e-07f, - -3.63759e-10f, -4.30175e-14f, -5.27385e-15f, - -1.48084e-15f, -1.05755e-19f, -3.2995e-21f, - -1.67354e-23f, -1.11885e-23f, -1.78506e-30f, - -5.07594e-31f, -3.65799e-31f, -1.43718e-34f, - -1.27126e-38f, -0.0f, 0.0f, - 1.17549e-38f, 1.56657e-37f, 4.08512e-29f, - 3.31357e-28f, 6.25073e-22f, 4.1723e-13f, - 1.44343e-09f, 5.27004e-08f, 9.48298e-08f, - 5.57888e-07f, 4.89988e-05f, 0.244326f, - 12.4895f, 19.0f, 47.0f, - 106.0f, 538.324f, 564.536f, - 819.124f, 7048.0f, 12611.0f, - 19878.0f, 20309.0f, 797056.0f, - 1.77219e+09f, 1.51116e+11f, 4.18193e+13f, - 3.59167e+16f, 3.38211e+19f, 2.67488e+20f, - 1.78831e+21f, 9.20914e+21f, 8.35654e+23f, - 1.4495e+24f, 5.94015e+25f, 4.43608e+30f, - 2.44502e+33f, 2.61152e+33f, 1.38178e+37f, - 1.71306e+37f, 3.31899e+38f, 3.40282e+38f, - std::numeric_limits<float>::infinity()}; + -std::numeric_limits<float>::infinity(), + -2.70497e+38f, + -1.4698e+37f, + -1.22813e+35f, + -1.20555e+35f, + -1.34584e+34f, + -1.0079e+32f, + -6.49364e+26f, + -3.06077e+25f, + -1.46821e+25f, + -1.17658e+23f, + -1.9617e+22f, + -2.7357e+20f, + -9223372036854775808.0f, // INT64_MIN + -1.48708e+13f, + -1.89633e+12f, + -4.66622e+11f, + -2.22581e+11f, + -1.45381e+10f, + -1.3956e+09f, + -1.32951e+09f, + -1.30721e+09f, + -1.19756e+09f, + -9.26822e+08f, + -6.35647e+08f, + -4.00037e+08f, + -1.81227e+08f, + -5.09256e+07f, + -964300.0f, + -192446.0f, + -28455.0f, + -27194.0f, + -26401.0f, + -20575.0f, + -17069.0f, + -9167.0f, + -960.178f, + -113.0f, + -62.0f, + -15.0f, + -7.0f, + -1.0f, + -0.0256635f, + -4.60374e-07f, + -3.63759e-10f, + -4.30175e-14f, + -5.27385e-15f, + -1.48084e-15f, + -1.05755e-19f, + -3.2995e-21f, + -1.67354e-23f, + -1.11885e-23f, + -1.78506e-30f, + -5.07594e-31f, + -3.65799e-31f, + -1.43718e-34f, + -1.27126e-38f, + -0.0f, + 0.0f, + 1.17549e-38f, + 1.56657e-37f, + 4.08512e-29f, + 3.31357e-28f, + 6.25073e-22f, + 4.1723e-13f, + 1.44343e-09f, + 5.27004e-08f, + 9.48298e-08f, + 5.57888e-07f, + 4.89988e-05f, + 0.244326f, + 1.0f, + 12.4895f, + 19.0f, + 47.0f, + 106.0f, + 538.324f, + 564.536f, + 819.124f, + 7048.0f, + 12611.0f, + 19878.0f, + 20309.0f, + 797056.0f, + 1.77219e+09f, + 1.51116e+11f, + 4.18193e+13f, + 3.59167e+16f, + 9223372036854775807.0f, // INT64_MAX + 18446744073709551615.0f, // UINT64_MAX + 3.38211e+19f, + 2.67488e+20f, + 1.78831e+21f, + 9.20914e+21f, + 8.35654e+23f, + 1.4495e+24f, + 5.94015e+25f, + 4.43608e+30f, + 2.44502e+33f, + 2.61152e+33f, + 1.38178e+37f, + 1.71306e+37f, + 3.31899e+38f, + 3.40282e+38f, + std::numeric_limits<float>::infinity(), + nan, + -nan, + }; return std::vector<float>(&kValues[0], &kValues[arraysize(kValues)]); } static std::vector<double> float64_vector() { static const double nan = std::numeric_limits<double>::quiet_NaN(); - static const double values[] = { - 0.125, 0.25, 0.375, 0.5, 1.25, -1.75, 2, 5.125, 6.25, 0.0, -0.0, - 982983.25, 888, 2147483647.0, -999.75, 3.1e7, -2e66, 3e-88, - -2147483648.0, V8_INFINITY, -V8_INFINITY, -nan, nan, 2147483647.375, - 2147483647.75, 2147483648.0, 2147483648.25, 2147483649.25, - -2147483647.0, -2147483647.125, -2147483647.875, -2147483648.25, - -2147483649.5}; + static const double values[] = {-2e66, + -9223373136366403584.0, + -9223372036854775808.0, // INT64_MIN + -2147483649.5, + -2147483648.25, + -2147483648.0, + -2147483647.875, + -2147483647.125, + -2147483647.0, + -999.75, + -2e66, + -1.75, + -1.0, + -0.5, + -0.0, + 0.0, + 3e-88, + 0.125, + 0.25, + 0.375, + 0.5, + 1.0, + 1.25, + 2, + 3.1e7, + 5.125, + 6.25, + 888, + 982983.25, + 2147483647.0, + 2147483647.375, + 2147483647.75, + 2147483648.0, + 2147483648.25, + 2147483649.25, + 9223372036854775807.0, // INT64_MAX + 9223373136366403584.0, + 18446744073709551615.0, // UINT64_MAX + 2e66, + V8_INFINITY, + -V8_INFINITY, + -nan, + nan}; return std::vector<double>(&values[0], &values[arraysize(values)]); } @@ -159,7 +272,9 @@ class ValueHelper { 0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff, 0x00003fffffffffff, 0x00001fffffffffff, 0x00000fffffffffff, - 0x000007ffffffffff, 0x000003ffffffffff, 0x000001ffffffffff}; + 0x000007ffffffffff, 0x000003ffffffffff, 0x000001ffffffffff, + 0x8000008000000000, 0x8000008000000001, 0x8000000000000400, + 0x8000000000000401}; return std::vector<uint64_t>(&kValues[0], &kValues[arraysize(kValues)]); } diff --git a/deps/v8/test/cctest/expression-type-collector-macros.h b/deps/v8/test/cctest/expression-type-collector-macros.h index 0b739f40b7..68d69481d9 100644 --- a/deps/v8/test/cctest/expression-type-collector-macros.h +++ b/deps/v8/test/cctest/expression-type-collector-macros.h @@ -14,11 +14,30 @@ CHECK_EQ(index, types.size()); \ } +#ifdef DEBUG +#define CHECK_TYPE(type) \ + if (!types[index].bounds.Narrows(type)) { \ + fprintf(stderr, "Expected:\n"); \ + fprintf(stderr, " lower: "); \ + type.lower->Print(); \ + fprintf(stderr, " upper: "); \ + type.upper->Print(); \ + fprintf(stderr, "Actual:\n"); \ + fprintf(stderr, " lower: "); \ + types[index].bounds.lower->Print(); \ + fprintf(stderr, " upper: "); \ + types[index].bounds.upper->Print(); \ + } \ + CHECK(types[index].bounds.Narrows(type)); +#else +#define CHECK_TYPE(type) CHECK(types[index].bounds.Narrows(type)); +#endif + #define CHECK_EXPR(ekind, type) \ CHECK_LT(index, types.size()); \ CHECK(strcmp(#ekind, types[index].kind) == 0); \ CHECK_EQ(depth, types[index].depth); \ - CHECK(types[index].bounds.Narrows(type)); \ + CHECK_TYPE(type); \ for (int j = (++depth, ++index, 0); j < 1 ? 1 : (--depth, 0); ++j) #define CHECK_VAR(vname, type) \ diff --git a/deps/v8/test/cctest/expression-type-collector.cc b/deps/v8/test/cctest/expression-type-collector.cc index bf2d10f306..c5218b3ec4 100644 --- a/deps/v8/test/cctest/expression-type-collector.cc +++ b/deps/v8/test/cctest/expression-type-collector.cc @@ -6,9 +6,9 @@ #include "test/cctest/expression-type-collector.h" -#include "src/ast.h" +#include "src/ast/ast.h" +#include "src/ast/scopes.h" #include "src/codegen.h" -#include "src/scopes.h" namespace v8 { namespace internal { diff --git a/deps/v8/test/cctest/expression-type-collector.h b/deps/v8/test/cctest/expression-type-collector.h index dab1f010cd..37bb9a3c02 100644 --- a/deps/v8/test/cctest/expression-type-collector.h +++ b/deps/v8/test/cctest/expression-type-collector.h @@ -5,7 +5,7 @@ #ifndef V8_EXPRESSION_TYPE_COLLECTOR_H_ #define V8_EXPRESSION_TYPE_COLLECTOR_H_ -#include "src/ast-expression-visitor.h" +#include "src/ast/ast-expression-visitor.h" namespace v8 { namespace internal { diff --git a/deps/v8/test/cctest/heap-tester.h b/deps/v8/test/cctest/heap/heap-tester.h index bb26b5a775..0a0860bcc4 100644 --- a/deps/v8/test/cctest/heap-tester.h +++ b/deps/v8/test/cctest/heap/heap-tester.h @@ -2,28 +2,32 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef HEAP_TESTER_H_ -#define HEAP_TESTER_H_ +#ifndef HEAP_HEAP_TESTER_H_ +#define HEAP_HEAP_TESTER_H_ #include "src/handles.h" #include "src/heap/spaces.h" // 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(CompactionSpaceDivideMultiplePages) \ - V(CompactionSpaceDivideSinglePage) \ - V(GCFlags) \ - V(MarkCompactCollector) \ - V(NoPromotion) \ - V(NumberStringCacheSize) \ - V(ObjectGroups) \ - V(Promotion) \ - V(Regression39128) \ - V(ResetWeakHandle) \ - V(StressHandles) \ - V(TestMemoryReducerSampleJsCalls) \ - V(TestSizeOfObjects) \ +#define HEAP_TEST_METHODS(V) \ + V(CompactionFullAbortedPage) \ + V(CompactionPartiallyAbortedPage) \ + V(CompactionPartiallyAbortedPageIntraAbortedPointers) \ + V(CompactionPartiallyAbortedPageWithStoreBufferEntries) \ + V(CompactionSpaceDivideMultiplePages) \ + V(CompactionSpaceDivideSinglePage) \ + V(GCFlags) \ + V(MarkCompactCollector) \ + V(NoPromotion) \ + V(NumberStringCacheSize) \ + V(ObjectGroups) \ + V(Promotion) \ + V(Regression39128) \ + V(ResetWeakHandle) \ + V(StressHandles) \ + V(TestMemoryReducerSampleJsCalls) \ + V(TestSizeOfObjects) \ V(WriteBarriersInCopyJSObject) @@ -79,4 +83,4 @@ class HeapTester { } // namespace internal } // namespace v8 -#endif // HEAP_TESTER_H_ +#endif // HEAP_HEAP_TESTER_H_ diff --git a/deps/v8/test/cctest/test-alloc.cc b/deps/v8/test/cctest/heap/test-alloc.cc index 864eb12b6a..1b969b21ff 100644 --- a/deps/v8/test/cctest/test-alloc.cc +++ b/deps/v8/test/cctest/heap/test-alloc.cc @@ -25,16 +25,13 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "test/cctest/cctest.h" #include "src/accessors.h" #include "src/api.h" -#include "test/cctest/heap-tester.h" - +#include "test/cctest/heap/heap-tester.h" +#include "test/cctest/heap/utils-inl.h" using namespace v8::internal; @@ -66,7 +63,7 @@ AllocationResult v8::internal::HeapTester::AllocateAfterFailures() { static const int kLargeObjectSpaceFillerLength = 3 * (Page::kPageSize / 10); static const int kLargeObjectSpaceFillerSize = FixedArray::SizeFor( kLargeObjectSpaceFillerLength); - DCHECK(kLargeObjectSpaceFillerSize > heap->old_space()->AreaSize()); + CHECK(kLargeObjectSpaceFillerSize > heap->old_space()->AreaSize()); while (heap->OldGenerationSpaceAvailable() > kLargeObjectSpaceFillerSize) { heap->AllocateFixedArray( kLargeObjectSpaceFillerLength, TENURED).ToObjectChecked(); @@ -152,9 +149,9 @@ TEST(StressJS) { // Patch the map to have an accessor for "get". Handle<Map> map(function->initial_map()); Handle<DescriptorArray> instance_descriptors(map->instance_descriptors()); - DCHECK(instance_descriptors->IsEmpty()); + CHECK(instance_descriptors->IsEmpty()); - PropertyAttributes attrs = static_cast<PropertyAttributes>(0); + PropertyAttributes attrs = NONE; Handle<AccessorInfo> foreign = TestAccessorInfo(isolate, attrs); Map::EnsureDescriptorSlack(map, 1); diff --git a/deps/v8/test/cctest/heap/test-compaction.cc b/deps/v8/test/cctest/heap/test-compaction.cc new file mode 100644 index 0000000000..064e5a82c0 --- /dev/null +++ b/deps/v8/test/cctest/heap/test-compaction.cc @@ -0,0 +1,340 @@ +// 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/cctest/cctest.h" +#include "test/cctest/heap/heap-tester.h" +#include "test/cctest/heap/utils-inl.h" + +namespace v8 { +namespace internal { + +static void CheckInvariantsOfAbortedPage(Page* page) { + // Check invariants: + // 1) Markbits are cleared + // 2) The page is not marked as evacuation candidate anymore + // 3) The page is not marked as aborted compaction anymore. + CHECK(page->markbits()->IsClean()); + CHECK(!page->IsEvacuationCandidate()); + CHECK(!page->IsFlagSet(Page::COMPACTION_WAS_ABORTED)); +} + + +HEAP_TEST(CompactionFullAbortedPage) { + // Test the scenario where we reach OOM during compaction and the whole page + // is aborted. + + // Disable concurrent sweeping to ensure memory is in an expected state, i.e., + // we can reach the state of a half aborted page. + FLAG_concurrent_sweeping = false; + FLAG_manual_evacuation_candidates_selection = true; + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + { + HandleScope scope1(isolate); + PageIterator it(heap->old_space()); + while (it.has_next()) { + it.next()->SetFlag(Page::NEVER_ALLOCATE_ON_PAGE); + } + + { + HandleScope scope2(isolate); + CHECK(heap->old_space()->Expand()); + auto compaction_page_handles = + CreatePadding(heap, Page::kAllocatableMemory, TENURED); + Page* to_be_aborted_page = + Page::FromAddress(compaction_page_handles.front()->address()); + to_be_aborted_page->SetFlag( + MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING); + + heap->set_force_oom(true); + heap->CollectAllGarbage(); + + // Check that all handles still point to the same page, i.e., compaction + // has been aborted on the page. + for (Handle<FixedArray> object : compaction_page_handles) { + CHECK_EQ(to_be_aborted_page, Page::FromAddress(object->address())); + } + CheckInvariantsOfAbortedPage(to_be_aborted_page); + } + } +} + + +HEAP_TEST(CompactionPartiallyAbortedPage) { + // Test the scenario where we reach OOM during compaction and parts of the + // page have already been migrated to a new one. + + // Disable concurrent sweeping to ensure memory is in an expected state, i.e., + // we can reach the state of a half aborted page. + FLAG_concurrent_sweeping = false; + FLAG_manual_evacuation_candidates_selection = true; + + const int object_size = 128 * KB; + + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + { + HandleScope scope1(isolate); + PageIterator it(heap->old_space()); + while (it.has_next()) { + it.next()->SetFlag(Page::NEVER_ALLOCATE_ON_PAGE); + } + + { + HandleScope scope2(isolate); + // Fill another page with objects of size {object_size} (last one is + // properly adjusted). + CHECK(heap->old_space()->Expand()); + auto compaction_page_handles = + CreatePadding(heap, Page::kAllocatableMemory, TENURED, object_size); + Page* to_be_aborted_page = + Page::FromAddress(compaction_page_handles.front()->address()); + to_be_aborted_page->SetFlag( + MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING); + + { + // Add another page that is filled with {num_objects} objects of size + // {object_size}. + HandleScope scope3(isolate); + CHECK(heap->old_space()->Expand()); + const int num_objects = 3; + std::vector<Handle<FixedArray>> page_to_fill_handles = CreatePadding( + heap, object_size * num_objects, TENURED, object_size); + Page* page_to_fill = + Page::FromAddress(page_to_fill_handles.front()->address()); + + heap->set_force_oom(true); + heap->CollectAllGarbage(); + + bool migration_aborted = false; + for (Handle<FixedArray> object : compaction_page_handles) { + // Once compaction has been aborted, all following objects still have + // to be on the initial page. + CHECK(!migration_aborted || + (Page::FromAddress(object->address()) == to_be_aborted_page)); + if (Page::FromAddress(object->address()) == to_be_aborted_page) { + // This object has not been migrated. + migration_aborted = true; + } else { + CHECK_EQ(Page::FromAddress(object->address()), page_to_fill); + } + } + // Check that we actually created a scenario with a partially aborted + // page. + CHECK(migration_aborted); + CheckInvariantsOfAbortedPage(to_be_aborted_page); + } + } + } +} + + +HEAP_TEST(CompactionPartiallyAbortedPageIntraAbortedPointers) { + // Test the scenario where we reach OOM during compaction and parts of the + // page have already been migrated to a new one. Objects on the aborted page + // are linked together. This test makes sure that intra-aborted page pointers + // get properly updated. + + // Disable concurrent sweeping to ensure memory is in an expected state, i.e., + // we can reach the state of a half aborted page. + FLAG_concurrent_sweeping = false; + FLAG_manual_evacuation_candidates_selection = true; + + const int object_size = 128 * KB; + + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + { + HandleScope scope1(isolate); + Handle<FixedArray> root_array = + isolate->factory()->NewFixedArray(10, TENURED); + + PageIterator it(heap->old_space()); + while (it.has_next()) { + it.next()->SetFlag(Page::NEVER_ALLOCATE_ON_PAGE); + } + + Page* to_be_aborted_page = nullptr; + { + HandleScope temporary_scope(isolate); + // Fill a fresh page with objects of size {object_size} (last one is + // properly adjusted). + CHECK(heap->old_space()->Expand()); + std::vector<Handle<FixedArray>> compaction_page_handles = + CreatePadding(heap, Page::kAllocatableMemory, TENURED, object_size); + to_be_aborted_page = + Page::FromAddress(compaction_page_handles.front()->address()); + to_be_aborted_page->SetFlag( + MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING); + for (size_t i = compaction_page_handles.size() - 1; i > 0; i--) { + compaction_page_handles[i]->set(0, *compaction_page_handles[i - 1]); + } + root_array->set(0, *compaction_page_handles.back()); + } + + { + // Add another page that is filled with {num_objects} objects of size + // {object_size}. + HandleScope scope3(isolate); + CHECK(heap->old_space()->Expand()); + const int num_objects = 2; + int used_memory = object_size * num_objects; + std::vector<Handle<FixedArray>> page_to_fill_handles = + CreatePadding(heap, used_memory, TENURED, object_size); + Page* page_to_fill = + Page::FromAddress(page_to_fill_handles.front()->address()); + + heap->set_force_oom(true); + heap->CollectAllGarbage(); + + // The following check makes sure that we compacted "some" objects, while + // leaving others in place. + bool in_place = true; + Handle<FixedArray> current = root_array; + while (current->get(0) != heap->undefined_value()) { + current = Handle<FixedArray>(FixedArray::cast(current->get(0))); + CHECK(current->IsFixedArray()); + if (Page::FromAddress(current->address()) != to_be_aborted_page) { + in_place = false; + } + bool on_aborted_page = + Page::FromAddress(current->address()) == to_be_aborted_page; + bool on_fill_page = + Page::FromAddress(current->address()) == page_to_fill; + CHECK((in_place && on_aborted_page) || (!in_place && on_fill_page)); + } + // Check that we at least migrated one object, as otherwise the test would + // not trigger. + CHECK(!in_place); + CheckInvariantsOfAbortedPage(to_be_aborted_page); + } + } +} + + +HEAP_TEST(CompactionPartiallyAbortedPageWithStoreBufferEntries) { + // Test the scenario where we reach OOM during compaction and parts of the + // page have already been migrated to a new one. Objects on the aborted page + // are linked together and the very first object on the aborted page points + // into new space. The test verifies that the store buffer entries are + // properly cleared and rebuilt after aborting a page. Failing to do so can + // result in other objects being allocated in the free space where their + // payload looks like a valid new space pointer. + + // Disable concurrent sweeping to ensure memory is in an expected state, i.e., + // we can reach the state of a half aborted page. + FLAG_concurrent_sweeping = false; + FLAG_manual_evacuation_candidates_selection = true; + + const int object_size = 128 * KB; + + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + { + HandleScope scope1(isolate); + Handle<FixedArray> root_array = + isolate->factory()->NewFixedArray(10, TENURED); + PageIterator it(heap->old_space()); + while (it.has_next()) { + it.next()->SetFlag(Page::NEVER_ALLOCATE_ON_PAGE); + } + + Page* to_be_aborted_page = nullptr; + { + HandleScope temporary_scope(isolate); + // Fill another page with objects of size {object_size} (last one is + // properly adjusted). + CHECK(heap->old_space()->Expand()); + auto compaction_page_handles = + CreatePadding(heap, Page::kAllocatableMemory, TENURED, object_size); + // Sanity check that we have enough space for linking up arrays. + CHECK_GE(compaction_page_handles.front()->length(), 2); + to_be_aborted_page = + Page::FromAddress(compaction_page_handles.front()->address()); + to_be_aborted_page->SetFlag( + MemoryChunk::FORCE_EVACUATION_CANDIDATE_FOR_TESTING); + + for (size_t i = compaction_page_handles.size() - 1; i > 0; i--) { + compaction_page_handles[i]->set(0, *compaction_page_handles[i - 1]); + } + root_array->set(0, *compaction_page_handles.back()); + Handle<FixedArray> new_space_array = + isolate->factory()->NewFixedArray(1, NOT_TENURED); + CHECK(heap->InNewSpace(*new_space_array)); + compaction_page_handles.front()->set(1, *new_space_array); + } + + { + // Add another page that is filled with {num_objects} objects of size + // {object_size}. + HandleScope scope3(isolate); + CHECK(heap->old_space()->Expand()); + const int num_objects = 2; + int used_memory = object_size * num_objects; + std::vector<Handle<FixedArray>> page_to_fill_handles = + CreatePadding(heap, used_memory, TENURED, object_size); + Page* page_to_fill = + Page::FromAddress(page_to_fill_handles.front()->address()); + + heap->set_force_oom(true); + heap->CollectAllGarbage(); + + // The following check makes sure that we compacted "some" objects, while + // leaving others in place. + bool in_place = true; + Handle<FixedArray> current = root_array; + while (current->get(0) != heap->undefined_value()) { + current = Handle<FixedArray>(FixedArray::cast(current->get(0))); + CHECK(!heap->InNewSpace(*current)); + CHECK(current->IsFixedArray()); + if (Page::FromAddress(current->address()) != to_be_aborted_page) { + in_place = false; + } + bool on_aborted_page = + Page::FromAddress(current->address()) == to_be_aborted_page; + bool on_fill_page = + Page::FromAddress(current->address()) == page_to_fill; + CHECK((in_place && on_aborted_page) || (!in_place && on_fill_page)); + } + // Check that we at least migrated one object, as otherwise the test would + // not trigger. + CHECK(!in_place); + CheckInvariantsOfAbortedPage(to_be_aborted_page); + + // Allocate a new object in new space. + Handle<FixedArray> holder = + isolate->factory()->NewFixedArray(10, NOT_TENURED); + // Create a broken address that looks like a tagged pointer to a new space + // object. + Address broken_address = holder->address() + 2 * kPointerSize + 1; + // Convert it to a vector to create a string from it. + Vector<const uint8_t> string_to_broken_addresss( + reinterpret_cast<const uint8_t*>(&broken_address), 8); + + Handle<String> string; + do { + // We know that the interesting slot will be on the aborted page and + // hence we allocate until we get our string on the aborted page. + // We used slot 1 in the fixed size array which corresponds to the + // the first word in the string. Since the first object definitely + // migrated we can just allocate until we hit the aborted page. + string = isolate->factory() + ->NewStringFromOneByte(string_to_broken_addresss, TENURED) + .ToHandleChecked(); + } while (Page::FromAddress(string->address()) != to_be_aborted_page); + + // If store buffer entries are not properly filtered/reset for aborted + // pages we have now a broken address at an object slot in old space and + // the following scavenge will crash. + heap->CollectGarbage(NEW_SPACE); + } + } +} + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/heap/test-heap.cc index 41e6c24b9f..726887a23a 100644 --- a/deps/v8/test/cctest/test-heap.cc +++ b/deps/v8/test/cctest/heap/test-heap.cc @@ -25,9 +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. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdlib.h> #include <utility> @@ -41,9 +38,11 @@ #include "src/heap/memory-reducer.h" #include "src/ic/ic.h" #include "src/macro-assembler.h" +#include "src/regexp/jsregexp.h" #include "src/snapshot/snapshot.h" #include "test/cctest/cctest.h" -#include "test/cctest/heap-tester.h" +#include "test/cctest/heap/heap-tester.h" +#include "test/cctest/heap/utils-inl.h" #include "test/cctest/test-feedback-vector.h" @@ -911,7 +910,7 @@ TEST(ObjectProperties) { CHECK(Just(true) == JSReceiver::HasOwnProperty(obj, first)); // delete first - JSReceiver::DeleteProperty(obj, first, SLOPPY).Check(); + CHECK(Just(true) == JSReceiver::DeleteProperty(obj, first, SLOPPY)); CHECK(Just(false) == JSReceiver::HasOwnProperty(obj, first)); // add first and then second @@ -921,9 +920,9 @@ TEST(ObjectProperties) { CHECK(Just(true) == JSReceiver::HasOwnProperty(obj, second)); // delete first and then second - JSReceiver::DeleteProperty(obj, first, SLOPPY).Check(); + CHECK(Just(true) == JSReceiver::DeleteProperty(obj, first, SLOPPY)); CHECK(Just(true) == JSReceiver::HasOwnProperty(obj, second)); - JSReceiver::DeleteProperty(obj, second, SLOPPY).Check(); + CHECK(Just(true) == JSReceiver::DeleteProperty(obj, second, SLOPPY)); CHECK(Just(false) == JSReceiver::HasOwnProperty(obj, first)); CHECK(Just(false) == JSReceiver::HasOwnProperty(obj, second)); @@ -934,9 +933,9 @@ TEST(ObjectProperties) { CHECK(Just(true) == JSReceiver::HasOwnProperty(obj, second)); // delete second and then first - JSReceiver::DeleteProperty(obj, second, SLOPPY).Check(); + CHECK(Just(true) == JSReceiver::DeleteProperty(obj, second, SLOPPY)); CHECK(Just(true) == JSReceiver::HasOwnProperty(obj, first)); - JSReceiver::DeleteProperty(obj, first, SLOPPY).Check(); + CHECK(Just(true) == JSReceiver::DeleteProperty(obj, first, SLOPPY)); CHECK(Just(false) == JSReceiver::HasOwnProperty(obj, first)); CHECK(Just(false) == JSReceiver::HasOwnProperty(obj, second)); @@ -1500,10 +1499,10 @@ TEST(TestCodeFlushingIncrementalAbort) { // disabled. int position = 0; Handle<Object> breakpoint_object(Smi::FromInt(0), isolate); - EnableDebugger(); + EnableDebugger(CcTest::isolate()); isolate->debug()->SetBreakPoint(function, breakpoint_object, &position); isolate->debug()->ClearAllBreakPoints(); - DisableDebugger(); + DisableDebugger(CcTest::isolate()); // Force optimization now that code flushing is disabled. { v8::HandleScope scope(CcTest::isolate()); @@ -1568,18 +1567,26 @@ TEST(CompilationCacheCachingBehavior) { language_mode); CHECK(!info.is_null()); - heap->CollectAllGarbage(); - - // On second compilation, the hash is replaced by a real cache entry mapping - // the source to the shared function info containing the code. - info = compilation_cache->LookupScript( - source, Handle<Object>(), 0, 0, - v8::ScriptOriginOptions(false, true, false), native_context, - language_mode); - CHECK(!info.is_null()); + // Check that the code cache entry survives at least on GC. + // (Unless --optimize-for-size, in which case it might get collected + // immediately.) + if (!FLAG_optimize_for_size) { + heap->CollectAllGarbage(); + info = compilation_cache->LookupScript( + source, Handle<Object>(), 0, 0, + v8::ScriptOriginOptions(false, true, false), native_context, + language_mode); + CHECK(!info.is_null()); + } + // Progress code age until it's old and ready for GC. while (!info.ToHandleChecked()->code()->IsOld()) { - info.ToHandleChecked()->code()->MakeOlder(NO_MARKING_PARITY); + // To guarantee progress, we have to MakeOlder with different parities. + // We can't just use NO_MARKING_PARITY, since e.g. kExecutedOnceCodeAge is + // always NO_MARKING_PARITY and the code age only progresses if the parity + // is different. + info.ToHandleChecked()->code()->MakeOlder(ODD_MARKING_PARITY); + info.ToHandleChecked()->code()->MakeOlder(EVEN_MARKING_PARITY); } heap->CollectAllGarbage(); @@ -1643,8 +1650,7 @@ int CountNativeContexts() { count++; object = Context::cast(object)->get(Context::NEXT_CONTEXT_LINK); } - // Subtract one to compensate for the code stub context that is always present - return count - 1; + return count; } @@ -1783,8 +1789,7 @@ static int CountNativeContextsWithGC(Isolate* isolate, int n) { Handle<Object>(Context::cast(*object)->get(Context::NEXT_CONTEXT_LINK), isolate); } - // Subtract one to compensate for the code stub context that is always present - return count - 1; + return count; } @@ -1869,7 +1874,7 @@ TEST(TestSizeOfRegExpCode) { // Adjust source below and this check to match // RegExpImple::kRegExpTooLargeToOptimize. - DCHECK_EQ(i::RegExpImpl::kRegExpTooLargeToOptimize, 20 * KB); + CHECK_EQ(i::RegExpImpl::kRegExpTooLargeToOptimize, 20 * KB); // Compile a regexp that is much larger if we are using regexp optimizations. CompileRun( @@ -2361,10 +2366,7 @@ static int NumberOfGlobalObjects() { for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { if (obj->IsJSGlobalObject()) 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; + return count; } @@ -2384,7 +2386,7 @@ TEST(LeakNativeContextViaMap) { } CcTest::heap()->CollectAllAvailableGarbage(); - CHECK_EQ(4, NumberOfGlobalObjects()); + CHECK_EQ(2, NumberOfGlobalObjects()); { v8::HandleScope inner_scope(isolate); @@ -2410,7 +2412,7 @@ TEST(LeakNativeContextViaMap) { isolate->ContextDisposedNotification(); } CcTest::heap()->CollectAllAvailableGarbage(); - CHECK_EQ(2, NumberOfGlobalObjects()); + CHECK_EQ(1, NumberOfGlobalObjects()); ctx2p.Reset(); CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, NumberOfGlobalObjects()); @@ -2433,7 +2435,7 @@ TEST(LeakNativeContextViaFunction) { } CcTest::heap()->CollectAllAvailableGarbage(); - CHECK_EQ(4, NumberOfGlobalObjects()); + CHECK_EQ(2, NumberOfGlobalObjects()); { v8::HandleScope inner_scope(isolate); @@ -2459,7 +2461,7 @@ TEST(LeakNativeContextViaFunction) { isolate->ContextDisposedNotification(); } CcTest::heap()->CollectAllAvailableGarbage(); - CHECK_EQ(2, NumberOfGlobalObjects()); + CHECK_EQ(1, NumberOfGlobalObjects()); ctx2p.Reset(); CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, NumberOfGlobalObjects()); @@ -2480,7 +2482,7 @@ TEST(LeakNativeContextViaMapKeyed) { } CcTest::heap()->CollectAllAvailableGarbage(); - CHECK_EQ(4, NumberOfGlobalObjects()); + CHECK_EQ(2, NumberOfGlobalObjects()); { v8::HandleScope inner_scope(isolate); @@ -2506,7 +2508,7 @@ TEST(LeakNativeContextViaMapKeyed) { isolate->ContextDisposedNotification(); } CcTest::heap()->CollectAllAvailableGarbage(); - CHECK_EQ(2, NumberOfGlobalObjects()); + CHECK_EQ(1, NumberOfGlobalObjects()); ctx2p.Reset(); CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, NumberOfGlobalObjects()); @@ -2527,7 +2529,7 @@ TEST(LeakNativeContextViaMapProto) { } CcTest::heap()->CollectAllAvailableGarbage(); - CHECK_EQ(4, NumberOfGlobalObjects()); + CHECK_EQ(2, NumberOfGlobalObjects()); { v8::HandleScope inner_scope(isolate); @@ -2557,7 +2559,7 @@ TEST(LeakNativeContextViaMapProto) { isolate->ContextDisposedNotification(); } CcTest::heap()->CollectAllAvailableGarbage(); - CHECK_EQ(2, NumberOfGlobalObjects()); + CHECK_EQ(1, NumberOfGlobalObjects()); ctx2p.Reset(); CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, NumberOfGlobalObjects()); @@ -2620,73 +2622,6 @@ TEST(InstanceOfStubWriteBarrier) { } -static int NumberOfProtoTransitions(Map* map) { - return TransitionArray::NumberOfPrototypeTransitions( - TransitionArray::GetPrototypeTransitions(map)); -} - - -TEST(PrototypeTransitionClearing) { - if (FLAG_never_compact) return; - CcTest::InitializeVM(); - Isolate* isolate = CcTest::i_isolate(); - Factory* factory = isolate->factory(); - v8::HandleScope scope(CcTest::isolate()); - v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); - - CompileRun("var base = {};"); - i::Handle<JSObject> baseObject = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( - CcTest::global()->Get(ctx, v8_str("base")).ToLocalChecked())); - - int initialTransitions = NumberOfProtoTransitions(baseObject->map()); - - CompileRun( - "var live = [];" - "for (var i = 0; i < 10; i++) {" - " var object = {};" - " var prototype = {};" - " object.__proto__ = prototype;" - " if (i >= 3) live.push(object, prototype);" - "}"); - - // Verify that only dead prototype transitions are cleared. - CHECK_EQ(initialTransitions + 10, - NumberOfProtoTransitions(baseObject->map())); - CcTest::heap()->CollectAllGarbage(); - const int transitions = 10 - 3; - CHECK_EQ(initialTransitions + transitions, - NumberOfProtoTransitions(baseObject->map())); - - // Verify that prototype transitions array was compacted. - FixedArray* trans = - TransitionArray::GetPrototypeTransitions(baseObject->map()); - for (int i = initialTransitions; i < initialTransitions + transitions; i++) { - int j = TransitionArray::kProtoTransitionHeaderSize + i; - CHECK(trans->get(j)->IsWeakCell()); - CHECK(WeakCell::cast(trans->get(j))->value()->IsMap()); - } - - // Make sure next prototype is placed on an old-space evacuation candidate. - Handle<JSObject> prototype; - PagedSpace* space = CcTest::heap()->old_space(); - { - AlwaysAllocateScope always_allocate(isolate); - SimulateFullSpace(space); - prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, - Strength::WEAK, TENURED); - } - - // Add a prototype on an evacuation candidate and verify that transition - // clearing correctly records slots in prototype transition array. - i::FLAG_always_compact = true; - Handle<Map> map(baseObject->map()); - CHECK(!space->LastPage()->Contains( - TransitionArray::GetPrototypeTransitions(*map)->address())); - CHECK(space->LastPage()->Contains(prototype->address())); -} - - TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) { i::FLAG_stress_compaction = false; i::FLAG_allow_natives_syntax = true; @@ -2877,7 +2812,7 @@ TEST(OptimizedAllocationAlwaysInNewSpace) { ->Int32Value(ctx) .FromJust()); - i::Handle<JSObject> o = + i::Handle<JSReceiver> o = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); CHECK(CcTest::heap()->InNewSpace(*o)); @@ -2918,14 +2853,14 @@ TEST(OptimizedPretenuringAllocationFolding) { v8::Local<v8::Value> int_array = v8::Object::Cast(*res)->Get(ctx, v8_str("0")).ToLocalChecked(); - i::Handle<JSObject> int_array_handle = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(int_array)); + i::Handle<JSObject> int_array_handle = i::Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(int_array))); v8::Local<v8::Value> double_array = v8::Object::Cast(*res)->Get(ctx, v8_str("1")).ToLocalChecked(); - i::Handle<JSObject> double_array_handle = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(double_array)); + i::Handle<JSObject> double_array_handle = i::Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(double_array))); - i::Handle<JSObject> o = + i::Handle<JSReceiver> o = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); CHECK(CcTest::heap()->InOldSpace(*o)); CHECK(CcTest::heap()->InOldSpace(*int_array_handle)); @@ -2967,8 +2902,8 @@ TEST(OptimizedPretenuringObjectArrayLiterals) { v8::Local<v8::Value> res = CompileRun(source.start()); - i::Handle<JSObject> o = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); + i::Handle<JSObject> o = Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res))); CHECK(CcTest::heap()->InOldSpace(o->elements())); CHECK(CcTest::heap()->InOldSpace(*o)); @@ -3008,8 +2943,8 @@ TEST(OptimizedPretenuringMixedInObjectProperties) { v8::Local<v8::Value> res = CompileRun(source.start()); - i::Handle<JSObject> o = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); + i::Handle<JSObject> o = Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res))); CHECK(CcTest::heap()->InOldSpace(*o)); FieldIndex idx1 = FieldIndex::ForPropertyIndex(o->map(), 0); @@ -3065,8 +3000,8 @@ TEST(OptimizedPretenuringDoubleArrayProperties) { v8::Local<v8::Value> res = CompileRun(source.start()); - i::Handle<JSObject> o = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); + i::Handle<JSObject> o = Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res))); CHECK(CcTest::heap()->InOldSpace(*o)); CHECK(CcTest::heap()->InOldSpace(o->properties())); @@ -3105,8 +3040,8 @@ TEST(OptimizedPretenuringdoubleArrayLiterals) { v8::Local<v8::Value> res = CompileRun(source.start()); - i::Handle<JSObject> o = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); + i::Handle<JSObject> o = Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res))); CHECK(CcTest::heap()->InOldSpace(o->elements())); CHECK(CcTest::heap()->InOldSpace(*o)); @@ -3146,14 +3081,15 @@ TEST(OptimizedPretenuringNestedMixedArrayLiterals) { v8::Local<v8::Value> int_array = v8::Object::Cast(*res)->Get(ctx, v8_str("0")).ToLocalChecked(); - i::Handle<JSObject> int_array_handle = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(int_array)); + i::Handle<JSObject> int_array_handle = i::Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(int_array))); v8::Local<v8::Value> double_array = v8::Object::Cast(*res)->Get(ctx, v8_str("1")).ToLocalChecked(); - i::Handle<JSObject> double_array_handle = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(double_array)); + i::Handle<JSObject> double_array_handle = i::Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(double_array))); - Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); + Handle<JSObject> o = Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res))); CHECK(CcTest::heap()->InOldSpace(*o)); CHECK(CcTest::heap()->InOldSpace(*int_array_handle)); CHECK(CcTest::heap()->InOldSpace(int_array_handle->elements())); @@ -3196,14 +3132,15 @@ TEST(OptimizedPretenuringNestedObjectLiterals) { v8::Local<v8::Value> int_array_1 = v8::Object::Cast(*res)->Get(ctx, v8_str("0")).ToLocalChecked(); - Handle<JSObject> int_array_handle_1 = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(int_array_1)); + Handle<JSObject> int_array_handle_1 = Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(int_array_1))); v8::Local<v8::Value> int_array_2 = v8::Object::Cast(*res)->Get(ctx, v8_str("1")).ToLocalChecked(); - Handle<JSObject> int_array_handle_2 = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(int_array_2)); + Handle<JSObject> int_array_handle_2 = Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(int_array_2))); - Handle<JSObject> o = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); + Handle<JSObject> o = Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res))); CHECK(CcTest::heap()->InOldSpace(*o)); CHECK(CcTest::heap()->InOldSpace(*int_array_handle_1)); CHECK(CcTest::heap()->InOldSpace(int_array_handle_1->elements())); @@ -3246,15 +3183,15 @@ TEST(OptimizedPretenuringNestedDoubleLiterals) { v8::Local<v8::Value> double_array_1 = v8::Object::Cast(*res)->Get(ctx, v8_str("0")).ToLocalChecked(); - i::Handle<JSObject> double_array_handle_1 = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(double_array_1)); + i::Handle<JSObject> double_array_handle_1 = i::Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(double_array_1))); v8::Local<v8::Value> double_array_2 = v8::Object::Cast(*res)->Get(ctx, v8_str("1")).ToLocalChecked(); - i::Handle<JSObject> double_array_handle_2 = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(double_array_2)); + i::Handle<JSObject> double_array_handle_2 = Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(double_array_2))); - i::Handle<JSObject> o = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); + i::Handle<JSObject> o = Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res))); CHECK(CcTest::heap()->InOldSpace(*o)); CHECK(CcTest::heap()->InOldSpace(*double_array_handle_1)); CHECK(CcTest::heap()->InOldSpace(double_array_handle_1->elements())); @@ -3286,8 +3223,8 @@ TEST(OptimizedAllocationArrayLiterals) { ->Int32Value(ctx) .FromJust()); - i::Handle<JSObject> o = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); + i::Handle<JSObject> o = Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res))); CHECK(CcTest::heap()->InNewSpace(o->elements())); } @@ -3321,8 +3258,9 @@ TEST(Regress1465) { CompileRun("var root = new F;"); } - i::Handle<JSObject> root = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( - CcTest::global()->Get(ctx, v8_str("root")).ToLocalChecked())); + i::Handle<JSReceiver> root = + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( + CcTest::global()->Get(ctx, v8_str("root")).ToLocalChecked())); // Count number of live transitions before marking. int transitions_before = CountMapTransitions(root->map()); @@ -3352,10 +3290,11 @@ static void AddTransitions(int transitions_count) { static i::Handle<JSObject> GetByName(const char* name) { - return v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( - CcTest::global() - ->Get(CcTest::isolate()->GetCurrentContext(), v8_str(name)) - .ToLocalChecked())); + return i::Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( + CcTest::global() + ->Get(CcTest::isolate()->GetCurrentContext(), v8_str(name)) + .ToLocalChecked()))); } @@ -3475,7 +3414,7 @@ TEST(TransitionArraySimpleToFull) { CompileRun("o = new F;" "root = new F"); root = GetByName("root"); - DCHECK(TransitionArray::IsSimpleTransition(root->map()->raw_transitions())); + CHECK(TransitionArray::IsSimpleTransition(root->map()->raw_transitions())); AddPropertyTo(2, root, "happy"); // Count number of live transitions after marking. Note that one transition @@ -3515,7 +3454,7 @@ TEST(Regress2143a) { // Explicitly request GC to perform final marking step and sweeping. CcTest::heap()->CollectAllGarbage(); - Handle<JSObject> root = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( + Handle<JSReceiver> root = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( CcTest::global() ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("root")) .ToLocalChecked())); @@ -3558,7 +3497,7 @@ TEST(Regress2143b) { // Explicitly request GC to perform final marking step and sweeping. CcTest::heap()->CollectAllGarbage(); - Handle<JSObject> root = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( + Handle<JSReceiver> root = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( CcTest::global() ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("root")) .ToLocalChecked())); @@ -3670,19 +3609,16 @@ TEST(IncrementalMarkingPreservesMonomorphicCallIC) { v8::Local<v8::Value> fun1, fun2; v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext(); { - LocalContext env; CompileRun("function fun() {};"); - fun1 = env->Global()->Get(env.local(), v8_str("fun")).ToLocalChecked(); + fun1 = CcTest::global()->Get(ctx, v8_str("fun")).ToLocalChecked(); } { - LocalContext env; CompileRun("function fun() {};"); - fun2 = env->Global()->Get(env.local(), v8_str("fun")).ToLocalChecked(); + fun2 = CcTest::global()->Get(ctx, v8_str("fun")).ToLocalChecked(); } - // Prepare function f that contains type feedback for closures - // originating from two different native contexts. + // Prepare function f that contains type feedback for the two closures. CHECK(CcTest::global()->Set(ctx, v8_str("fun1"), fun1).FromJust()); CHECK(CcTest::global()->Set(ctx, v8_str("fun2"), fun2).FromJust()); CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);"); @@ -3713,7 +3649,6 @@ TEST(IncrementalMarkingPreservesMonomorphicCallIC) { static Code* FindFirstIC(Code* code, Code::Kind kind) { int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | - RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID); for (RelocIterator it(code, mask); !it.done(); it.next()) { RelocInfo* info = it.rinfo(); @@ -3752,39 +3687,6 @@ static void CheckVectorICCleared(Handle<JSFunction> f, int 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"); - i::Handle<JSObject> maybe_apply = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(res)); - apply = i::Handle<JSFunction>::cast(maybe_apply); - i::Handle<TypeFeedbackVector> vector(apply->shared()->feedback_vector()); - FeedbackVectorHelper feedback_helper(vector); - CHECK_EQ(1, feedback_helper.slot_count()); - 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(); @@ -4500,6 +4402,115 @@ TEST(Regress514122) { } +TEST(OptimizedCodeMapReuseEntries) { + i::FLAG_flush_optimized_code_cache = false; + i::FLAG_allow_natives_syntax = true; + // BUG(v8:4598): Since TurboFan doesn't treat maps in code weakly, we can't + // run this test. + if (i::FLAG_turbo) return; + CcTest::InitializeVM(); + v8::Isolate* v8_isolate = CcTest::isolate(); + Isolate* isolate = CcTest::i_isolate(); + Heap* heap = isolate->heap(); + HandleScope scope(isolate); + + // Create 3 contexts, allow the 2nd one to be disposed, and verify that + // a 4th context will re-use the weak slots in the optimized code map + // to hold data, rather than expanding the map. + v8::Local<v8::Context> c1 = v8::Context::New(v8_isolate); + const char* source = "function foo(x) { var l = [1]; return x+l[0]; }"; + v8::ScriptCompiler::Source script_source( + v8::String::NewFromUtf8(v8_isolate, source, v8::NewStringType::kNormal) + .ToLocalChecked()); + v8::Local<v8::UnboundScript> indep = + v8::ScriptCompiler::CompileUnboundScript(v8_isolate, &script_source) + .ToLocalChecked(); + const char* toplevel = "foo(3); %OptimizeFunctionOnNextCall(foo); foo(3);"; + // Perfrom one initial GC to enable code flushing. + heap->CollectAllGarbage(); + + c1->Enter(); + indep->BindToCurrentContext()->Run(c1).ToLocalChecked(); + CompileRun(toplevel); + + Handle<SharedFunctionInfo> shared; + Handle<JSFunction> foo = Handle<JSFunction>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( + CcTest::global()->Get(c1, v8_str("foo")).ToLocalChecked()))); + CHECK(foo->shared()->is_compiled()); + shared = handle(foo->shared()); + c1->Exit(); + + { + HandleScope scope(isolate); + v8::Local<v8::Context> c2 = v8::Context::New(v8_isolate); + c2->Enter(); + indep->BindToCurrentContext()->Run(c2).ToLocalChecked(); + CompileRun(toplevel); + c2->Exit(); + } + + { + HandleScope scope(isolate); + v8::Local<v8::Context> c3 = v8::Context::New(v8_isolate); + c3->Enter(); + indep->BindToCurrentContext()->Run(c3).ToLocalChecked(); + CompileRun(toplevel); + c3->Exit(); + + // Now, collect garbage. Context c2 should have no roots to it, and it's + // entry in the optimized code map should be free for a new context. + for (int i = 0; i < 4; i++) { + heap->CollectAllGarbage(); + } + + Handle<FixedArray> optimized_code_map = + handle(shared->optimized_code_map()); + // There should be 3 entries in the map. + CHECK_EQ( + 3, ((optimized_code_map->length() - SharedFunctionInfo::kEntriesStart) / + SharedFunctionInfo::kEntryLength)); + // But one of them (formerly for c2) should be cleared. + int cleared_count = 0; + for (int i = SharedFunctionInfo::kEntriesStart; + i < optimized_code_map->length(); + i += SharedFunctionInfo::kEntryLength) { + cleared_count += + WeakCell::cast( + optimized_code_map->get(i + SharedFunctionInfo::kContextOffset)) + ->cleared() + ? 1 + : 0; + } + CHECK_EQ(1, cleared_count); + + // Verify that a new context uses the cleared entry rather than creating a + // new + // optimized code map array. + v8::Local<v8::Context> c4 = v8::Context::New(v8_isolate); + c4->Enter(); + indep->BindToCurrentContext()->Run(c4).ToLocalChecked(); + CompileRun(toplevel); + c4->Exit(); + CHECK_EQ(*optimized_code_map, shared->optimized_code_map()); + + // Now each entry is in use. + cleared_count = 0; + for (int i = SharedFunctionInfo::kEntriesStart; + i < optimized_code_map->length(); + i += SharedFunctionInfo::kEntryLength) { + cleared_count += + WeakCell::cast( + optimized_code_map->get(i + SharedFunctionInfo::kContextOffset)) + ->cleared() + ? 1 + : 0; + } + CHECK_EQ(0, cleared_count); + } +} + + TEST(Regress513496) { i::FLAG_flush_optimized_code_cache = false; i::FLAG_allow_natives_syntax = true; @@ -4623,7 +4634,7 @@ TEST(DeferredHandles) { } // An entire block of handles has been filled. // Next handle would require a new block. - DCHECK(data->next == data->limit); + CHECK(data->next == data->limit); DeferredHandleScope deferred(isolate); DummyVisitor visitor; @@ -4646,8 +4657,8 @@ TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) { } // This big step should be sufficient to mark the whole array. marking->Step(100 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD); - DCHECK(marking->IsComplete() || - marking->IsReadyToOverApproximateWeakClosure()); + CHECK(marking->IsComplete() || + marking->IsReadyToOverApproximateWeakClosure()); } @@ -4722,12 +4733,12 @@ TEST(EnsureAllocationSiteDependentCodesProcessed) { CompileRun("%OptimizeFunctionOnNextCall(bar); bar();"); - DependentCode::GroupStartIndexes starts(site->dependent_code()); - CHECK_GE(starts.number_of_entries(), 1); - int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup); - CHECK(site->dependent_code()->object_at(index)->IsWeakCell()); + CHECK_EQ(DependentCode::kAllocationSiteTransitionChangedGroup, + site->dependent_code()->group()); + CHECK_EQ(1, site->dependent_code()->count()); + CHECK(site->dependent_code()->object_at(0)->IsWeakCell()); Code* function_bar = Code::cast( - WeakCell::cast(site->dependent_code()->object_at(index))->value()); + WeakCell::cast(site->dependent_code()->object_at(0))->value()); Handle<JSFunction> bar_handle = Handle<JSFunction>::cast( v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( CcTest::global() @@ -4744,10 +4755,8 @@ TEST(EnsureAllocationSiteDependentCodesProcessed) { // The site still exists because of our global handle, but the code is no // longer referred to by dependent_code(). - DependentCode::GroupStartIndexes starts(site->dependent_code()); - int index = starts.at(DependentCode::kAllocationSiteTransitionChangedGroup); - CHECK(site->dependent_code()->object_at(index)->IsWeakCell() && - WeakCell::cast(site->dependent_code()->object_at(index))->cleared()); + CHECK(site->dependent_code()->object_at(0)->IsWeakCell() && + WeakCell::cast(site->dependent_code()->object_at(0))->cleared()); } @@ -4766,17 +4775,19 @@ TEST(CellsInOptimizedCodeAreWeak) { LocalContext context; HandleScope scope(heap->isolate()); - CompileRun("bar = (function() {" - " function bar() {" - " return foo(1);" - " };" - " var foo = function(x) { with (x) { return 1 + x; } };" - " bar(foo);" - " bar(foo);" - " bar(foo);" - " %OptimizeFunctionOnNextCall(bar);" - " bar(foo);" - " return bar;})();"); + CompileRun( + "bar = (function() {" + " function bar() {" + " return foo(1);" + " };" + " var foo = function(x) { with (x) { return 1 + x; } };" + " %NeverOptimizeFunction(foo);" + " bar(foo);" + " bar(foo);" + " bar(foo);" + " %OptimizeFunctionOnNextCall(bar);" + " bar(foo);" + " return bar;})();"); Handle<JSFunction> bar = Handle<JSFunction>::cast(v8::Utils::OpenHandle( *v8::Local<v8::Function>::Cast(CcTest::global() @@ -4790,7 +4801,7 @@ TEST(CellsInOptimizedCodeAreWeak) { heap->CollectAllGarbage(); } - DCHECK(code->marked_for_deoptimization()); + CHECK(code->marked_for_deoptimization()); } @@ -4809,15 +4820,17 @@ TEST(ObjectsInOptimizedCodeAreWeak) { LocalContext context; HandleScope scope(heap->isolate()); - CompileRun("function bar() {" - " return foo(1);" - "};" - "function foo(x) { with (x) { return 1 + x; } };" - "bar();" - "bar();" - "bar();" - "%OptimizeFunctionOnNextCall(bar);" - "bar();"); + CompileRun( + "function bar() {" + " return foo(1);" + "};" + "function foo(x) { with (x) { return 1 + x; } };" + "%NeverOptimizeFunction(foo);" + "bar();" + "bar();" + "bar();" + "%OptimizeFunctionOnNextCall(bar);" + "bar();"); Handle<JSFunction> bar = Handle<JSFunction>::cast(v8::Utils::OpenHandle( *v8::Local<v8::Function>::Cast(CcTest::global() @@ -4831,7 +4844,7 @@ TEST(ObjectsInOptimizedCodeAreWeak) { heap->CollectAllGarbage(); } - DCHECK(code->marked_for_deoptimization()); + CHECK(code->marked_for_deoptimization()); } @@ -4947,7 +4960,8 @@ TEST(NextCodeLinkIsWeak) { static Handle<Code> DummyOptimizedCode(Isolate* isolate) { i::byte buffer[i::Assembler::kMinimalBufferSize]; - MacroAssembler masm(isolate, buffer, sizeof(buffer)); + MacroAssembler masm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); CodeDesc desc; masm.Push(isolate->factory()->undefined_value()); masm.Drop(1); @@ -5519,7 +5533,7 @@ TEST(Regress357137) { .ToLocalChecked(), v8::FunctionTemplate::New(isolate, RequestInterrupt)); v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global); - DCHECK(!context.IsEmpty()); + CHECK(!context.IsEmpty()); v8::Context::Scope cscope(context); v8::Local<v8::Value> result = CompileRun( @@ -5573,8 +5587,8 @@ TEST(ArrayShiftSweeping) { "array.shift();" "array;"); - Handle<JSObject> o = - v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(result)); + Handle<JSObject> o = Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(result))); CHECK(heap->InOldSpace(o->elements())); CHECK(heap->InOldSpace(*o)); Page* page = Page::FromAddress(o->elements()->address()); @@ -5722,7 +5736,7 @@ TEST(Regress3631) { CcTest::heap()->StartIncrementalMarking(); } // Incrementally mark the backing store. - Handle<JSObject> obj = + Handle<JSReceiver> obj = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(result)); Handle<JSWeakCollection> weak_map(reinterpret_cast<JSWeakCollection*>(*obj)); while (!Marking::IsBlack( @@ -5782,7 +5796,7 @@ TEST(Regress3877) { { HandleScope inner_scope(isolate); v8::Local<v8::Value> result = CompileRun("cls.prototype"); - Handle<JSObject> proto = + Handle<JSReceiver> proto = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(result)); weak_prototype = inner_scope.CloseAndEscape(factory->NewWeakCell(proto)); } @@ -5810,7 +5824,7 @@ Handle<WeakCell> AddRetainedMap(Isolate* isolate, Heap* heap) { Handle<Map> map = Map::Create(isolate, 1); v8::Local<v8::Value> result = CompileRun("(function () { return {x : 10}; })();"); - Handle<JSObject> proto = + Handle<JSReceiver> proto = v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(result)); Map::SetPrototype(map, proto); heap->AddRetainedMap(map); @@ -5825,9 +5839,11 @@ void CheckMapRetainingFor(int n) { Handle<WeakCell> weak_cell = AddRetainedMap(isolate, heap); CHECK(!weak_cell->cleared()); for (int i = 0; i < n; i++) { + SimulateIncrementalMarking(heap); heap->CollectGarbage(OLD_SPACE); } CHECK(!weak_cell->cleared()); + SimulateIncrementalMarking(heap); heap->CollectGarbage(OLD_SPACE); CHECK(weak_cell->cleared()); } diff --git a/deps/v8/test/cctest/test-incremental-marking.cc b/deps/v8/test/cctest/heap/test-incremental-marking.cc index ef3bad68ae..5822d4a979 100644 --- a/deps/v8/test/cctest/test-incremental-marking.cc +++ b/deps/v8/test/cctest/heap/test-incremental-marking.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdlib.h> #ifdef __linux__ @@ -22,6 +19,8 @@ #include "src/full-codegen/full-codegen.h" #include "src/global-handles.h" #include "test/cctest/cctest.h" +#include "test/cctest/heap/utils-inl.h" + using v8::IdleTask; using v8::Task; @@ -86,6 +85,28 @@ class MockPlatform : public v8::Platform { delete task; } + uint64_t AddTraceEvent(char phase, const uint8_t* categoryEnabledFlag, + const char* name, uint64_t id, uint64_t bind_id, + int numArgs, const char** argNames, + const uint8_t* argTypes, const uint64_t* argValues, + unsigned int flags) override { + return 0; + } + + void UpdateTraceEventDuration(const uint8_t* categoryEnabledFlag, + const char* name, uint64_t handle) override {} + + const uint8_t* GetCategoryGroupEnabled(const char* name) override { + static uint8_t no = 0; + return &no; + } + + const char* GetCategoryGroupName( + const uint8_t* categoryEnabledFlag) override { + static const char* dummy = "dummy"; + return dummy; + } + private: v8::Platform* platform_; IdleTask* idle_task_; diff --git a/deps/v8/test/cctest/heap/test-lab.cc b/deps/v8/test/cctest/heap/test-lab.cc new file mode 100644 index 0000000000..770804f162 --- /dev/null +++ b/deps/v8/test/cctest/heap/test-lab.cc @@ -0,0 +1,284 @@ +// 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 <vector> + +#include "src/globals.h" +#include "src/heap/heap.h" +#include "src/heap/spaces.h" +#include "src/heap/spaces-inl.h" +#include "test/cctest/cctest.h" + +namespace v8 { +namespace internal { + +static Address AllocateLabBackingStore(Heap* heap, intptr_t size_in_bytes) { + AllocationResult result = heap->old_space()->AllocateRaw( + static_cast<int>(size_in_bytes), kDoubleAligned); + Object* obj = result.ToObjectChecked(); + Address adr = HeapObject::cast(obj)->address(); + return adr; +} + + +static void VerifyIterable(v8::internal::Address base, + v8::internal::Address limit, + std::vector<intptr_t> expected_size) { + CHECK_LE(reinterpret_cast<intptr_t>(base), reinterpret_cast<intptr_t>(limit)); + HeapObject* object = nullptr; + size_t counter = 0; + while (base < limit) { + object = HeapObject::FromAddress(base); + CHECK(object->IsFiller()); + CHECK_LT(counter, expected_size.size()); + CHECK_EQ(expected_size[counter], object->Size()); + base += object->Size(); + counter++; + } +} + + +static bool AllocateFromLab(Heap* heap, LocalAllocationBuffer* lab, + intptr_t size_in_bytes, + AllocationAlignment alignment = kWordAligned) { + HeapObject* obj; + AllocationResult result = + lab->AllocateRawAligned(static_cast<int>(size_in_bytes), alignment); + if (result.To(&obj)) { + heap->CreateFillerObjectAt(obj->address(), static_cast<int>(size_in_bytes)); + return true; + } + return false; +} + + +TEST(InvalidLab) { + LocalAllocationBuffer lab = LocalAllocationBuffer::InvalidBuffer(); + CHECK(!lab.IsValid()); +} + + +TEST(UnusedLabImplicitClose) { + CcTest::InitializeVM(); + Heap* heap = CcTest::heap(); + heap->root(Heap::kOnePointerFillerMapRootIndex); + const int kLabSize = 4 * KB; + Address base = AllocateLabBackingStore(heap, kLabSize); + Address limit = base + kLabSize; + intptr_t expected_sizes_raw[1] = {kLabSize}; + std::vector<intptr_t> expected_sizes(expected_sizes_raw, + expected_sizes_raw + 1); + { + AllocationResult lab_backing_store(HeapObject::FromAddress(base)); + LocalAllocationBuffer lab = + LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize); + CHECK(lab.IsValid()); + } + VerifyIterable(base, limit, expected_sizes); +} + + +TEST(SimpleAllocate) { + CcTest::InitializeVM(); + Heap* heap = CcTest::heap(); + const int kLabSize = 4 * KB; + Address base = AllocateLabBackingStore(heap, kLabSize); + Address limit = base + kLabSize; + intptr_t sizes_raw[1] = {128}; + intptr_t expected_sizes_raw[2] = {128, kLabSize - 128}; + std::vector<intptr_t> sizes(sizes_raw, sizes_raw + 1); + std::vector<intptr_t> expected_sizes(expected_sizes_raw, + expected_sizes_raw + 2); + { + AllocationResult lab_backing_store(HeapObject::FromAddress(base)); + LocalAllocationBuffer lab = + LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize); + CHECK(lab.IsValid()); + intptr_t sum = 0; + for (auto size : sizes) { + if (AllocateFromLab(heap, &lab, size)) { + sum += size; + } + } + } + VerifyIterable(base, limit, expected_sizes); +} + + +TEST(AllocateUntilLabOOM) { + CcTest::InitializeVM(); + Heap* heap = CcTest::heap(); + const int kLabSize = 2 * KB; + Address base = AllocateLabBackingStore(heap, kLabSize); + Address limit = base + kLabSize; + // The following objects won't fit in {kLabSize}. + intptr_t sizes_raw[5] = {512, 512, 128, 512, 512}; + intptr_t expected_sizes_raw[5] = {512, 512, 128, 512, 384 /* left over */}; + std::vector<intptr_t> sizes(sizes_raw, sizes_raw + 5); + std::vector<intptr_t> expected_sizes(expected_sizes_raw, + expected_sizes_raw + 5); + intptr_t sum = 0; + { + AllocationResult lab_backing_store(HeapObject::FromAddress(base)); + LocalAllocationBuffer lab = + LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize); + CHECK(lab.IsValid()); + for (auto size : sizes) { + if (AllocateFromLab(heap, &lab, size)) { + sum += size; + } + } + CHECK_EQ(kLabSize - sum, 384); + } + VerifyIterable(base, limit, expected_sizes); +} + + +TEST(AllocateExactlyUntilLimit) { + CcTest::InitializeVM(); + Heap* heap = CcTest::heap(); + const int kLabSize = 2 * KB; + Address base = AllocateLabBackingStore(heap, kLabSize); + Address limit = base + kLabSize; + intptr_t sizes_raw[4] = {512, 512, 512, 512}; + intptr_t expected_sizes_raw[5] = {512, 512, 512, 512, 0}; + std::vector<intptr_t> sizes(sizes_raw, sizes_raw + 4); + std::vector<intptr_t> expected_sizes(expected_sizes_raw, + expected_sizes_raw + 5); + { + AllocationResult lab_backing_store(HeapObject::FromAddress(base)); + LocalAllocationBuffer lab = + LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize); + CHECK(lab.IsValid()); + intptr_t sum = 0; + for (auto size : sizes) { + if (AllocateFromLab(heap, &lab, size)) { + sum += size; + } else { + break; + } + } + CHECK_EQ(kLabSize - sum, 0); + } + VerifyIterable(base, limit, expected_sizes); +} + + +TEST(MergeSuccessful) { + CcTest::InitializeVM(); + Heap* heap = CcTest::heap(); + const int kLabSize = 2 * KB; + Address base1 = AllocateLabBackingStore(heap, kLabSize); + Address limit1 = base1 + kLabSize; + Address base2 = limit1; + Address limit2 = base2 + kLabSize; + + intptr_t sizes1_raw[4] = {512, 512, 512, 256}; + intptr_t expected_sizes1_raw[5] = {512, 512, 512, 256, 256}; + std::vector<intptr_t> sizes1(sizes1_raw, sizes1_raw + 4); + std::vector<intptr_t> expected_sizes1(expected_sizes1_raw, + expected_sizes1_raw + 5); + + intptr_t sizes2_raw[5] = {256, 512, 512, 512, 512}; + intptr_t expected_sizes2_raw[10] = {512, 512, 512, 256, 256, + 512, 512, 512, 512, 0}; + std::vector<intptr_t> sizes2(sizes2_raw, sizes2_raw + 5); + std::vector<intptr_t> expected_sizes2(expected_sizes2_raw, + expected_sizes2_raw + 10); + + { + AllocationResult lab_backing_store1(HeapObject::FromAddress(base1)); + LocalAllocationBuffer lab1 = + LocalAllocationBuffer::FromResult(heap, lab_backing_store1, kLabSize); + CHECK(lab1.IsValid()); + intptr_t sum = 0; + for (auto size : sizes1) { + if (AllocateFromLab(heap, &lab1, size)) { + sum += size; + } else { + break; + } + } + + AllocationResult lab_backing_store2(HeapObject::FromAddress(base2)); + LocalAllocationBuffer lab2 = + LocalAllocationBuffer::FromResult(heap, lab_backing_store2, kLabSize); + CHECK(lab2.IsValid()); + CHECK(lab2.TryMerge(&lab1)); + CHECK(!lab1.IsValid()); + for (auto size : sizes2) { + if (AllocateFromLab(heap, &lab2, size)) { + sum += size; + } else { + break; + } + } + CHECK_EQ(2 * kLabSize - sum, 0); + } + VerifyIterable(base1, limit1, expected_sizes1); + VerifyIterable(base1, limit2, expected_sizes2); +} + + +TEST(MergeFailed) { + CcTest::InitializeVM(); + Heap* heap = CcTest::heap(); + const int kLabSize = 2 * KB; + Address base1 = AllocateLabBackingStore(heap, kLabSize); + Address base2 = base1 + kLabSize; + Address base3 = base2 + kLabSize; + + { + AllocationResult lab_backing_store1(HeapObject::FromAddress(base1)); + LocalAllocationBuffer lab1 = + LocalAllocationBuffer::FromResult(heap, lab_backing_store1, kLabSize); + CHECK(lab1.IsValid()); + + AllocationResult lab_backing_store2(HeapObject::FromAddress(base2)); + LocalAllocationBuffer lab2 = + LocalAllocationBuffer::FromResult(heap, lab_backing_store2, kLabSize); + CHECK(lab2.IsValid()); + + AllocationResult lab_backing_store3(HeapObject::FromAddress(base3)); + LocalAllocationBuffer lab3 = + LocalAllocationBuffer::FromResult(heap, lab_backing_store3, kLabSize); + CHECK(lab3.IsValid()); + + CHECK(!lab3.TryMerge(&lab1)); + } +} + + +#ifdef V8_HOST_ARCH_32_BIT +TEST(AllocateAligned) { + CcTest::InitializeVM(); + Heap* heap = CcTest::heap(); + const int kLabSize = 2 * KB; + Address base = AllocateLabBackingStore(heap, kLabSize); + Address limit = base + kLabSize; + std::pair<intptr_t, AllocationAlignment> sizes_raw[2] = { + std::make_pair(116, kWordAligned), std::make_pair(64, kDoubleAligned)}; + std::vector<std::pair<intptr_t, AllocationAlignment>> sizes(sizes_raw, + sizes_raw + 2); + intptr_t expected_sizes_raw[4] = {116, 4, 64, 1864}; + std::vector<intptr_t> expected_sizes(expected_sizes_raw, + expected_sizes_raw + 4); + + { + AllocationResult lab_backing_store(HeapObject::FromAddress(base)); + LocalAllocationBuffer lab = + LocalAllocationBuffer::FromResult(heap, lab_backing_store, kLabSize); + CHECK(lab.IsValid()); + for (auto pair : sizes) { + if (!AllocateFromLab(heap, &lab, pair.first, pair.second)) { + break; + } + } + } + VerifyIterable(base, limit, expected_sizes); +} +#endif // V8_HOST_ARCH_32_BIT + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/test/cctest/test-mark-compact.cc b/deps/v8/test/cctest/heap/test-mark-compact.cc index decf646b05..cfcf149c61 100644 --- a/deps/v8/test/cctest/test-mark-compact.cc +++ b/deps/v8/test/cctest/heap/test-mark-compact.cc @@ -42,7 +42,9 @@ #include "src/full-codegen/full-codegen.h" #include "src/global-handles.h" #include "test/cctest/cctest.h" -#include "test/cctest/heap-tester.h" +#include "test/cctest/heap/heap-tester.h" +#include "test/cctest/heap/utils-inl.h" + using namespace v8::internal; using v8::Just; @@ -239,7 +241,7 @@ static void WeakPointerCallback( std::pair<v8::Persistent<v8::Value>*, int>* p = reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>( data.GetParameter()); - DCHECK_EQ(1234, p->second); + CHECK_EQ(1234, p->second); NumberOfWeakCalls++; p->first->Reset(); } @@ -360,7 +362,7 @@ class TestRetainedObjectInfo : public v8::RetainedObjectInfo { bool has_been_disposed() { return has_been_disposed_; } virtual void Dispose() { - DCHECK(!has_been_disposed_); + CHECK(!has_been_disposed_); has_been_disposed_ = true; } @@ -385,7 +387,7 @@ TEST(EmptyObjectGroups) { TestRetainedObjectInfo info; global_handles->AddObjectGroup(NULL, 0, &info); - DCHECK(info.has_been_disposed()); + CHECK(info.has_been_disposed()); } diff --git a/deps/v8/test/cctest/test-spaces.cc b/deps/v8/test/cctest/heap/test-spaces.cc index cf053d0a9c..2fe099d2e3 100644 --- a/deps/v8/test/cctest/test-spaces.cc +++ b/deps/v8/test/cctest/heap/test-spaces.cc @@ -25,16 +25,14 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdlib.h> #include "src/base/platform/platform.h" #include "src/snapshot/snapshot.h" #include "src/v8.h" #include "test/cctest/cctest.h" -#include "test/cctest/heap-tester.h" +#include "test/cctest/heap/heap-tester.h" +#include "test/cctest/heap/utils-inl.h" namespace v8 { namespace internal { @@ -804,7 +802,7 @@ class Observer : public InlineAllocationObserver { explicit Observer(intptr_t step_size) : InlineAllocationObserver(step_size), count_(0) {} - virtual void Step(int bytes_allocated) { count_++; } + void Step(int bytes_allocated, Address, size_t) override { count_++; } int count() const { return count_; } @@ -834,13 +832,8 @@ UNINITIALIZED_TEST(InlineAllocationObserver) { AllocateUnaligned(new_space, 64); CHECK_EQ(observer1.count(), 0); - // The observer should not get called even when we have allocated exactly - // 128 bytes. + // The observer should get called when we have allocated exactly 128 bytes. AllocateUnaligned(new_space, 64); - CHECK_EQ(observer1.count(), 0); - - // The next allocation gets the notification. - AllocateUnaligned(new_space, 8); CHECK_EQ(observer1.count(), 1); // Another >128 bytes should get another notification. @@ -851,36 +844,83 @@ UNINITIALIZED_TEST(InlineAllocationObserver) { AllocateUnaligned(new_space, 1024); CHECK_EQ(observer1.count(), 3); - // Allocating another 2048 bytes in small objects should get 12 + // Allocating another 2048 bytes in small objects should get 16 // notifications. for (int i = 0; i < 64; ++i) { AllocateUnaligned(new_space, 32); } - CHECK_EQ(observer1.count(), 15); + CHECK_EQ(observer1.count(), 19); // Multiple observers should work. Observer observer2(96); new_space->AddInlineAllocationObserver(&observer2); AllocateUnaligned(new_space, 2048); - CHECK_EQ(observer1.count(), 16); + CHECK_EQ(observer1.count(), 20); CHECK_EQ(observer2.count(), 1); AllocateUnaligned(new_space, 104); - CHECK_EQ(observer1.count(), 16); + CHECK_EQ(observer1.count(), 20); CHECK_EQ(observer2.count(), 2); // Callback should stop getting called after an observer is removed. new_space->RemoveInlineAllocationObserver(&observer1); AllocateUnaligned(new_space, 384); - CHECK_EQ(observer1.count(), 16); // no more notifications. + CHECK_EQ(observer1.count(), 20); // no more notifications. CHECK_EQ(observer2.count(), 3); // this one is still active. + // Ensure that PauseInlineAllocationObserversScope work correctly. + AllocateUnaligned(new_space, 48); + CHECK_EQ(observer2.count(), 3); + { + PauseInlineAllocationObserversScope pause_observers(new_space); + CHECK_EQ(observer2.count(), 3); + AllocateUnaligned(new_space, 384); + CHECK_EQ(observer2.count(), 3); + } + CHECK_EQ(observer2.count(), 3); + // Coupled with the 48 bytes allocated before the pause, another 48 bytes + // allocated here should trigger a notification. + AllocateUnaligned(new_space, 48); + CHECK_EQ(observer2.count(), 4); + new_space->RemoveInlineAllocationObserver(&observer2); AllocateUnaligned(new_space, 384); - CHECK_EQ(observer1.count(), 16); - CHECK_EQ(observer2.count(), 3); + CHECK_EQ(observer1.count(), 20); + CHECK_EQ(observer2.count(), 4); + } + isolate->Dispose(); +} + + +UNINITIALIZED_TEST(InlineAllocationObserverCadence) { + v8::Isolate::CreateParams create_params; + create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); + v8::Isolate* isolate = v8::Isolate::New(create_params); + { + v8::Isolate::Scope isolate_scope(isolate); + v8::HandleScope handle_scope(isolate); + v8::Context::New(isolate)->Enter(); + + Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); + + NewSpace* new_space = i_isolate->heap()->new_space(); + + Observer observer1(512); + new_space->AddInlineAllocationObserver(&observer1); + Observer observer2(576); + new_space->AddInlineAllocationObserver(&observer2); + + for (int i = 0; i < 512; ++i) { + AllocateUnaligned(new_space, 32); + } + + new_space->RemoveInlineAllocationObserver(&observer1); + new_space->RemoveInlineAllocationObserver(&observer2); + + CHECK_EQ(observer1.count(), 32); + CHECK_EQ(observer2.count(), 28); } isolate->Dispose(); } diff --git a/deps/v8/test/cctest/heap/utils-inl.h b/deps/v8/test/cctest/heap/utils-inl.h new file mode 100644 index 0000000000..f255bb6c03 --- /dev/null +++ b/deps/v8/test/cctest/heap/utils-inl.h @@ -0,0 +1,137 @@ +// 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 HEAP_UTILS_H_ +#define HEAP_UTILS_H_ + +#include "src/factory.h" +#include "src/heap/heap-inl.h" +#include "src/heap/incremental-marking.h" +#include "src/heap/mark-compact.h" +#include "src/isolate.h" + + +namespace v8 { +namespace internal { + +static int LenFromSize(int size) { + return (size - FixedArray::kHeaderSize) / kPointerSize; +} + + +static inline std::vector<Handle<FixedArray>> CreatePadding( + Heap* heap, int padding_size, PretenureFlag tenure, + int object_size = Page::kMaxRegularHeapObjectSize) { + std::vector<Handle<FixedArray>> handles; + Isolate* isolate = heap->isolate(); + int allocate_memory; + int length; + int free_memory = padding_size; + if (tenure == i::TENURED) { + heap->old_space()->EmptyAllocationInfo(); + int overall_free_memory = static_cast<int>(heap->old_space()->Available()); + CHECK(padding_size <= overall_free_memory || overall_free_memory == 0); + } else { + heap->new_space()->DisableInlineAllocationSteps(); + int overall_free_memory = + static_cast<int>(*heap->new_space()->allocation_limit_address() - + *heap->new_space()->allocation_top_address()); + CHECK(padding_size <= overall_free_memory || overall_free_memory == 0); + } + while (free_memory > 0) { + if (free_memory > object_size) { + allocate_memory = object_size; + length = LenFromSize(allocate_memory); + } else { + allocate_memory = free_memory; + length = LenFromSize(allocate_memory); + if (length <= 0) { + // Not enough room to create another fixed array. Let's create a filler. + heap->CreateFillerObjectAt(*heap->old_space()->allocation_top_address(), + free_memory); + break; + } + } + handles.push_back(isolate->factory()->NewFixedArray(length, tenure)); + CHECK((tenure == NOT_TENURED && heap->InNewSpace(*handles.back())) || + (tenure == TENURED && heap->InOldSpace(*handles.back()))); + free_memory -= allocate_memory; + } + return handles; +} + + +// Helper function that simulates a full new-space in the heap. +static inline bool FillUpOnePage(v8::internal::NewSpace* space) { + space->DisableInlineAllocationSteps(); + int space_remaining = static_cast<int>(*space->allocation_limit_address() - + *space->allocation_top_address()); + if (space_remaining == 0) return false; + CreatePadding(space->heap(), space_remaining, i::NOT_TENURED); + return true; +} + + +// Helper function that simulates a fill new-space in the heap. +static inline void AllocateAllButNBytes(v8::internal::NewSpace* space, + int extra_bytes) { + space->DisableInlineAllocationSteps(); + int space_remaining = static_cast<int>(*space->allocation_limit_address() - + *space->allocation_top_address()); + CHECK(space_remaining >= extra_bytes); + int new_linear_size = space_remaining - extra_bytes; + if (new_linear_size == 0) return; + CreatePadding(space->heap(), new_linear_size, i::NOT_TENURED); +} + + +static inline void FillCurrentPage(v8::internal::NewSpace* space) { + AllocateAllButNBytes(space, 0); +} + + +static inline void SimulateFullSpace(v8::internal::NewSpace* space) { + FillCurrentPage(space); + while (FillUpOnePage(space)) { + } +} + + +// Helper function that simulates a full old-space in the heap. +static inline void SimulateFullSpace(v8::internal::PagedSpace* space) { + space->EmptyAllocationInfo(); + space->ResetFreeList(); + space->ClearStats(); +} + + +// Helper function that simulates many incremental marking steps until +// marking is completed. +static inline void SimulateIncrementalMarking(i::Heap* heap, + bool force_completion = true) { + i::MarkCompactCollector* collector = heap->mark_compact_collector(); + i::IncrementalMarking* marking = heap->incremental_marking(); + if (collector->sweeping_in_progress()) { + collector->EnsureSweepingCompleted(); + } + CHECK(marking->IsMarking() || marking->IsStopped()); + if (marking->IsStopped()) { + heap->StartIncrementalMarking(); + } + CHECK(marking->IsMarking()); + if (!force_completion) return; + + while (!marking->IsComplete()) { + marking->Step(i::MB, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD); + if (marking->IsReadyToOverApproximateWeakClosure()) { + marking->FinalizeIncrementally(); + } + } + CHECK(marking->IsComplete()); +} + +} // namespace internal +} // namespace v8 + +#endif // HEAP_UTILS_H_ diff --git a/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc b/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc index c29eb9659d..2c06da26a1 100644 --- a/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc +++ b/deps/v8/test/cctest/interpreter/test-bytecode-generator.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(rmcilroy): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "src/compiler.h" @@ -26,12 +23,13 @@ class BytecodeGeneratorHelper { -InterpreterFrameConstants::kLastParamFromRegisterPointer / kPointerSize; BytecodeGeneratorHelper() { - i::FLAG_vector_stores = true; i::FLAG_ignition = true; i::FLAG_ignition_fake_try_catch = true; + i::FLAG_ignition_fallback_on_eval_and_catch = false; i::FLAG_ignition_filter = StrDup(kFunctionName); i::FLAG_always_opt = false; i::FLAG_allow_natives_syntax = true; + i::FLAG_legacy_const = true; CcTest::i_isolate()->interpreter()->Initialize(); } @@ -59,10 +57,22 @@ class BytecodeGeneratorHelper { return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); } + Handle<BytecodeArray> MakeBytecode(const char* script, const char* filter, + const char* function_name) { + const char* old_ignition_filter = i::FLAG_ignition_filter; + i::FLAG_ignition_filter = filter; + Handle<BytecodeArray> return_val = MakeBytecode(script, function_name); + i::FLAG_ignition_filter = old_ignition_filter; + return return_val; + } + Handle<BytecodeArray> MakeBytecodeForFunctionBody(const char* body) { - ScopedVector<char> program(3072); - SNPrintF(program, "function %s() { %s }\n%s();", kFunctionName, body, - kFunctionName); + static const char kFormat[] = "function %s() { %s }\n%s();"; + static const int kFormatLength = arraysize(kFormat); + int length = kFormatLength + 2 * StrLength(kFunctionName) + StrLength(body); + ScopedVector<char> program(length); + length = SNPrintF(program, kFormat, kFunctionName, body, kFunctionName); + CHECK_GT(length, 0); return MakeBytecode(program.start(), kFunctionName); } @@ -73,14 +83,9 @@ class BytecodeGeneratorHelper { } Handle<BytecodeArray> MakeBytecodeForFunctionNoFilter(const char* function) { - const char* old_ignition_filter = i::FLAG_ignition_filter; - i::FLAG_ignition_filter = "*"; ScopedVector<char> program(3072); SNPrintF(program, "%s\n%s();", function, kFunctionName); - Handle<BytecodeArray> return_val = - MakeBytecode(program.start(), kFunctionName); - i::FLAG_ignition_filter = old_ignition_filter; - return return_val; + return MakeBytecode(program.start(), "*", kFunctionName); } }; @@ -94,17 +99,25 @@ class BytecodeGeneratorHelper { #if defined(V8_TARGET_LITTLE_ENDIAN) #define U16(x) static_cast<uint8_t>((x) & 0xff), \ static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff) +#define U16I(x) static_cast<uint8_t>((x) & 0xff), \ + static_cast<uint8_t>(((x++) >> kBitsPerByte) & 0xff) #elif defined(V8_TARGET_BIG_ENDIAN) #define U16(x) static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff), \ static_cast<uint8_t>((x) & 0xff) +#define U16I(x) static_cast<uint8_t>(((x) >> kBitsPerByte) & 0xff), \ + static_cast<uint8_t>((x++) & 0xff) #else #error Unknown byte ordering #endif +#define XSTR(A) #A +#define STR(A) XSTR(A) + #define COMMA() , #define SPACE() +#define UNIQUE_VAR() "var a" STR(__COUNTER__) " = 0;\n" -#define REPEAT_2(SEP, ...) \ +#define REPEAT_2(SEP, ...) \ __VA_ARGS__ SEP() __VA_ARGS__ #define REPEAT_4(SEP, ...) \ REPEAT_2(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) @@ -127,6 +140,16 @@ class BytecodeGeneratorHelper { REPEAT_4(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) SEP() \ __VA_ARGS__ +#define REPEAT_249(SEP, ...) \ + REPEAT_127(SEP, __VA_ARGS__) SEP() REPEAT_64(SEP, __VA_ARGS__) SEP() \ + REPEAT_32(SEP, __VA_ARGS__) SEP() REPEAT_16(SEP, __VA_ARGS__) SEP() \ + REPEAT_8(SEP, __VA_ARGS__) SEP() REPEAT_2(SEP, __VA_ARGS__) + +#define REPEAT_249_UNIQUE_VARS() \ +UNIQUE_VAR() REPEAT_127(UNIQUE_VAR) UNIQUE_VAR() REPEAT_64(UNIQUE_VAR) \ +UNIQUE_VAR() REPEAT_32(UNIQUE_VAR) UNIQUE_VAR() REPEAT_16(UNIQUE_VAR) \ +UNIQUE_VAR() REPEAT_8(UNIQUE_VAR) UNIQUE_VAR() REPEAT_2(UNIQUE_VAR) + // Structure for containing expected bytecode snippets. template<typename T, int C = 6> struct ExpectedSnippet { @@ -264,124 +287,134 @@ TEST(PrimitiveExpressions) { {"var x = 0; return x;", kPointerSize, 1, - 6, + 4, {B(LdaZero), // B(Star), R(0), // - B(Ldar), R(0), // B(Return)}, 0}, {"var x = 0; return x + 3;", - kPointerSize, + 2 * kPointerSize, 1, - 8, + 10, {B(LdaZero), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(3), // - B(Add), R(0), // + B(Add), R(1), // B(Return)}, 0}, {"var x = 0; return x - 3;", - kPointerSize, + 2 * kPointerSize, 1, - 8, + 10, {B(LdaZero), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(3), // - B(Sub), R(0), // + B(Sub), R(1), // B(Return)}, 0}, {"var x = 4; return x * 3;", - kPointerSize, + 2 * kPointerSize, 1, - 9, + 11, {B(LdaSmi8), U8(4), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(3), // - B(Mul), R(0), // + B(Mul), R(1), // B(Return)}, 0}, {"var x = 4; return x / 3;", - kPointerSize, + 2 * kPointerSize, 1, - 9, + 11, {B(LdaSmi8), U8(4), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(3), // - B(Div), R(0), // + B(Div), R(1), // B(Return)}, 0}, {"var x = 4; return x % 3;", - kPointerSize, + 2 * kPointerSize, 1, - 9, + 11, {B(LdaSmi8), U8(4), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(3), // - B(Mod), R(0), // + B(Mod), R(1), // B(Return)}, 0}, {"var x = 1; return x | 2;", - kPointerSize, + 2 * kPointerSize, 1, - 9, + 11, {B(LdaSmi8), U8(1), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(2), // - B(BitwiseOr), R(0), // + B(BitwiseOr), R(1), // B(Return)}, 0}, {"var x = 1; return x ^ 2;", - kPointerSize, + 2 * kPointerSize, 1, - 9, + 11, {B(LdaSmi8), U8(1), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(2), // - B(BitwiseXor), R(0), // + B(BitwiseXor), R(1), // B(Return)}, 0}, {"var x = 1; return x & 2;", - kPointerSize, + 2 * kPointerSize, 1, - 9, + 11, {B(LdaSmi8), U8(1), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(2), // - B(BitwiseAnd), R(0), // + B(BitwiseAnd), R(1), // B(Return)}, 0}, {"var x = 10; return x << 3;", - kPointerSize, + 2 * kPointerSize, 1, - 9, + 11, {B(LdaSmi8), U8(10), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(3), // - B(ShiftLeft), R(0), // + B(ShiftLeft), R(1), // B(Return)}, 0}, {"var x = 10; return x >> 3;", - kPointerSize, + 2 * kPointerSize, 1, - 9, + 11, {B(LdaSmi8), U8(10), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(3), // - B(ShiftRight), R(0), // + B(ShiftRight), R(1), // B(Return)}, 0}, {"var x = 10; return x >>> 3;", - kPointerSize, + 2 * kPointerSize, 1, - 9, + 11, {B(LdaSmi8), U8(10), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(3), // - B(ShiftRightLogical), R(0), // + B(ShiftRightLogical), R(1), // B(Return)}, 0}, {"var x = 0; return (x, 3);", - kPointerSize, + 1 * kPointerSize, 1, 6, {B(LdaZero), // @@ -402,27 +435,26 @@ TEST(LogicalExpressions) { InitializedHandleScope handle_scope; BytecodeGeneratorHelper helper; - ExpectedSnippet<int> snippets[] = { {"var x = 0; return x || 3;", 1 * kPointerSize, 1, - 10, + 8, {B(LdaZero), // B(Star), R(0), // - B(Ldar), R(0), // B(JumpIfToBooleanTrue), U8(4), // B(LdaSmi8), U8(3), // B(Return)}, 0}, {"var x = 0; return (x == 1) || 3;", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 12, + 14, {B(LdaZero), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(1), // - B(TestEqual), R(0), // + B(TestEqual), R(1), // B(JumpIfTrue), U8(4), // B(LdaSmi8), U8(3), // B(Return)}, @@ -430,22 +462,22 @@ TEST(LogicalExpressions) { {"var x = 0; return x && 3;", 1 * kPointerSize, 1, - 10, + 8, {B(LdaZero), // B(Star), R(0), // - B(Ldar), R(0), // B(JumpIfToBooleanFalse), U8(4), // B(LdaSmi8), U8(3), // B(Return)}, 0}, {"var x = 0; return (x == 0) && 3;", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 11, + 13, {B(LdaZero), // B(Star), R(0), // + B(Star), R(1), // B(LdaZero), // - B(TestEqual), R(0), // + B(TestEqual), R(1), // B(JumpIfFalse), U8(4), // B(LdaSmi8), U8(3), // B(Return)}, @@ -453,10 +485,9 @@ TEST(LogicalExpressions) { {"var x = 0; return x || (1, 2, 3);", 1 * kPointerSize, 1, - 10, + 8, {B(LdaZero), // B(Star), R(0), // - B(Ldar), R(0), // B(JumpIfToBooleanTrue), U8(4), // B(LdaSmi8), U8(3), // B(Return)}, @@ -464,18 +495,22 @@ TEST(LogicalExpressions) { {"var a = 2, b = 3, c = 4; return a || (a, b, a, b, c = 5, 3);", 3 * kPointerSize, 1, - 23, - {B(LdaSmi8), U8(2), // - B(Star), R(0), // - B(LdaSmi8), U8(3), // - B(Star), R(1), // - B(LdaSmi8), U8(4), // - B(Star), R(2), // - B(Ldar), R(0), // - B(JumpIfToBooleanTrue), U8(8), // - B(LdaSmi8), U8(5), // - B(Star), R(2), // - B(LdaSmi8), U8(3), // + 31, + {B(LdaSmi8), U8(2), // + B(Star), R(0), // + B(LdaSmi8), U8(3), // + B(Star), R(1), // + B(LdaSmi8), U8(4), // + B(Star), R(2), // + B(Ldar), R(0), // + B(JumpIfToBooleanTrue), U8(16), // + B(Ldar), R(0), // + B(Ldar), R(1), // + B(Ldar), R(0), // + B(Ldar), R(1), // + B(LdaSmi8), U8(5), // + B(Star), R(2), // + B(LdaSmi8), U8(3), // B(Return)}, 0}, {"var x = 1; var a = 2, b = 3; return x || (" @@ -493,10 +528,10 @@ TEST(LogicalExpressions) { B(Ldar), R(0), // B(JumpIfToBooleanTrueConstant), U8(0), // REPEAT_32(COMMA, // - B(LdaSmi8), U8(1), // - B(Star), R(1), // - B(LdaSmi8), U8(2), // - B(Star), R(2)), // + B(LdaSmi8), U8(1), // + B(Star), R(1), // + B(LdaSmi8), U8(2), // + B(Star), R(2)), // B(LdaSmi8), U8(3), // B(Return)}, 1, @@ -516,10 +551,10 @@ TEST(LogicalExpressions) { B(Ldar), R(0), // B(JumpIfToBooleanFalseConstant), U8(0), // REPEAT_32(COMMA, // - B(LdaSmi8), U8(1), // - B(Star), R(1), // - B(LdaSmi8), U8(2), // - B(Star), R(2)), // + B(LdaSmi8), U8(1), // + B(Star), R(1), // + B(LdaSmi8), U8(2), // + B(Star), R(2)), // B(LdaSmi8), U8(3), // B(Return)}, // 1, @@ -527,23 +562,25 @@ TEST(LogicalExpressions) { {"var x = 1; var a = 2, b = 3; return (x > 3) || (" REPEAT_32(SPACE, "a = 1, b = 2, ") "3);", - 3 * kPointerSize, + 4 * kPointerSize, 1, - 277, + 281, {B(LdaSmi8), U8(1), // B(Star), R(0), // B(LdaSmi8), U8(2), // B(Star), R(1), // B(LdaSmi8), U8(3), // B(Star), R(2), // + B(Ldar), R(0), // + B(Star), R(3), // B(LdaSmi8), U8(3), // - B(TestGreaterThan), R(0), // + B(TestGreaterThan), R(3), // B(JumpIfTrueConstant), U8(0), // REPEAT_32(COMMA, // - B(LdaSmi8), U8(1), // - B(Star), R(1), // - B(LdaSmi8), U8(2), // - B(Star), R(2)), // + B(LdaSmi8), U8(1), // + B(Star), R(1), // + B(LdaSmi8), U8(2), // + B(Star), R(2)), // B(LdaSmi8), U8(3), // B(Return)}, 1, @@ -551,23 +588,25 @@ TEST(LogicalExpressions) { {"var x = 0; var a = 2, b = 3; return (x < 5) && (" REPEAT_32(SPACE, "a = 1, b = 2, ") "3);", - 3 * kPointerSize, + 4 * kPointerSize, 1, - 276, + 280, {B(LdaZero), // B(Star), R(0), // B(LdaSmi8), U8(2), // B(Star), R(1), // B(LdaSmi8), U8(3), // B(Star), R(2), // + B(Ldar), R(0), // + B(Star), R(3), // B(LdaSmi8), U8(5), // - B(TestLessThan), R(0), // + B(TestLessThan), R(3), // B(JumpIfFalseConstant), U8(0), // REPEAT_32(COMMA, // - B(LdaSmi8), U8(1), // - B(Star), R(1), // - B(LdaSmi8), U8(2), // - B(Star), R(2)), // + B(LdaSmi8), U8(1), // + B(Star), R(1), // + B(LdaSmi8), U8(2), // + B(Star), R(2)), // B(LdaSmi8), U8(3), // B(Return)}, 1, @@ -589,10 +628,9 @@ TEST(LogicalExpressions) { {"var x = 1; return x && 3 || 0, 1;", 1 * kPointerSize, 1, - 16, + 14, {B(LdaSmi8), U8(1), // B(Star), R(0), // - B(Ldar), R(0), // B(JumpIfToBooleanFalse), U8(4), // B(LdaSmi8), U8(3), // B(JumpIfToBooleanTrue), U8(3), // @@ -856,154 +894,205 @@ TEST(PropertyLoads) { ExpectedSnippet<const char*> snippets[] = { {"function f(a) { return a.name; }\nf({name : \"test\"})", - 0, + 1 * kPointerSize, 2, - 5, + 9, { - B(LoadICSloppy), A(1, 2), U8(0), U8(vector->GetIndex(slot1)), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LoadICSloppy), R(0), U8(0), U8(vector->GetIndex(slot1)), // + B(Return), // }, 1, {"name"}}, {"function f(a) { return a[\"key\"]; }\nf({key : \"test\"})", - 0, + 1 * kPointerSize, 2, - 5, + 9, { - B(LoadICSloppy), A(1, 2), U8(0), U8(vector->GetIndex(slot1)), // - B(Return) // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LoadICSloppy), R(0), U8(0), U8(vector->GetIndex(slot1)), // + B(Return) // }, 1, {"key"}}, {"function f(a) { return a[100]; }\nf({100 : \"test\"})", - 0, + 1 * kPointerSize, 2, - 6, + 10, { - B(LdaSmi8), U8(100), // - B(KeyedLoadICSloppy), A(1, 2), U8(vector->GetIndex(slot1)), // - B(Return) // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LdaSmi8), U8(100), // + B(KeyedLoadICSloppy), R(0), U8(vector->GetIndex(slot1)), // + B(Return) // }, 0}, {"function f(a, b) { return a[b]; }\nf({arg : \"test\"}, \"arg\")", - 0, + 1 * kPointerSize, 3, - 6, + 10, { - B(Ldar), A(1, 2), // - B(KeyedLoadICSloppy), A(1, 3), U8(vector->GetIndex(slot1)), // - B(Return) // + B(Ldar), A(1, 3), // + B(Star), R(0), // + B(Ldar), A(1, 2), // + B(KeyedLoadICSloppy), R(0), U8(vector->GetIndex(slot1)), // + B(Return) // }, 0}, {"function f(a) { var b = a.name; return a[-124]; }\n" "f({\"-124\" : \"test\", name : 123 })", - kPointerSize, + 2 * kPointerSize, 2, - 12, + 20, { - B(LoadICSloppy), A(1, 2), U8(0), U8(vector->GetIndex(slot1)), // - B(Star), R(0), // - B(LdaSmi8), U8(-124), // - B(KeyedLoadICSloppy), A(1, 2), U8(vector->GetIndex(slot2)), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(1), // + B(LoadICSloppy), R(1), U8(0), U8(vector->GetIndex(slot1)), // + B(Star), R(0), // + B(Ldar), A(1, 2), // + B(Star), R(1), // + B(LdaSmi8), U8(-124), // + B(KeyedLoadICSloppy), R(1), U8(vector->GetIndex(slot2)), // + B(Return), // }, 1, {"name"}}, {"function f(a) { \"use strict\"; return a.name; }\nf({name : \"test\"})", - 0, + 1 * kPointerSize, 2, - 5, + 9, { - B(LoadICStrict), A(1, 2), U8(0), U8(vector->GetIndex(slot1)), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LoadICStrict), R(0), U8(0), U8(vector->GetIndex(slot1)), // + B(Return), // }, 1, {"name"}}, - { - "function f(a, b) { \"use strict\"; return a[b]; }\n" - "f({arg : \"test\"}, \"arg\")", - 0, - 3, - 6, - { - B(Ldar), A(2, 3), // - B(KeyedLoadICStrict), A(1, 3), U8(vector->GetIndex(slot1)), // - B(Return), // - }, - 0}, - { - "function f(a) {\n" - " var b;\n" - REPEAT_127(SPACE, " b = a.name; ") - " return a.name; }\n" - "f({name : \"test\"})\n", - 1 * kPointerSize, - 2, - 769, - { - REPEAT_127(COMMA, // - B(LoadICSloppy), A(1, 2), U8(0), U8((wide_idx_1 += 2)), // - B(Star), R(0)), // - B(LoadICSloppyWide), A(1, 2), U16(0), U16(wide_idx_1 + 2), // - B(Return), // - }, - 1, - {"name"}}, - { - "function f(a) {\n" - " 'use strict'; var b;\n" - REPEAT_127(SPACE, " b = a.name; ") - " return a.name; }\n" - "f({name : \"test\"})\n", - 1 * kPointerSize, - 2, - 769, - { - REPEAT_127(COMMA, // - B(LoadICStrict), A(1, 2), U8(0), U8((wide_idx_2 += 2)), // - B(Star), R(0)), // - B(LoadICStrictWide), A(1, 2), U16(0), U16(wide_idx_2 + 2), // - B(Return), // - }, - 1, - {"name"}}, - { - "function f(a, b) {\n" - " var c;\n" - REPEAT_127(SPACE, " c = a[b]; ") - " return a[b]; }\n" - "f({name : \"test\"}, \"name\")\n", - 1 * kPointerSize, - 3, - 896, - { - REPEAT_127(COMMA, // - B(Ldar), A(2, 3), // - B(KeyedLoadICSloppy), A(1, 3), U8((wide_idx_3 += 2)), // - B(Star), R(0)), // - B(Ldar), A(2, 3), // - B(KeyedLoadICSloppyWide), A(1, 3), U16(wide_idx_3 + 2), // - B(Return), // - }}, - { - "function f(a, b) {\n" - " 'use strict'; var c;\n" - REPEAT_127(SPACE, " c = a[b]; ") - " return a[b]; }\n" - "f({name : \"test\"}, \"name\")\n", - 1 * kPointerSize, - 3, - 896, - { - REPEAT_127(COMMA, // - B(Ldar), A(2, 3), // - B(KeyedLoadICStrict), A(1, 3), U8((wide_idx_4 += 2)), // - B(Star), R(0)), // - B(Ldar), A(2, 3), // - B(KeyedLoadICStrictWide), A(1, 3), U16(wide_idx_4 + 2), // - B(Return), // - }}, - }; + {"function f(a, b) { \"use strict\"; return a[b]; }\n" + "f({arg : \"test\"}, \"arg\")", + 1 * kPointerSize, + 3, + 10, + { + B(Ldar), A(1, 3), // + B(Star), R(0), // + B(Ldar), A(2, 3), // + B(KeyedLoadICStrict), R(0), U8(vector->GetIndex(slot1)), // + B(Return), // + }, + 0}, + {"function f(a) {\n" + " var b;\n" + "b = a.name;" + REPEAT_127(SPACE, " b = a.name; ") + " return a.name; }\n" + "f({name : \"test\"})\n", + 2 * kPointerSize, + 2, + 1291, + { + B(Ldar), A(1, 2), // + B(Star), R(1), // + B(LoadICSloppy), R(1), U8(0), U8(wide_idx_1 += 2), // + B(Star), R(0), // + REPEAT_127(COMMA, // + B(Ldar), A(1, 2), // + B(Star), R(1), // + B(LoadICSloppy), R(1), U8(0), // + U8((wide_idx_1 += 2)), // + B(Star), R(0)), // + B(Ldar), A(1, 2), // + B(Star), R(1), // + B(LoadICSloppyWide), R(1), U16(0), U16(wide_idx_1 + 2), // + B(Return), // + }, + 1, + {"name"}}, + {"function f(a) {\n" + " 'use strict'; var b;\n" + " b = a.name;\n" + REPEAT_127(SPACE, " b = a.name; ") + " return a.name; }\n" + "f({name : \"test\"})\n", + 2 * kPointerSize, + 2, + 1291, + { + B(Ldar), A(1, 2), // + B(Star), R(1), // + B(LoadICStrict), R(1), U8(0), U8((wide_idx_2 += 2)), // + B(Star), R(0), // + REPEAT_127(COMMA, // + B(Ldar), A(1, 2), // + B(Star), R(1), // + B(LoadICStrict), R(1), U8(0), // + U8((wide_idx_2 += 2)), // + B(Star), R(0)), // + B(Ldar), A(1, 2), // + B(Star), R(1), // + B(LoadICStrictWide), R(1), U16(0), U16(wide_idx_2 + 2), // + B(Return), // + }, + 1, + {"name"}}, + {"function f(a, b) {\n" + " var c;\n" + " c = a[b];" + REPEAT_127(SPACE, " c = a[b]; ") + " return a[b]; }\n" + "f({name : \"test\"}, \"name\")\n", + 2 * kPointerSize, + 3, + 1419, + { + B(Ldar), A(1, 3), // + B(Star), R(1), // + B(Ldar), A(2, 3), // + B(KeyedLoadICSloppy), R(1), U8((wide_idx_3 += 2)), // + B(Star), R(0), // + REPEAT_127(COMMA, // + B(Ldar), A(1, 3), // + B(Star), R(1), // + B(Ldar), A(2, 3), // + B(KeyedLoadICSloppy), R(1), U8((wide_idx_3 += 2)), // + B(Star), R(0)), // + B(Ldar), A(1, 3), // + B(Star), R(1), // + B(Ldar), A(2, 3), // + B(KeyedLoadICSloppyWide), R(1), U16(wide_idx_3 + 2), // + B(Return), // + }}, + {"function f(a, b) {\n" + " 'use strict'; var c;\n" + " c = a[b];" + REPEAT_127(SPACE, " c = a[b]; ") + " return a[b]; }\n" + "f({name : \"test\"}, \"name\")\n", + 2 * kPointerSize, + 3, + 1419, + { + B(Ldar), A(1, 3), // + B(Star), R(1), // + B(Ldar), A(2, 3), // + B(KeyedLoadICStrict), R(1), U8((wide_idx_4 += 2)), // + B(Star), R(0), // + REPEAT_127(COMMA, // + B(Ldar), A(1, 3), // + B(Star), R(1), // + B(Ldar), A(2, 3), // + B(KeyedLoadICStrict), R(1), U8((wide_idx_4 += 2)), // + B(Star), R(0)), // + B(Ldar), A(1, 3), // + B(Star), R(1), // + B(Ldar), A(2, 3), // + B(KeyedLoadICStrictWide), R(1), U16(wide_idx_4 + 2), // + B(Return), // + }}, + }; for (size_t i = 0; i < arraysize(snippets); i++) { Handle<BytecodeArray> bytecode_array = helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName); @@ -1032,171 +1121,238 @@ TEST(PropertyStores) { ExpectedSnippet<const char*> snippets[] = { {"function f(a) { a.name = \"val\"; }\nf({name : \"test\"})", - 0, + kPointerSize, 2, - 8, + 12, { - B(LdaConstant), U8(1), // - B(StoreICSloppy), A(1, 2), U8(0), U8(vector->GetIndex(slot1)), // - B(LdaUndefined), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LdaConstant), U8(0), // + B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), // + B(LdaUndefined), // + B(Return), // }, 2, - {"name", "val"}}, + {"val", "name"}}, {"function f(a) { a[\"key\"] = \"val\"; }\nf({key : \"test\"})", - 0, + kPointerSize, 2, - 8, + 12, { - B(LdaConstant), U8(1), // - B(StoreICSloppy), A(1, 2), U8(0), U8(vector->GetIndex(slot1)), // - B(LdaUndefined), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LdaConstant), U8(0), // + B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), // + B(LdaUndefined), // + B(Return), // }, 2, - {"key", "val"}}, + {"val", "key"}}, {"function f(a) { a[100] = \"val\"; }\nf({100 : \"test\"})", - kPointerSize, + 2 * kPointerSize, 2, - 12, + 16, { - B(LdaSmi8), U8(100), // - B(Star), R(0), // - B(LdaConstant), U8(0), // - B(KeyedStoreICSloppy), A(1, 2), R(0), // - U8(vector->GetIndex(slot1)), // - B(LdaUndefined), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LdaSmi8), U8(100), // + B(Star), R(1), // + B(LdaConstant), U8(0), // + B(KeyedStoreICSloppy), R(0), R(1), // + U8(vector->GetIndex(slot1)), // + B(LdaUndefined), // + B(Return), // }, 1, {"val"}}, {"function f(a, b) { a[b] = \"val\"; }\nf({arg : \"test\"}, \"arg\")", - 0, + 2 * kPointerSize, 3, - 8, + 16, { - B(LdaConstant), U8(0), // - B(KeyedStoreICSloppy), A(1, 3), A(2, 3), // - U8(vector->GetIndex(slot1)), // - B(LdaUndefined), // - B(Return), // + B(Ldar), A(1, 3), // + B(Star), R(0), // + B(Ldar), A(2, 3), // + B(Star), R(1), // + B(LdaConstant), U8(0), // + B(KeyedStoreICSloppy), R(0), R(1), // + U8(vector->GetIndex(slot1)), // + B(LdaUndefined), // + B(Return), // }, 1, {"val"}}, {"function f(a) { a.name = a[-124]; }\n" "f({\"-124\" : \"test\", name : 123 })", - 0, + 2 * kPointerSize, 2, - 11, + 19, { - B(LdaSmi8), U8(-124), // - B(KeyedLoadICSloppy), A(1, 2), U8(vector->GetIndex(slot1)), // - B(StoreICSloppy), A(1, 2), U8(0), U8(vector->GetIndex(slot2)), // - B(LdaUndefined), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(Ldar), A(1, 2), // + B(Star), R(1), // + B(LdaSmi8), U8(-124), // + B(KeyedLoadICSloppy), R(1), U8(vector->GetIndex(slot1)), // + B(StoreICSloppy), R(0), U8(0), U8(vector->GetIndex(slot2)), // + B(LdaUndefined), // + B(Return), // }, 1, {"name"}}, {"function f(a) { \"use strict\"; a.name = \"val\"; }\n" "f({name : \"test\"})", - 0, + kPointerSize, 2, - 8, + 12, { - B(LdaConstant), U8(1), // - B(StoreICStrict), A(1, 2), U8(0), U8(vector->GetIndex(slot1)), // - B(LdaUndefined), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LdaConstant), U8(0), // + B(StoreICStrict), R(0), U8(1), U8(vector->GetIndex(slot1)), // + B(LdaUndefined), // + B(Return), // }, 2, - {"name", "val"}}, + {"val", "name"}}, {"function f(a, b) { \"use strict\"; a[b] = \"val\"; }\n" "f({arg : \"test\"}, \"arg\")", - 0, + 2 * kPointerSize, 3, - 8, + 16, { - B(LdaConstant), U8(0), // - B(KeyedStoreICStrict), A(1, 3), A(2, 3), // - U8(vector->GetIndex(slot1)), // - B(LdaUndefined), // - B(Return), // + B(Ldar), A(1, 3), // + B(Star), R(0), // + B(Ldar), A(2, 3), // + B(Star), R(1), // + B(LdaConstant), U8(0), // + B(KeyedStoreICStrict), R(0), R(1), U8(vector->GetIndex(slot1)), // + B(LdaUndefined), // + B(Return), // }, 1, {"val"}}, {"function f(a) {\n" + "a.name = 1;" REPEAT_127(SPACE, " a.name = 1; ") " a.name = 2; }\n" "f({name : \"test\"})\n", - 0, + kPointerSize, 2, - 772, + 1294, { - REPEAT_127(COMMA, // - B(LdaSmi8), U8(1), // - B(StoreICSloppy), A(1, 2), U8(0), U8((wide_idx_1 += 2))), // - B(LdaSmi8), U8(2), // - B(StoreICSloppyWide), A(1, 2), U16(0), U16(wide_idx_1 + 2), // - B(LdaUndefined), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LdaSmi8), U8(1), // + B(StoreICSloppy), R(0), U8(0), U8((wide_idx_1 += 2)), // + REPEAT_127(COMMA, // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LdaSmi8), U8(1), // + B(StoreICSloppy), R(0), U8(0), // + U8((wide_idx_1 += 2))), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LdaSmi8), U8(2), // + B(StoreICSloppyWide), R(0), U16(0), U16(wide_idx_1 + 2), // + B(LdaUndefined), // + B(Return), // }, 1, {"name"}}, {"function f(a) {\n" - "'use strict';\n" + " 'use strict';\n" + " a.name = 1;" REPEAT_127(SPACE, " a.name = 1; ") " a.name = 2; }\n" "f({name : \"test\"})\n", - 0, + kPointerSize, 2, - 772, + 1294, { - REPEAT_127(COMMA, // - B(LdaSmi8), U8(1), // - B(StoreICStrict), A(1, 2), U8(0), U8((wide_idx_2 += 2))), // - B(LdaSmi8), U8(2), // - B(StoreICStrictWide), A(1, 2), U16(0), U16(wide_idx_2 + 2), // - B(LdaUndefined), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LdaSmi8), U8(1), // + B(StoreICStrict), R(0), U8(0), U8(wide_idx_2 += 2), // + REPEAT_127(COMMA, // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LdaSmi8), U8(1), // + B(StoreICStrict), R(0), U8(0), // + U8((wide_idx_2 += 2))), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LdaSmi8), U8(2), // + B(StoreICStrictWide), R(0), U16(0), U16(wide_idx_2 + 2), // + B(LdaUndefined), // + B(Return), // }, 1, {"name"}}, {"function f(a, b) {\n" - REPEAT_127(SPACE, " a[b] = 1; ") + " a[b] = 1;" + REPEAT_127(SPACE, " a[b] = 1; ") " a[b] = 2; }\n" "f({name : \"test\"})\n", - 0, + 2 * kPointerSize, 3, - 771, - { - REPEAT_127(COMMA, // - B(LdaSmi8), U8(1), // - B(KeyedStoreICSloppy), A(1, 3), A(2, 3), // - U8((wide_idx_3 += 2))), // - B(LdaSmi8), U8(2), // - B(KeyedStoreICSloppyWide), A(1, 3), A(2, 3), // - U16(wide_idx_3 + 2), // - B(LdaUndefined), // - B(Return), // + 1809, + { + B(Ldar), A(1, 3), // + B(Star), R(0), // + B(Ldar), A(2, 3), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(KeyedStoreICSloppy), R(0), R(1), U8(wide_idx_3 += 2), // + REPEAT_127(COMMA, // + B(Ldar), A(1, 3), // + B(Star), R(0), // + B(Ldar), A(2, 3), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(KeyedStoreICSloppy), R(0), R(1), // + U8((wide_idx_3 += 2))), // + B(Ldar), A(1, 3), // + B(Star), R(0), // + B(Ldar), A(2, 3), // + B(Star), R(1), // + B(LdaSmi8), U8(2), // + B(KeyedStoreICSloppyWide), R(0), R(1), U16(wide_idx_3 + 2), // + B(LdaUndefined), // + B(Return), // }}, {"function f(a, b) {\n" - "'use strict';\n" - REPEAT_127(SPACE, " a[b] = 1; ") + " 'use strict';\n" + " a[b] = 1;" + REPEAT_127(SPACE, " a[b] = 1; ") " a[b] = 2; }\n" "f({name : \"test\"})\n", - 0, + 2 * kPointerSize, 3, - 771, - { - REPEAT_127(COMMA, // - B(LdaSmi8), U8(1), // - B(KeyedStoreICStrict), A(1, 3), A(2, 3), // - U8((wide_idx_4 += 2))), // - B(LdaSmi8), U8(2), // - B(KeyedStoreICStrictWide), A(1, 3), A(2, 3), // - U16(wide_idx_4 + 2), // - B(LdaUndefined), // - B(Return), // + 1809, + { + B(Ldar), A(1, 3), // + B(Star), R(0), // + B(Ldar), A(2, 3), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(KeyedStoreICStrict), R(0), R(1), U8(wide_idx_4 += 2), // + REPEAT_127(COMMA, // + B(Ldar), A(1, 3), // + B(Star), R(0), // + B(Ldar), A(2, 3), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(KeyedStoreICStrict), R(0), R(1), // + U8((wide_idx_4 += 2))), // + B(Ldar), A(1, 3), // + B(Star), R(0), // + B(Ldar), A(2, 3), // + B(Star), R(1), // + B(LdaSmi8), U8(2), // + B(KeyedStoreICStrictWide), R(0), R(1), U16(wide_idx_4 + 2), // + B(LdaUndefined), // + B(Return), // }}}; for (size_t i = 0; i < arraysize(snippets); i++) { Handle<BytecodeArray> bytecode_array = @@ -1215,24 +1371,26 @@ TEST(PropertyCall) { Zone zone; FeedbackVectorSpec feedback_spec(&zone); - FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); + FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot(); FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); - USE(slot1); Handle<i::TypeFeedbackVector> vector = i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); + // These are a hack used by the CallWide test below. + int wide_idx = vector->GetIndex(slot1) - 2; + ExpectedSnippet<const char*> snippets[] = { {"function f(a) { return a.func(); }\nf(" FUNC_ARG ")", 2 * kPointerSize, 2, - 15, + 16, { B(Ldar), A(1, 2), // B(Star), R(1), // B(LoadICSloppy), R(1), U8(0), U8(vector->GetIndex(slot2)), // B(Star), R(0), // - B(Call), R(0), R(1), U8(0), // + B(Call), R(0), R(1), U8(0), U8(vector->GetIndex(slot1)), // B(Return), // }, 1, @@ -1240,7 +1398,7 @@ TEST(PropertyCall) { {"function f(a, b, c) { return a.func(b, c); }\nf(" FUNC_ARG ", 1, 2)", 4 * kPointerSize, 4, - 23, + 24, { B(Ldar), A(1, 4), // B(Star), R(1), // @@ -1250,7 +1408,7 @@ TEST(PropertyCall) { B(Star), R(2), // B(Ldar), A(3, 4), // B(Star), R(3), // - B(Call), R(0), R(1), U8(2), // + B(Call), R(0), R(1), U8(2), U8(vector->GetIndex(slot1)), // B(Return) // }, 1, @@ -1258,22 +1416,49 @@ TEST(PropertyCall) { {"function f(a, b) { return a.func(b + b, b); }\nf(" FUNC_ARG ", 1)", 4 * kPointerSize, 3, - 25, + 30, { B(Ldar), A(1, 3), // B(Star), R(1), // B(LoadICSloppy), R(1), U8(0), U8(vector->GetIndex(slot2)), // B(Star), R(0), // B(Ldar), A(2, 3), // - B(Add), A(2, 3), // + B(Star), R(3), // + B(Ldar), A(2, 3), // + B(Add), R(3), // B(Star), R(2), // B(Ldar), A(2, 3), // B(Star), R(3), // - B(Call), R(0), R(1), U8(2), // + B(Call), R(0), R(1), U8(2), U8(vector->GetIndex(slot1)), // B(Return), // }, 1, - {"func"}}}; + {"func"}}, + {"function f(a) {\n" + " a.func;\n" + REPEAT_127(SPACE, " a.func;\n") + " return a.func(); }\nf(" FUNC_ARG ")", + 2 * kPointerSize, + 2, + 1044, + { + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LoadICSloppy), R(0), U8(0), U8(wide_idx += 2), // + REPEAT_127(COMMA, // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LoadICSloppy), R(0), U8(0), U8((wide_idx += 2))), // + B(Ldar), A(1, 2), // + B(Star), R(1), // + B(LoadICSloppyWide), R(1), U16(0), U16(wide_idx + 4), // + B(Star), R(0), // + B(CallWide), R(0), R(1), U16(0), U16(wide_idx + 2), // + B(Return), // + }, + 1, + {"func"}}, + }; for (size_t i = 0; i < arraysize(snippets); i++) { Handle<BytecodeArray> bytecode_array = helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName); @@ -1338,32 +1523,48 @@ TEST(LoadGlobal) { }, 1, {"a"}}, - {"a = 1; function f(b) {\n" - REPEAT_127(SPACE, "b.name; ") - " return a; }\nf({name: 1});", - 0, + {"a = 1;" + "function f(b) {\n" + " b.name;\n" + REPEAT_127(SPACE, "b.name; ") + " return a;" + "}\nf({name: 1});", + kPointerSize, 2, - 514, + 1030, { - REPEAT_127(COMMA, // - B(LoadICSloppy), A(1, 2), U8(0), U8(wide_idx_1 += 2)), // - B(LdaGlobalSloppyWide), U16(1), U16(wide_idx_1 + 2), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LoadICSloppy), R(0), U8(0), U8(wide_idx_1 += 2), // + REPEAT_127(COMMA, // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LoadICSloppy), R(0), U8(0), U8(wide_idx_1 += 2)), // + B(LdaGlobalSloppyWide), U16(1), U16(wide_idx_1 + 2), // + B(Return), // }, 2, {"name", "a"}}, - {"a = 1; function f(b) {\n" + {"a = 1;" + "function f(b) {\n" " 'use strict';\n" - REPEAT_127(SPACE, "b.name; ") - " return a; }\nf({name: 1});", - 0, + " b.name\n" + REPEAT_127(SPACE, "b.name; ") + " return a;" + "}\nf({name: 1});", + kPointerSize, 2, - 514, + 1030, { - REPEAT_127(COMMA, // - B(LoadICStrict), A(1, 2), U8(0), U8(wide_idx_2 += 2)), // - B(LdaGlobalStrictWide), U16(1), U16(wide_idx_2 + 2), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LoadICStrict), R(0), U8(0), U8(wide_idx_2 += 2), // + REPEAT_127(COMMA, // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LoadICStrict), R(0), U8(0), U8(wide_idx_2 += 2)), // + B(LdaGlobalStrictWide), U16(1), U16(wide_idx_2 + 2), // + B(Return), // }, 2, {"name", "a"}}, @@ -1441,36 +1642,52 @@ TEST(StoreGlobal) { }, 1, {"a"}}, - {"a = 1; function f(b) {\n" + {"a = 1;" + "function f(b) {" + " b.name;\n" REPEAT_127(SPACE, "b.name; ") - " a = 2; }\nf({name: 1});", - 0, + " a = 2; }\n" + "f({name: 1});", + kPointerSize, 2, - 517, + 1033, { - REPEAT_127(COMMA, // - B(LoadICSloppy), A(1, 2), U8(0), U8(wide_idx_1 += 2)), // - B(LdaSmi8), U8(2), // - B(StaGlobalSloppyWide), U16(1), U16(wide_idx_1 + 2), // - B(LdaUndefined), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LoadICSloppy), R(0), U8(0), U8(wide_idx_1 += 2), // + REPEAT_127(COMMA, // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LoadICSloppy), R(0), U8(0), U8(wide_idx_1 += 2)), // + B(LdaSmi8), U8(2), // + B(StaGlobalSloppyWide), U16(1), U16(wide_idx_1 + 2), // + B(LdaUndefined), // + B(Return), // }, 2, {"name", "a"}}, - {"a = 1; function f(b) {\n" + {"a = 1;" + "function f(b) {\n" " 'use strict';\n" + " b.name;\n" REPEAT_127(SPACE, "b.name; ") - " a = 2; }\nf({name: 1});", - 0, + " a = 2; }\n" + "f({name: 1});", + kPointerSize, 2, - 517, + 1033, { - REPEAT_127(COMMA, // - B(LoadICStrict), A(1, 2), U8(0), U8(wide_idx_2 += 2)), // - B(LdaSmi8), U8(2), // - B(StaGlobalStrictWide), U16(1), U16(wide_idx_2 + 2), // - B(LdaUndefined), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LoadICStrict), R(0), U8(0), U8(wide_idx_2 += 2), // + REPEAT_127(COMMA, // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LoadICStrict), R(0), U8(0), U8(wide_idx_2 += 2)), // + B(LdaSmi8), U8(2), // + B(StaGlobalStrictWide), U16(1), U16(wide_idx_2 + 2), // + B(LdaUndefined), // + B(Return), // }, 2, {"name", "a"}}, @@ -1490,9 +1707,8 @@ TEST(CallGlobal) { Zone zone; FeedbackVectorSpec feedback_spec(&zone); - FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); + FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot(); FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); - USE(slot1); Handle<i::TypeFeedbackVector> vector = i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); @@ -1501,34 +1717,34 @@ TEST(CallGlobal) { {"function t() { }\nfunction f() { return t(); }\nf()", 2 * kPointerSize, 1, - 13, + 14, { - B(LdaUndefined), // - B(Star), R(1), // - B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), // - B(Star), R(0), // - B(Call), R(0), R(1), U8(0), // - B(Return) // + B(LdaUndefined), // + B(Star), R(1), // + B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), // + B(Star), R(0), // + B(Call), R(0), R(1), U8(0), U8(vector->GetIndex(slot1)), // + B(Return) // }, 1, {"t"}}, {"function t(a, b, c) { }\nfunction f() { return t(1, 2, 3); }\nf()", 5 * kPointerSize, 1, - 25, + 26, { - B(LdaUndefined), // - B(Star), R(1), // - B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), // - B(Star), R(0), // - B(LdaSmi8), U8(1), // - B(Star), R(2), // - B(LdaSmi8), U8(2), // - B(Star), R(3), // - B(LdaSmi8), U8(3), // - B(Star), R(4), // - B(Call), R(0), R(1), U8(3), // - B(Return) // + B(LdaUndefined), // + B(Star), R(1), // + B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot2)), // + B(Star), R(0), // + B(LdaSmi8), U8(1), // + B(Star), R(2), // + B(LdaSmi8), U8(2), // + B(Star), R(3), // + B(LdaSmi8), U8(3), // + B(Star), R(4), // + B(Call), R(0), R(1), U8(3), U8(vector->GetIndex(slot1)), // + B(Return) // }, 1, {"t"}}, @@ -1589,12 +1805,11 @@ TEST(CallRuntime) { "function f() { return %spread_iterable([1]) }\nf()", 2 * kPointerSize, 1, - 16, + 15, { B(LdaUndefined), // B(Star), R(0), // - B(LdaConstant), U8(0), // - B(CreateArrayLiteral), U8(0), U8(3), // + B(CreateArrayLiteral), U8(0), U8(0), U8(3), // B(Star), R(1), // B(CallJSRuntime), U16(Context::SPREAD_ITERABLE_INDEX), R(0), // U8(1), // @@ -1661,16 +1876,17 @@ TEST(IfConditions) { 0, {unused, unused, unused, unused, unused, unused}}, {"function f() { var a = 1; if (a) { a += 1; } else { return 2; } } f();", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 21, + 23, { B(LdaSmi8), U8(1), // B(Star), R(0), // + B(JumpIfToBooleanFalse), U8(14), // B(Ldar), R(0), // - B(JumpIfToBooleanFalse), U8(10), // + B(Star), R(1), // B(LdaSmi8), U8(1), // - B(Add), R(0), // + B(Add), R(1), // B(Star), R(0), // B(Jump), U8(5), // B(LdaSmi8), U8(2), // @@ -1682,19 +1898,21 @@ TEST(IfConditions) { {unused, unused, unused, unused, unused, unused}}, {"function f(a) { if (a <= 0) { return 200; } else { return -200; } }" "f(99);", - 0, + kPointerSize, 2, - 13, + 17, { - B(LdaZero), // - B(TestLessThanOrEqual), A(1, 2), // - B(JumpIfFalse), U8(5), // - B(LdaConstant), U8(0), // - B(Return), // - B(LdaConstant), U8(1), // - B(Return), // - B(LdaUndefined), // - B(Return), // + B(Ldar), A(1, 2), // + B(Star), R(0), // + B(LdaZero), // + B(TestLessThanOrEqual), R(0), // + B(JumpIfFalse), U8(5), // + B(LdaConstant), U8(0), // + B(Return), // + B(LdaConstant), U8(1), // + B(Return), // + B(LdaUndefined), // + B(Return), // }, 2, {helper.factory()->NewNumberFromInt(200), @@ -1702,12 +1920,14 @@ TEST(IfConditions) { unused}}, {"function f(a, b) { if (a in b) { return 200; } }" "f('prop', { prop: 'yes'});", - 0, + kPointerSize, 3, - 11, + 15, { + B(Ldar), A(1, 3), // + B(Star), R(0), // B(Ldar), A(2, 3), // - B(TestIn), A(1, 3), // + B(TestIn), R(0), // B(JumpIfFalse), U8(5), // B(LdaConstant), U8(0), // B(Return), // @@ -1718,23 +1938,24 @@ TEST(IfConditions) { {helper.factory()->NewNumberFromInt(200), unused, unused, unused, unused, unused}}, {"function f(z) { var a = 0; var b = 0; if (a === 0.01) { " - REPEAT_32(SPACE, "b = a; a = b; ") + REPEAT_64(SPACE, "b = a; a = b; ") " return 200; } else { return -200; } } f(0.001)", - 2 * kPointerSize, + 3 * kPointerSize, 2, - 276, + 282, { B(LdaZero), // B(Star), R(0), // B(LdaZero), // B(Star), R(1), // + B(Ldar), R(0), // + B(Star), R(2), // B(LdaConstant), U8(0), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfFalseConstant), U8(2), // - REPEAT_32(COMMA, // - B(Ldar), R(0), // + B(Ldar), R(0), // + REPEAT_64(COMMA, // B(Star), R(1), // - B(Ldar), R(1), // B(Star), R(0)), // B(LdaConstant), U8(1), // B(Return), // @@ -1745,14 +1966,14 @@ TEST(IfConditions) { 4, {helper.factory()->NewHeapNumber(0.01), helper.factory()->NewNumberFromInt(200), - helper.factory()->NewNumberFromInt(261), + helper.factory()->NewNumberFromInt(263), helper.factory()->NewNumberFromInt(-200), unused, unused}}, {"function f() { var a = 0; var b = 0; if (a) { " - REPEAT_32(SPACE, "b = a; a = b; ") + REPEAT_64(SPACE, "b = a; a = b; ") " return 200; } else { return -200; } } f()", 2 * kPointerSize, 1, - 274, + 276, { B(LdaZero), // B(Star), R(0), // @@ -1760,10 +1981,9 @@ TEST(IfConditions) { B(Star), R(1), // B(Ldar), R(0), // B(JumpIfToBooleanFalseConstant), U8(1), // - REPEAT_32(COMMA, // - B(Ldar), R(0), // + B(Ldar), R(0), // + REPEAT_64(COMMA, // B(Star), R(1), // - B(Ldar), R(1), // B(Star), R(0)), // B(LdaConstant), U8(0), // B(Return), // @@ -1773,7 +1993,7 @@ TEST(IfConditions) { B(Return)}, // 3, {helper.factory()->NewNumberFromInt(200), - helper.factory()->NewNumberFromInt(261), + helper.factory()->NewNumberFromInt(263), helper.factory()->NewNumberFromInt(-200), unused, unused, unused}}, {"function f(a, b) {\n" @@ -1787,13 +2007,15 @@ TEST(IfConditions) { " if (a instanceof b) { return 1; }\n" " return 0;\n" "} f(1, 1);", - 0, + kPointerSize, 3, - 74, + 106, { #define IF_CONDITION_RETURN(condition) \ + B(Ldar), A(1, 3), \ + B(Star), R(0), \ B(Ldar), A(2, 3), \ - B(condition), A(1, 3), \ + B(condition), R(0), \ B(JumpIfFalse), U8(5), \ B(LdaSmi8), U8(1), \ B(Return), @@ -1820,11 +2042,10 @@ TEST(IfConditions) { "f();", 1 * kPointerSize, 1, - 15, + 13, { B(LdaZero), // B(Star), R(0), // - B(Ldar), R(0), // B(JumpIfToBooleanFalse), U8(5), // B(LdaSmi8), U8(20), // B(Return), // @@ -1834,8 +2055,7 @@ TEST(IfConditions) { B(Return) }, 0, - {unused, unused, unused, unused, unused, unused}} - }; + {unused, unused, unused, unused, unused, unused}}}; for (size_t i = 0; i < arraysize(snippets); i++) { Handle<BytecodeArray> bytecode_array = @@ -1861,6 +2081,7 @@ TEST(DeclareGlobals) { FeedbackVectorSpec feedback_spec_loads(&zone); FeedbackVectorSlot load_slot_1 = feedback_spec_loads.AddLoadICSlot(); + FeedbackVectorSlot call_slot_1 = feedback_spec_loads.AddCallICSlot(); Handle<i::TypeFeedbackVector> load_vector = i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec_loads); @@ -1907,7 +2128,7 @@ TEST(DeclareGlobals) { {"var a = 1;\na=2;", 4 * kPointerSize, 1, - 38, + 36, { B(LdaConstant), U8(0), // B(Star), R(1), // @@ -1925,7 +2146,6 @@ TEST(DeclareGlobals) { B(StaGlobalSloppy), U8(1), // U8(store_vector->GetIndex(store_slot_2)), // B(Star), R(0), // - B(Ldar), R(0), // B(Return) // }, 2, @@ -1934,22 +2154,22 @@ TEST(DeclareGlobals) { {"function f() {}\nf();", 3 * kPointerSize, 1, - 29, + 28, { - B(LdaConstant), U8(0), // - B(Star), R(1), // - B(LdaZero), // - B(Star), R(2), // - B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), // - B(LdaUndefined), // - B(Star), R(2), // - B(LdaGlobalSloppy), U8(1), // - U8(load_vector->GetIndex(load_slot_1)), // - B(Star), R(1), // - B(Call), R(1), R(2), U8(0), // - B(Star), R(0), // - B(Ldar), R(0), // - B(Return) // + B(LdaConstant), U8(0), // + B(Star), R(1), // + B(LdaZero), // + B(Star), R(2), // + B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), // + B(LdaUndefined), // + B(Star), R(2), // + B(LdaGlobalSloppy), U8(1), // + U8(load_vector->GetIndex(load_slot_1)), // + B(Star), R(1), // + B(Call), R(1), R(2), U8(0), // + U8(load_vector->GetIndex(call_slot_1)), // + B(Star), R(0), // + B(Return) // }, 2, {InstanceType::FIXED_ARRAY_TYPE, @@ -1964,42 +2184,178 @@ TEST(DeclareGlobals) { } +TEST(BreakableBlocks) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + + ExpectedSnippet<int> snippets[] = { + {"var x = 0;\n" + "label: {\n" + " x = x + 1;\n" + " break label;\n" + " x = x + 1;\n" + "}\n" + "return x;", + 2 * kPointerSize, + 1, + 16, + { + B(LdaZero), // + B(Star), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(Add), R(1), // + B(Star), R(0), // + B(Jump), U8(2), // + B(Ldar), R(0), // + B(Return) // + }}, + {"var sum = 0;\n" + "outer: {\n" + " for (var x = 0; x < 10; ++x) {\n" + " for (var y = 0; y < 3; ++y) {\n" + " ++sum;\n" + " if (x + y == 12) { break outer; }\n" + " }\n" + " }\n" + "}\n" + "return sum;", + 5 * kPointerSize, + 1, + 72, + { + B(LdaZero), // + B(Star), R(0), // + B(LdaZero), // + B(Star), R(1), // + B(Ldar), R(1), // + B(Star), R(3), // + B(LdaSmi8), U8(10), // + B(TestLessThan), R(3), // + B(JumpIfFalse), U8(55), // + B(LdaZero), // + B(Star), R(2), // + B(Ldar), R(2), // + B(Star), R(3), // + B(LdaSmi8), U8(3), // + B(TestLessThan), R(3), // + B(JumpIfFalse), U8(34), // + B(Ldar), R(0), // + B(ToNumber), // + B(Inc), // + B(Star), R(0), // + B(Ldar), R(1), // + B(Star), R(3), // + B(Ldar), R(2), // + B(Add), R(3), // + B(Star), R(4), // + B(LdaSmi8), U8(12), // + B(TestEqual), R(4), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(18), // + B(Ldar), R(2), // + B(ToNumber), // + B(Inc), // + B(Star), R(2), // + B(Jump), U8(-40), // + B(Ldar), R(1), // + B(ToNumber), // + B(Inc), // + B(Star), R(1), // + B(Jump), U8(-61), // + B(Ldar), R(0), // + B(Return), // + }}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + Handle<BytecodeArray> bytecode_array = + helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + + TEST(BasicLoops) { InitializedHandleScope handle_scope; BytecodeGeneratorHelper helper; ExpectedSnippet<int> snippets[] = { + {"var x = 0;\n" + "while (false) { x = 99; break; continue; }\n" + "return x;", + 1 * kPointerSize, + 1, + 4, + { + B(LdaZero), // + B(Star), R(0), // + B(Return) // + }}, + {"var x = 0;" + "while (false) {" + " x = x + 1;" + "};" + "return x;", + 1 * kPointerSize, + 1, + 4, + { + B(LdaZero), // + B(Star), R(0), // + B(Return), // + }, + 0}, {"var x = 0;" "var y = 1;" "while (x < 10) {" " y = y * 12;" " x = x + 1;" + " if (x == 3) continue;" + " if (x == 4) break;" "}" "return y;", - 2 * kPointerSize, + 3 * kPointerSize, 1, - 30, + 64, { B(LdaZero), // B(Star), R(0), // B(LdaSmi8), U8(1), // B(Star), R(1), // - B(Jump), U8(14), // + B(Ldar), R(0), // + B(Star), R(2), // + B(LdaSmi8), U8(10), // + B(TestLessThan), R(2), // + B(JumpIfFalse), U8(46), // + B(Ldar), R(1), // + B(Star), R(2), // B(LdaSmi8), U8(12), // - B(Mul), R(1), // + B(Mul), R(2), // B(Star), R(1), // + B(Ldar), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(1), // - B(Add), R(0), // + B(Add), R(2), // B(Star), R(0), // - B(LdaSmi8), U8(10), // - B(TestLessThan), R(0), // - B(JumpIfTrue), U8(-16), // + B(Star), R(2), // + B(LdaSmi8), U8(3), // + B(TestEqual), R(2), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(-38), // + B(Ldar), R(0), // + B(Star), R(2), // + B(LdaSmi8), U8(4), // + B(TestEqual), R(2), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(4), // + B(Jump), U8(-52), // B(Ldar), R(1), // B(Return), // }, 0}, {"var i = 0;" - "while(true) {" + "while (true) {" " if (i < 0) continue;" " if (i == 3) break;" " if (i == 4) break;" @@ -2008,130 +2364,54 @@ TEST(BasicLoops) { " i = i + 1;" "}" "return i;", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 53, + 77, { B(LdaZero), // B(Star), R(0), // + B(Ldar), R(0), // + B(Star), R(1), // B(LdaZero), // - B(TestLessThan), R(0), // + B(TestLessThan), R(1), // B(JumpIfFalse), U8(4), // - B(Jump), U8(40), // + B(Jump), U8(-9), // + B(Ldar), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(3), // - B(TestEqual), R(0), // + B(TestEqual), R(1), // B(JumpIfFalse), U8(4), // - B(Jump), U8(34), // + B(Jump), U8(50), // + B(Ldar), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(4), // - B(TestEqual), R(0), // + B(TestEqual), R(1), // B(JumpIfFalse), U8(4), // - B(Jump), U8(26), // + B(Jump), U8(38), // + B(Ldar), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(10), // - B(TestEqual), R(0), // - B(JumpIfFalse), U8(4), // - B(Jump), U8(16), // - B(LdaSmi8), U8(5), // - B(TestEqual), R(0), // + B(TestEqual), R(1), // B(JumpIfFalse), U8(4), // - B(Jump), U8(10), // - B(LdaSmi8), U8(1), // - B(Add), R(0), // - B(Star), R(0), // B(Jump), U8(-45), // B(Ldar), R(0), // - B(Return), // - }, - 0}, - {"var x = 0; var y = 1;" - "do {" - " y = y * 10;" - " if (x == 5) break;" - " if (x == 6) continue;" - " x = x + 1;" - "} while (x < 10);" - "return y;", - 2 * kPointerSize, - 1, - 44, - { - B(LdaZero), // - B(Star), R(0), // - B(LdaSmi8), U8(1), // - B(Star), R(1), // - B(LdaSmi8), U8(10), // - B(Mul), R(1), // - B(Star), R(1), // - B(LdaSmi8), U8(5), // - B(TestEqual), R(0), // - B(JumpIfFalse), U8(4), // - B(Jump), U8(22), // - B(LdaSmi8), U8(6), // - B(TestEqual), R(0), // - B(JumpIfFalse), U8(4), // - B(Jump), U8(8), // - B(LdaSmi8), U8(1), // - B(Add), R(0), // - B(Star), R(0), // - B(LdaSmi8), U8(10), // - B(TestLessThan), R(0), // - B(JumpIfTrue), U8(-32), // - B(Ldar), R(1), // - B(Return), // - }, - 0}, - {"var x = 0; " - "for(;;) {" - " if (x == 1) break;" - " x = x + 1;" - "}", - 1 * kPointerSize, - 1, - 21, - { - B(LdaZero), // - B(Star), R(0), // - B(LdaSmi8), U8(1), // - B(TestEqual), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(5), // + B(TestEqual), R(1), // B(JumpIfFalse), U8(4), // - B(Jump), U8(10), // + B(Jump), U8(14), // + B(Ldar), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(1), // - B(Add), R(0), // + B(Add), R(1), // B(Star), R(0), // - B(Jump), U8(-14), // - B(LdaUndefined), // + B(Jump), U8(-69), // + B(Ldar), R(0), // B(Return), // }, 0}, - {"var u = 0;" - "for(var i = 0; i < 100; i = i + 1) {" - " u = u + 1;" - " continue;" - "}", - 2 * kPointerSize, - 1, - 30, - { - B(LdaZero), // - B(Star), R(0), // - B(LdaZero), // - B(Star), R(1), // - B(Jump), U8(16), // - B(LdaSmi8), U8(1), // - B(Add), R(0), // - B(Star), R(0), // - B(Jump), U8(2), // - B(LdaSmi8), U8(1), // - B(Add), R(1), // - B(Star), R(1), // - B(LdaSmi8), U8(100), // - B(TestLessThan), R(1), // - B(JumpIfTrue), U8(-18), // - B(LdaUndefined), // - B(Return), // - }, - 0}, {"var i = 0;" - "while(true) {" + "while (true) {" " while (i < 3) {" " if (i == 2) break;" " i = i + 1;" @@ -2140,28 +2420,36 @@ TEST(BasicLoops) { " break;" "}" "return i;", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 38, + 54, { B(LdaZero), // B(Star), R(0), // - B(Jump), U8(16), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(3), // + B(TestLessThan), R(1), // + B(JumpIfFalse), U8(26), // + B(Ldar), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(2), // - B(TestEqual), R(0), // + B(TestEqual), R(1), // B(JumpIfFalse), U8(4), // B(Jump), U8(14), // + B(Ldar), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(1), // - B(Add), R(0), // + B(Add), R(1), // B(Star), R(0), // - B(LdaSmi8), U8(3), // - B(TestLessThan), R(0), // - B(JumpIfTrue), U8(-18), // + B(Jump), U8(-32), // + B(Ldar), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(1), // - B(Add), R(0), // + B(Add), R(1), // B(Star), R(0), // B(Jump), U8(4), // - B(Jump), U8(-30), // + B(Jump), U8(-46), // B(Ldar), R(0), // B(Return), // }, @@ -2173,78 +2461,106 @@ TEST(BasicLoops) { " x = x - 1;" "}" "return y;", - 2 * kPointerSize, + 3 * kPointerSize, 1, - 29, + 37, { B(LdaSmi8), U8(10), // B(Star), R(0), // B(LdaSmi8), U8(1), // B(Star), R(1), // - B(Jump), U8(14), // - B(LdaSmi8), U8(12), // - B(Mul), R(1), // - B(Star), R(1), // - B(LdaSmi8), U8(1), // - B(Sub), R(0), // - B(Star), R(0), // B(Ldar), R(0), // - B(JumpIfToBooleanTrue), U8(-14), // + B(JumpIfToBooleanFalse), U8(24), // B(Ldar), R(1), // - B(Return), // - }, - 0}, - {"var x = 10;" - "var y = 1;" - "do {" - " y = y * 12;" - " x = x - 1;" - "} while(x);" - "return y;", - 2 * kPointerSize, - 1, - 27, - { - B(LdaSmi8), U8(10), // - B(Star), R(0), // - B(LdaSmi8), U8(1), // - B(Star), R(1), // + B(Star), R(2), // B(LdaSmi8), U8(12), // - B(Mul), R(1), // + B(Mul), R(2), // B(Star), R(1), // + B(Ldar), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(1), // - B(Sub), R(0), // + B(Sub), R(2), // B(Star), R(0), // - B(Ldar), R(0), // - B(JumpIfToBooleanTrue), U8(-14), // + B(Jump), U8(-24), // B(Ldar), R(1), // B(Return), // - }, + }, 0}, - {"var y = 1;" - "for (var x = 10; x; --x) {" + {"var x = 0; var y = 1;" + "do {" + " y = y * 10;" + " if (x == 5) break;" + " if (x == 6) continue;" + " x = x + 1;" + "} while (x < 10);" + "return y;", + 3 * kPointerSize, + 1, + 64, + { + B(LdaZero), // + B(Star), R(0), // + B(LdaSmi8), U8(1), // + B(Star), R(1), // + B(Ldar), R(1), // + B(Star), R(2), // + B(LdaSmi8), U8(10), // + B(Mul), R(2), // + B(Star), R(1), // + B(Ldar), R(0), // + B(Star), R(2), // + B(LdaSmi8), U8(5), // + B(TestEqual), R(2), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(34), // + B(Ldar), R(0), // + B(Star), R(2), // + B(LdaSmi8), U8(6), // + B(TestEqual), R(2), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(12), // + B(Ldar), R(0), // + B(Star), R(2), // + B(LdaSmi8), U8(1), // + B(Add), R(2), // + B(Star), R(0), // + B(Ldar), R(0), // + B(Star), R(2), // + B(LdaSmi8), U8(10), // + B(TestLessThan), R(2), // + B(JumpIfTrue), U8(-52), // + B(Ldar), R(1), // + B(Return), // + }, + 0}, + {"var x = 10;" + "var y = 1;" + "do {" " y = y * 12;" - "}" + " x = x - 1;" + "} while (x);" "return y;", - 2 * kPointerSize, + 3 * kPointerSize, 1, - 29, + 35, { - B(LdaSmi8), U8(1), // - B(Star), R(0), // B(LdaSmi8), U8(10), // - B(Star), R(1), // - B(Jump), U8(14), // - B(LdaSmi8), U8(12), // - B(Mul), R(0), // B(Star), R(0), // - B(Ldar), R(1), // - B(ToNumber), // - B(Dec), // + B(LdaSmi8), U8(1), // B(Star), R(1), // B(Ldar), R(1), // - B(JumpIfToBooleanTrue), U8(-14), // + B(Star), R(2), // + B(LdaSmi8), U8(12), // + B(Mul), R(2), // + B(Star), R(1), // B(Ldar), R(0), // + B(Star), R(2), // + B(LdaSmi8), U8(1), // + B(Sub), R(2), // + B(Star), R(0), // + B(Ldar), R(0), // + B(JumpIfToBooleanTrue), U8(-22), // + B(Ldar), R(1), // B(Return), // }, 0}, @@ -2256,26 +2572,33 @@ TEST(BasicLoops) { " if (x == 6) continue;" "} while (false);" "return y;", - 2 * kPointerSize, + 3 * kPointerSize, 1, - 38, + 52, { B(LdaZero), // B(Star), R(0), // B(LdaSmi8), U8(1), // B(Star), R(1), // + B(Ldar), R(1), // + B(Star), R(2), // B(LdaSmi8), U8(10), // - B(Mul), R(1), // + B(Mul), R(2), // B(Star), R(1), // + B(Ldar), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(5), // - B(TestEqual), R(0), // + B(TestEqual), R(2), // B(JumpIfFalse), U8(4), // - B(Jump), U8(16), // + B(Jump), U8(22), // + B(Ldar), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(1), // - B(Add), R(0), // + B(Add), R(2), // B(Star), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(6), // - B(TestEqual), R(0), // + B(TestEqual), R(2), // B(JumpIfFalse), U8(4), // B(Jump), U8(2), // B(Ldar), R(1), // @@ -2290,50 +2613,237 @@ TEST(BasicLoops) { " if (x == 6) continue;" "} while (true);" "return y;", - 2 * kPointerSize, + 3 * kPointerSize, 1, - 40, + 54, { B(LdaZero), // B(Star), R(0), // B(LdaSmi8), U8(1), // B(Star), R(1), // + B(Ldar), R(1), // + B(Star), R(2), // B(LdaSmi8), U8(10), // - B(Mul), R(1), // + B(Mul), R(2), // B(Star), R(1), // + B(Ldar), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(5), // - B(TestEqual), R(0), // + B(TestEqual), R(2), // B(JumpIfFalse), U8(4), // - B(Jump), U8(18), // + B(Jump), U8(24), // + B(Ldar), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(1), // - B(Add), R(0), // + B(Add), R(2), // B(Star), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(6), // - B(TestEqual), R(0), // + B(TestEqual), R(2), // B(JumpIfFalse), U8(4), // - B(Jump), U8(2), // - B(Jump), U8(-28), // + B(Jump), U8(-40), // + B(Jump), U8(-42), // B(Ldar), R(1), // B(Return), // }, 0}, - {"var x = 0;" - "while(false) {" + {"var x = 0; " + "for (;;) {" + " if (x == 1) break;" + " if (x == 2) continue;" " x = x + 1;" - "};" - "return x;", - 1 * kPointerSize, + "}", + 2 * kPointerSize, 1, - 6, + 41, { - B(LdaZero), // - B(Star), R(0), // - B(Ldar), R(0), // - B(Return), // + B(LdaZero), // + B(Star), R(0), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(TestEqual), R(1), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(26), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(2), // + B(TestEqual), R(1), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(-22), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(Add), R(1), // + B(Star), R(0), // + B(Jump), U8(-34), // + B(LdaUndefined), // + B(Return), // + }, + 0}, + {"for (var x = 0;;) {" + " if (x == 1) break;" + " if (x == 2) continue;" + " x = x + 1;" + "}", + 2 * kPointerSize, + 1, + 41, + { + B(LdaZero), // + B(Star), R(0), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(TestEqual), R(1), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(26), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(2), // + B(TestEqual), R(1), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(-22), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(Add), R(1), // + B(Star), R(0), // + B(Jump), U8(-34), // + B(LdaUndefined), // + B(Return), // + }, + 0}, + {"var x = 0; " + "for (;; x = x + 1) {" + " if (x == 1) break;" + " if (x == 2) continue;" + "}", + 2 * kPointerSize, + 1, + 41, + { + B(LdaZero), // + B(Star), R(0), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(TestEqual), R(1), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(26), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(2), // + B(TestEqual), R(1), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(2), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(Add), R(1), // + B(Star), R(0), // + B(Jump), U8(-34), // + B(LdaUndefined), // + B(Return), // + }, + 0}, + {"for (var x = 0;; x = x + 1) {" + " if (x == 1) break;" + " if (x == 2) continue;" + "}", + 2 * kPointerSize, + 1, + 41, + { + B(LdaZero), // + B(Star), R(0), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(TestEqual), R(1), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(26), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(2), // + B(TestEqual), R(1), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(2), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(Add), R(1), // + B(Star), R(0), // + B(Jump), U8(-34), // + B(LdaUndefined), // + B(Return), // + }, + 0}, + {"var u = 0;" + "for (var i = 0; i < 100; i = i + 1) {" + " u = u + 1;" + " continue;" + "}", + 3 * kPointerSize, + 1, + 42, + { + B(LdaZero), // + B(Star), R(0), // + B(LdaZero), // + B(Star), R(1), // + B(Ldar), R(1), // + B(Star), R(2), // + B(LdaSmi8), U8(100), // + B(TestLessThan), R(2), // + B(JumpIfFalse), U8(26), // + B(Ldar), R(0), // + B(Star), R(2), // + B(LdaSmi8), U8(1), // + B(Add), R(2), // + B(Star), R(0), // + B(Jump), U8(2), // + B(Ldar), R(1), // + B(Star), R(2), // + B(LdaSmi8), U8(1), // + B(Add), R(2), // + B(Star), R(1), // + B(Jump), U8(-32), // + B(LdaUndefined), // + B(Return), // + }, + 0}, + {"var y = 1;" + "for (var x = 10; x; --x) {" + " y = y * 12;" + "}" + "return y;", + 3 * kPointerSize, + 1, + 33, + { + B(LdaSmi8), U8(1), // + B(Star), R(0), // + B(LdaSmi8), U8(10), // + B(Star), R(1), // + B(Ldar), R(1), // + B(JumpIfToBooleanFalse), U8(20), // + B(Ldar), R(0), // + B(Star), R(2), // + B(LdaSmi8), U8(12), // + B(Mul), R(2), // + B(Star), R(0), // + B(Ldar), R(1), // + B(ToNumber), // + B(Dec), // + B(Star), R(1), // + B(Jump), U8(-20), // + B(Ldar), R(0), // + B(Return), // }, 0}, {"var x = 0;" - "for( var i = 0; false; i++) {" + "for (var i = 0; false; i++) {" " x = x + 1;" "};" "return x;", @@ -2350,31 +2860,34 @@ TEST(BasicLoops) { }, 0}, {"var x = 0;" - "for( var i = 0; true; ++i) {" + "for (var i = 0; true; ++i) {" " x = x + 1;" " if (x == 20) break;" "};" "return x;", - 2 * kPointerSize, + 3 * kPointerSize, 1, - 31, + 37, { B(LdaZero), // B(Star), R(0), // B(LdaZero), // B(Star), R(1), // + B(Ldar), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(1), // - B(Add), R(0), // + B(Add), R(2), // B(Star), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(20), // - B(TestEqual), R(0), // + B(TestEqual), R(2), // B(JumpIfFalse), U8(4), // B(Jump), U8(10), // B(Ldar), R(1), // B(ToNumber), // B(Inc), // B(Star), R(1), // - B(Jump), U8(-20), // + B(Jump), U8(-26), // B(Ldar), R(0), // B(Return), // }, @@ -2389,6 +2902,83 @@ TEST(BasicLoops) { } +TEST(JumpsRequiringConstantWideOperands) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + + int constant_count = 0; + ExpectedSnippet<Handle<Object>, 316> snippets[] = { + { + REPEAT_256(SPACE, "var x = 0.1;") + REPEAT_32(SPACE, "var x = 0.2;") + REPEAT_16(SPACE, "var x = 0.3;") + REPEAT_8(SPACE, "var x = 0.4;") + "for (var i = 0; i < 3; i++) {\n" + " if (i == 1) continue;\n" + " if (i == 2) break;\n" + "}\n" + "return 3;", + kPointerSize * 3, + 1, + 1359, + { +#define L(c) B(LdaConstant), U8(c), B(Star), R(0) + REPEAT_256(COMMA, L(constant_count++)), +#undef L +#define LW(c) B(LdaConstantWide), U16I(c), B(Star), R(0) + REPEAT_32(COMMA, LW(constant_count)), + REPEAT_16(COMMA, LW(constant_count)), + REPEAT_8(COMMA, LW(constant_count)), +#undef LW + B(LdaZero), // + B(Star), R(1), // + B(Ldar), R(1), // + B(Star), R(2), // + B(LdaSmi8), U8(3), // + B(TestLessThan), R(2), // + B(JumpIfFalseConstantWide), U16(313), // + B(Ldar), R(1), // + B(Star), R(2), // + B(LdaSmi8), U8(1), // + B(TestEqual), R(2), // + B(JumpIfFalseConstantWide), U16(312), // + B(JumpConstantWide), U16(315), // + B(Ldar), R(1), // + B(Star), R(2), // + B(LdaSmi8), U8(2), // + B(TestEqual), R(2), // + B(JumpIfFalseConstantWide), U16(312), // + B(JumpConstantWide), U16(314), // + B(Ldar), R(1), // + B(ToNumber), // + B(Star), R(2), // + B(Inc), // + B(Star), R(1), // + B(Jump), U8(-47), // + B(LdaSmi8), U8(3), // + B(Return) // + }, + 316, + { +#define S(x) CcTest::i_isolate()->factory()->NewNumber(x) + REPEAT_256(COMMA, S(0.1)), + REPEAT_32(COMMA, S(0.2)), + REPEAT_16(COMMA, S(0.3)), + REPEAT_8(COMMA, S(0.4)), +#undef S +#define N(x) CcTest::i_isolate()->factory()->NewNumberFromInt(x) + N(6), N(41), N(13), N(17) +#undef N + }}}; + + for (size_t i = 0; i < arraysize(snippets); i++) { + Handle<BytecodeArray> bytecode_array = + helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + + TEST(UnaryOperators) { InitializedHandleScope handle_scope; BytecodeGeneratorHelper helper; @@ -2399,20 +2989,24 @@ TEST(UnaryOperators) { " x = x + 10;" "}" "return x;", - kPointerSize, + 2 * kPointerSize, 1, - 21, + 29, { B(LdaZero), // B(Star), R(0), // - B(Jump), U8(8), // - B(LdaSmi8), U8(10), // - B(Add), R(0), // - B(Star), R(0), // + B(Ldar), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(10), // - B(TestEqual), R(0), // + B(TestEqual), R(1), // B(LogicalNot), // - B(JumpIfTrue), U8(-11), // + B(JumpIfFalse), U8(14), // + B(Ldar), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(10), // + B(Add), R(1), // + B(Star), R(0), // + B(Jump), U8(-21), // B(Ldar), R(0), // B(Return), // }, @@ -2422,32 +3016,35 @@ TEST(UnaryOperators) { " x = !x;" "} while(x == false);" "return x;", - kPointerSize, + 2 * kPointerSize, 1, - 16, + 20, { B(LdaFalse), // B(Star), R(0), // B(Ldar), R(0), // B(LogicalNot), // B(Star), R(0), // + B(Ldar), R(0), // + B(Star), R(1), // B(LdaFalse), // - B(TestEqual), R(0), // - B(JumpIfTrue), U8(-8), // + B(TestEqual), R(1), // + B(JumpIfTrue), U8(-12), // B(Ldar), R(0), // B(Return), // }, 0}, {"var x = 101;" "return void(x * 3);", - kPointerSize, + 2 * kPointerSize, 1, - 10, + 12, { B(LdaSmi8), U8(101), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(3), // - B(Mul), R(0), // + B(Mul), R(1), // B(LdaUndefined), // B(Return), // }, @@ -2455,60 +3052,63 @@ TEST(UnaryOperators) { {"var x = 1234;" "var y = void (x * x - 1);" "return y;", - 3 * kPointerSize, + 4 * kPointerSize, 1, 20, { B(LdaConstant), U8(0), // B(Star), R(0), // - B(Ldar), R(0), // - B(Mul), R(0), // B(Star), R(2), // + B(Ldar), R(0), // + B(Mul), R(2), // + B(Star), R(3), // B(LdaSmi8), U8(1), // - B(Sub), R(2), // + B(Sub), R(3), // B(LdaUndefined), // B(Star), R(1), // - B(Ldar), R(1), // B(Return), // }, 1, {1234}}, {"var x = 13;" "return ~x;", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 9, + 11, { B(LdaSmi8), U8(13), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(-1), // - B(BitwiseXor), R(0), // + B(BitwiseXor), R(1), // B(Return), // }, 0}, {"var x = 13;" "return +x;", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 9, + 11, { B(LdaSmi8), U8(13), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(1), // - B(Mul), R(0), // + B(Mul), R(1), // B(Return), // }, 0}, {"var x = 13;" "return -x;", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 9, + 11, { B(LdaSmi8), U8(13), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(-1), // - B(Mul), R(0), // + B(Mul), R(1), // B(Return), // }, 0}}; @@ -2539,11 +3139,10 @@ TEST(Typeof) { "}; f();", kPointerSize, 1, - 8, + 6, { B(LdaSmi8), U8(13), // - B(Star), R(0), // TODO(oth): Ldar R(X) following Star R(X) - B(Ldar), R(0), // could be culled in bytecode array builder. + B(Star), R(0), // B(TypeOf), // B(Return), // }}, @@ -2599,45 +3198,45 @@ TEST(Delete) { ExpectedSnippet<InstanceType> snippets[] = { {"var a = {x:13, y:14}; return delete a.x;", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 12, + 13, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // - B(Star), R(0), // - B(LdaConstant), U8(1), // - B(DeletePropertySloppy), R(0), // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // + B(Star), R(0), // + B(Star), R(1), // + B(LdaConstant), U8(1), // + B(DeletePropertySloppy), R(1), // B(Return) }, 2, {InstanceType::FIXED_ARRAY_TYPE, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, {"'use strict'; var a = {x:13, y:14}; return delete a.x;", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 12, + 13, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // - B(Star), R(0), // - B(LdaConstant), U8(1), // - B(DeletePropertyStrict), R(0), // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // + B(Star), R(0), // + B(Star), R(1), // + B(LdaConstant), U8(1), // + B(DeletePropertyStrict), R(1), // B(Return) }, 2, {InstanceType::FIXED_ARRAY_TYPE, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, {"var a = {1:13, 2:14}; return delete a[2];", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 12, + 13, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // - B(Star), R(0), // - B(LdaSmi8), U8(2), // - B(DeletePropertySloppy), R(0), // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // + B(Star), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(2), // + B(DeletePropertySloppy), R(1), // B(Return) }, 1, @@ -2659,20 +3258,18 @@ TEST(Delete) { "return delete a[1];", 2 * kPointerSize, 1, - 29, + 27, { - B(CallRuntime), U16(Runtime::kNewFunctionContext), // - R(closure), U8(1), // - B(PushContext), R(0), // - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // - B(StaContextSlot), R(0), U8(first_context_slot), // - B(LdaConstant), U8(1), // - B(CreateClosure), U8(0), // - B(LdaContextSlot), R(0), U8(first_context_slot), // - B(Star), R(1), // - B(LdaSmi8), U8(1), // - B(DeletePropertyStrict), R(1), // + B(CallRuntime), U16(Runtime::kNewFunctionContext), // + R(closure), U8(1), // + B(PushContext), R(0), // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // + B(StaContextSlot), R(0), U8(first_context_slot), // + B(CreateClosure), U8(1), U8(0), // + B(LdaContextSlot), R(0), U8(first_context_slot), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(DeletePropertyStrict), R(1), // B(Return) }, 2, @@ -2703,7 +3300,8 @@ TEST(GlobalDelete) { Zone zone; int context = Register::function_context().index(); - int global_object_index = Context::GLOBAL_OBJECT_INDEX; + int native_context_index = Context::NATIVE_CONTEXT_INDEX; + int global_context_index = Context::EXTENSION_INDEX; FeedbackVectorSpec feedback_spec(&zone); FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); @@ -2715,13 +3313,11 @@ TEST(GlobalDelete) { 1 * kPointerSize, 1, 10, - { - B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)), // - B(Star), R(0), // - B(LdaConstant), U8(1), // - B(DeletePropertySloppy), R(0), // - B(Return) - }, + {B(LdaGlobalSloppy), U8(0), U8(vector->GetIndex(slot)), // + B(Star), R(0), // + B(LdaConstant), U8(1), // + B(DeletePropertySloppy), R(0), // + B(Return)}, 2, {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, @@ -2730,39 +3326,37 @@ TEST(GlobalDelete) { 1 * kPointerSize, 1, 10, - { - B(LdaGlobalStrict), U8(0), U8(vector->GetIndex(slot)), // - B(Star), R(0), // - B(LdaSmi8), U8(1), // - B(DeletePropertyStrict), R(0), // - B(Return) - }, + {B(LdaGlobalStrict), U8(0), U8(vector->GetIndex(slot)), // + B(Star), R(0), // + B(LdaSmi8), U8(1), // + B(DeletePropertyStrict), R(0), // + B(Return)}, 1, {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, {"var a = {x:13, y:14};\n function f() { return delete a; };\n f();", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 10, - { - B(LdaContextSlot), R(context), U8(global_object_index), // - B(Star), R(0), // - B(LdaConstant), U8(0), // - B(DeletePropertySloppy), R(0), // - B(Return) - }, + 15, + {B(LdaContextSlot), R(context), U8(native_context_index), // + B(Star), R(0), // + B(LdaContextSlot), R(0), U8(global_context_index), // + B(Star), R(1), // + B(LdaConstant), U8(0), // + B(DeletePropertySloppy), R(1), // + B(Return)}, 1, {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, {"b = 30;\n function f() { return delete b; };\n f();", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 10, - { - B(LdaContextSlot), R(context), U8(global_object_index), // - B(Star), R(0), // - B(LdaConstant), U8(0), // - B(DeletePropertySloppy), R(0), // - B(Return) - }, + 15, + {B(LdaContextSlot), R(context), U8(native_context_index), // + B(Star), R(0), // + B(LdaContextSlot), R(0), U8(global_context_index), // + B(Star), R(1), // + B(LdaConstant), U8(0), // + B(DeletePropertySloppy), R(1), // + B(Return)}, 1, {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}}; @@ -2777,16 +3371,22 @@ TEST(GlobalDelete) { TEST(FunctionLiterals) { InitializedHandleScope handle_scope; BytecodeGeneratorHelper helper; + Zone zone; + + FeedbackVectorSpec feedback_spec(&zone); + FeedbackVectorSlot slot = feedback_spec.AddCallICSlot(); + + Handle<i::TypeFeedbackVector> vector = + i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); ExpectedSnippet<InstanceType> snippets[] = { {"return function(){ }", 0, 1, - 5, + 4, { - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // - B(Return) // + B(CreateClosure), U8(0), U8(0), // + B(Return) // }, 1, {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, @@ -2795,13 +3395,12 @@ TEST(FunctionLiterals) { 1, 14, { - B(LdaUndefined), // - B(Star), R(1), // - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // - B(Star), R(0), // - B(Call), R(0), R(1), U8(0), // - B(Return) // + B(LdaUndefined), // + B(Star), R(1), // + B(CreateClosure), U8(0), U8(0), // + B(Star), R(0), // + B(Call), R(0), R(1), U8(0), U8(vector->GetIndex(slot)), // + B(Return) // }, 1, {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, @@ -2810,15 +3409,14 @@ TEST(FunctionLiterals) { 1, 18, { - B(LdaUndefined), // - B(Star), R(1), // - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // - B(Star), R(0), // - B(LdaSmi8), U8(1), // - B(Star), R(2), // - B(Call), R(0), R(1), U8(1), // - B(Return) // + B(LdaUndefined), // + B(Star), R(1), // + B(CreateClosure), U8(0), U8(0), // + B(Star), R(0), // + B(LdaSmi8), U8(1), // + B(Star), R(2), // + B(Call), R(0), R(1), U8(1), U8(vector->GetIndex(slot)), // + B(Return) // }, 1, {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, @@ -2838,58 +3436,82 @@ TEST(RegExpLiterals) { Zone zone; FeedbackVectorSpec feedback_spec(&zone); - feedback_spec.AddLoadICSlot(); + FeedbackVectorSlot slot1 = feedback_spec.AddCallICSlot(); FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); + uint8_t i_flags = JSRegExp::kIgnoreCase; Handle<i::TypeFeedbackVector> vector = i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); ExpectedSnippet<const char*> snippets[] = { {"return /ab+d/;", - 1 * kPointerSize, + 0 * kPointerSize, 1, - 10, + 5, { - B(LdaConstant), U8(0), // - B(Star), R(0), // - B(LdaConstant), U8(1), // - B(CreateRegExpLiteral), U8(0), R(0), // - B(Return), // + B(CreateRegExpLiteral), U8(0), U8(0), U8(0), // + B(Return), // }, - 2, - {"", "ab+d"}}, + 1, + {"ab+d"}}, {"return /(\\w+)\\s(\\w+)/i;", - 1 * kPointerSize, + 0 * kPointerSize, 1, - 10, + 5, { - B(LdaConstant), U8(0), // - B(Star), R(0), // - B(LdaConstant), U8(1), // - B(CreateRegExpLiteral), U8(0), R(0), // - B(Return), // + B(CreateRegExpLiteral), U8(0), U8(0), U8(i_flags), // + B(Return), // }, - 2, - {"i", "(\\w+)\\s(\\w+)"}}, + 1, + {"(\\w+)\\s(\\w+)"}}, {"return /ab+d/.exec('abdd');", 3 * kPointerSize, 1, - 26, + 22, { - B(LdaConstant), U8(0), // - B(Star), R(2), // - B(LdaConstant), U8(1), // - B(CreateRegExpLiteral), U8(0), R(2), // + B(CreateRegExpLiteral), U8(0), U8(0), U8(0), // B(Star), R(1), // - B(LoadICSloppy), R(1), U8(2), U8(vector->GetIndex(slot2)), // + B(LoadICSloppy), R(1), U8(1), U8(vector->GetIndex(slot2)), // B(Star), R(0), // - B(LdaConstant), U8(3), // + B(LdaConstant), U8(2), // B(Star), R(2), // - B(Call), R(0), R(1), U8(1), // + B(Call), R(0), R(1), U8(1), U8(vector->GetIndex(slot1)), // B(Return), // }, - 4, - {"", "ab+d", "exec", "abdd"}}, + 3, + {"ab+d", "exec", "abdd"}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + Handle<BytecodeArray> bytecode_array = + helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + + +TEST(RegExpLiteralsWide) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + Zone zone; + + int wide_idx = 0; + + ExpectedSnippet<InstanceType, 257> snippets[] = { + {"var a;" REPEAT_256(SPACE, "a = 1.23;") "return /ab+d/;", + 1 * kPointerSize, + 1, + 1031, + { + REPEAT_256(COMMA, // + B(LdaConstant), U8(wide_idx++), // + B(Star), R(0)), // + B(CreateRegExpLiteralWide), U16(256), U16(0), U8(0), // + B(Return) // + }, + 257, + {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), + InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, }; for (size_t i = 0; i < arraysize(snippets); i++) { @@ -2920,23 +3542,21 @@ TEST(ArrayLiterals) { {"return [ 1, 2 ];", 0, 1, - 6, + 5, { - B(LdaConstant), U8(0), // - B(CreateArrayLiteral), U8(0), U8(simple_flags), // - B(Return) // + B(CreateArrayLiteral), U8(0), U8(0), U8(simple_flags), // + B(Return) // }, 1, {InstanceType::FIXED_ARRAY_TYPE}}, {"var a = 1; return [ a, a + 1 ];", - 3 * kPointerSize, + 4 * kPointerSize, 1, - 35, + 38, { B(LdaSmi8), U8(1), // B(Star), R(0), // - B(LdaConstant), U8(0), // - B(CreateArrayLiteral), U8(0), U8(3), // + B(CreateArrayLiteral), U8(0), U8(0), U8(3), // B(Star), R(2), // B(LdaZero), // B(Star), R(1), // @@ -2944,8 +3564,10 @@ TEST(ArrayLiterals) { B(KeyedStoreICSloppy), R(2), R(1), U8(vector->GetIndex(slot1)), // B(LdaSmi8), U8(1), // B(Star), R(1), // + B(Ldar), R(0), // + B(Star), R(3), // B(LdaSmi8), U8(1), // - B(Add), R(0), // + B(Add), R(3), // B(KeyedStoreICSloppy), R(2), R(1), U8(vector->GetIndex(slot1)), // B(Ldar), R(2), // B(Return), // @@ -2955,28 +3577,25 @@ TEST(ArrayLiterals) { {"return [ [ 1, 2 ], [ 3 ] ];", 0, 1, - 6, + 5, { - B(LdaConstant), U8(0), // - B(CreateArrayLiteral), U8(2), U8(deep_elements_flags), // - B(Return) // + B(CreateArrayLiteral), U8(0), U8(2), U8(deep_elements_flags), // + B(Return) // }, 1, {InstanceType::FIXED_ARRAY_TYPE}}, {"var a = 1; return [ [ a, 2 ], [ a + 2 ] ];", - 5 * kPointerSize, + 6 * kPointerSize, 1, - 67, + 68, { B(LdaSmi8), U8(1), // B(Star), R(0), // - B(LdaConstant), U8(0), // - B(CreateArrayLiteral), U8(2), U8(deep_elements_flags), // + B(CreateArrayLiteral), U8(0), U8(2), U8(deep_elements_flags), // B(Star), R(2), // B(LdaZero), // B(Star), R(1), // - B(LdaConstant), U8(1), // - B(CreateArrayLiteral), U8(0), U8(simple_flags), // + B(CreateArrayLiteral), U8(1), U8(0), U8(simple_flags), // B(Star), R(4), // B(LdaZero), // B(Star), R(3), // @@ -2986,13 +3605,14 @@ TEST(ArrayLiterals) { B(KeyedStoreICSloppy), R(2), R(1), U8(vector->GetIndex(slot3)), // B(LdaSmi8), U8(1), // B(Star), R(1), // - B(LdaConstant), U8(2), // - B(CreateArrayLiteral), U8(1), U8(simple_flags), // + B(CreateArrayLiteral), U8(2), U8(1), U8(simple_flags), // B(Star), R(4), // B(LdaZero), // B(Star), R(3), // + B(Ldar), R(0), // + B(Star), R(5), // B(LdaSmi8), U8(2), // - B(Add), R(0), // + B(Add), R(5), // B(KeyedStoreICSloppy), R(4), R(3), U8(vector->GetIndex(slot2)), // B(Ldar), R(4), // B(KeyedStoreICSloppy), R(2), R(1), U8(vector->GetIndex(slot3)), // @@ -3012,6 +3632,40 @@ TEST(ArrayLiterals) { } +TEST(ArrayLiteralsWide) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + Zone zone; + + int wide_idx = 0; + int simple_flags = + ArrayLiteral::kDisableMementos | ArrayLiteral::kShallowElements; + + ExpectedSnippet<InstanceType, 257> snippets[] = { + {"var a;" REPEAT_256(SPACE, "a = 1.23;") "return [ 1 , 2 ];", + 1 * kPointerSize, + 1, + 1031, + { + REPEAT_256(COMMA, // + B(LdaConstant), U8(wide_idx++), // + B(Star), R(0)), // + B(CreateArrayLiteralWide), U16(256), U16(0), U8(simple_flags), // + B(Return) // + }, + 257, + {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), + InstanceType::FIXED_ARRAY_TYPE}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + Handle<BytecodeArray> bytecode_array = + helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + + TEST(ObjectLiterals) { InitializedHandleScope handle_scope; BytecodeGeneratorHelper helper; @@ -3032,58 +3686,56 @@ TEST(ObjectLiterals) { {"return { };", 0, 1, - 6, + 5, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(simple_flags), // - B(Return) // + B(CreateObjectLiteral), U8(0), U8(0), U8(simple_flags), // + B(Return) // }, 1, {InstanceType::FIXED_ARRAY_TYPE}}, {"return { name: 'string', val: 9.2 };", 0, 1, - 6, + 5, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // - B(Return) // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // + B(Return) // }, 1, {InstanceType::FIXED_ARRAY_TYPE}}, {"var a = 1; return { name: 'string', val: a };", 2 * kPointerSize, 1, - 20, + 19, { - B(LdaSmi8), U8(1), // - B(Star), R(0), // - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // - B(Star), R(1), // - B(Ldar), R(0), // - B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)), // - B(Ldar), R(1), // - B(Return), // + B(LdaSmi8), U8(1), // + B(Star), R(0), // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // + B(Star), R(1), // + B(Ldar), R(0), // + B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)), // + B(Ldar), R(1), // + B(Return), // }, 2, {InstanceType::FIXED_ARRAY_TYPE, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, {"var a = 1; return { val: a, val: a + 1 };", - 2 * kPointerSize, + 3 * kPointerSize, 1, - 22, + 25, { - B(LdaSmi8), U8(1), // - B(Star), R(0), // - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // - B(Star), R(1), // - B(LdaSmi8), U8(1), // - B(Add), R(0), // - B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)), // - B(Ldar), R(1), // - B(Return), // + B(LdaSmi8), U8(1), // + B(Star), R(0), // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // + B(Star), R(1), // + B(Ldar), R(0), // + B(Star), R(2), // + B(LdaSmi8), U8(1), // + B(Add), R(2), // + B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)), // + B(Ldar), R(1), // + B(Return), // }, 2, {InstanceType::FIXED_ARRAY_TYPE, @@ -3091,51 +3743,45 @@ TEST(ObjectLiterals) { {"return { func: function() { } };", 1 * kPointerSize, 1, - 18, + 16, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // - B(Star), R(0), // - B(LdaConstant), U8(2), // - B(CreateClosure), U8(0), // - B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), // - B(Ldar), R(0), // - B(Return), // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // + B(Star), R(0), // + B(CreateClosure), U8(1), U8(0), // + B(StoreICSloppy), R(0), U8(2), U8(vector->GetIndex(slot1)), // + B(Ldar), R(0), // + B(Return), // }, 3, {InstanceType::FIXED_ARRAY_TYPE, - InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, - InstanceType::SHARED_FUNCTION_INFO_TYPE}}, + InstanceType::SHARED_FUNCTION_INFO_TYPE, + InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, {"return { func(a) { return a; } };", 1 * kPointerSize, 1, - 18, + 16, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // - B(Star), R(0), // - B(LdaConstant), U8(2), // - B(CreateClosure), U8(0), // - B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), // - B(Ldar), R(0), // - B(Return), // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // + B(Star), R(0), // + B(CreateClosure), U8(1), U8(0), // + B(StoreICSloppy), R(0), U8(2), U8(vector->GetIndex(slot1)), // + B(Ldar), R(0), // + B(Return), // }, 3, {InstanceType::FIXED_ARRAY_TYPE, - InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, - InstanceType::SHARED_FUNCTION_INFO_TYPE}}, + InstanceType::SHARED_FUNCTION_INFO_TYPE, + InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, {"return { get a() { return 2; } };", 5 * kPointerSize, 1, - 31, + 29, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // B(Star), R(0), // B(LdaConstant), U8(1), // B(Star), R(1), // - B(LdaConstant), U8(2), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(2), U8(0), // B(Star), R(2), // B(LdaNull), // B(Star), R(3), // @@ -3153,18 +3799,15 @@ TEST(ObjectLiterals) { {"return { get a() { return this.x; }, set a(val) { this.x = val } };", 5 * kPointerSize, 1, - 34, + 31, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // B(Star), R(0), // B(LdaConstant), U8(1), // B(Star), R(1), // - B(LdaConstant), U8(2), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(2), U8(0), // B(Star), R(2), // - B(LdaConstant), U8(3), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(3), U8(0), // B(Star), R(3), // B(LdaZero), // B(Star), R(4), // @@ -3181,17 +3824,15 @@ TEST(ObjectLiterals) { {"return { set b(val) { this.y = val } };", 5 * kPointerSize, 1, - 31, + 29, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // B(Star), R(0), // B(LdaConstant), U8(1), // B(Star), R(1), // B(LdaNull), // B(Star), R(2), // - B(LdaConstant), U8(2), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(2), U8(0), // B(Star), R(3), // B(LdaZero), // B(Star), R(4), // @@ -3207,32 +3848,30 @@ TEST(ObjectLiterals) { {"var a = 1; return { 1: a };", 5 * kPointerSize, 1, - 30, + 29, { - B(LdaSmi8), U8(1), // - B(Star), R(0), // - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // - B(Star), R(1), // - B(LdaSmi8), U8(1), // - B(Star), R(2), // - B(Ldar), R(0), // - B(Star), R(3), // - B(LdaZero), // - B(Star), R(4), // - B(CallRuntime), U16(Runtime::kSetProperty), R(1), U8(4), // - B(Ldar), R(1), // - B(Return), // + B(LdaSmi8), U8(1), // + B(Star), R(0), // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(Star), R(2), // + B(Ldar), R(0), // + B(Star), R(3), // + B(LdaZero), // + B(Star), R(4), // + B(CallRuntime), U16(Runtime::kSetProperty), R(1), U8(4), // + B(Ldar), R(1), // + B(Return), // }, 1, {InstanceType::FIXED_ARRAY_TYPE}}, {"return { __proto__: null }", 2 * kPointerSize, 1, - 18, + 17, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(simple_flags), // + B(CreateObjectLiteral), U8(0), U8(0), U8(simple_flags), // B(Star), R(0), // B(LdaNull), B(Star), R(1), // B(CallRuntime), U16(Runtime::kInternalSetPrototype), R(0), U8(2), // @@ -3244,12 +3883,11 @@ TEST(ObjectLiterals) { {"var a = 'test'; return { [a]: 1 }", 5 * kPointerSize, 1, - 31, + 30, { B(LdaConstant), U8(0), // B(Star), R(0), // - B(LdaConstant), U8(1), // - B(CreateObjectLiteral), U8(0), U8(simple_flags), // + B(CreateObjectLiteral), U8(1), U8(0), U8(simple_flags), // B(Star), R(1), // B(Ldar), R(0), // B(ToName), // @@ -3269,12 +3907,11 @@ TEST(ObjectLiterals) { {"var a = 'test'; return { val: a, [a]: 1 }", 5 * kPointerSize, 1, - 37, + 36, { B(LdaConstant), U8(0), // B(Star), R(0), // - B(LdaConstant), U8(1), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // + B(CreateObjectLiteral), U8(1), U8(0), U8(deep_elements_flags), // B(Star), R(1), // B(Ldar), R(0), // B(StoreICSloppy), R(1), U8(2), U8(vector->GetIndex(slot1)), // @@ -3297,12 +3934,11 @@ TEST(ObjectLiterals) { {"var a = 'test'; return { [a]: 1, __proto__: {} }", 5 * kPointerSize, 1, - 43, + 41, { B(LdaConstant), U8(0), // B(Star), R(0), // - B(LdaConstant), U8(1), // - B(CreateObjectLiteral), U8(1), U8(simple_flags), // + B(CreateObjectLiteral), U8(1), U8(1), U8(simple_flags), // B(Star), R(1), // B(Ldar), R(0), // B(ToName), // @@ -3313,8 +3949,7 @@ TEST(ObjectLiterals) { B(Star), R(4), // B(CallRuntime), U16(Runtime::kDefineDataPropertyUnchecked), R(1), // U8(4), // - B(LdaConstant), U8(1), // - B(CreateObjectLiteral), U8(0), U8(13), // + B(CreateObjectLiteral), U8(1), U8(0), U8(13), // B(Star), R(2), // B(CallRuntime), U16(Runtime::kInternalSetPrototype), R(1), U8(2), // B(Ldar), R(1), // @@ -3326,12 +3961,11 @@ TEST(ObjectLiterals) { {"var n = 'name'; return { [n]: 'val', get a() { }, set a(b) {} };", 5 * kPointerSize, 1, - 69, + 64, { B(LdaConstant), U8(0), // B(Star), R(0), // - B(LdaConstant), U8(1), // - B(CreateObjectLiteral), U8(0), U8(simple_flags), // + B(CreateObjectLiteral), U8(1), U8(0), U8(simple_flags), // B(Star), R(1), // B(Ldar), R(0), // B(ToName), // @@ -3343,20 +3977,16 @@ TEST(ObjectLiterals) { B(CallRuntime), U16(Runtime::kDefineDataPropertyUnchecked), R(1), // U8(4), // B(LdaConstant), U8(3), // - B(ToName), // B(Star), R(2), // - B(LdaConstant), U8(4), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(4), U8(0), // B(Star), R(3), // B(LdaZero), // B(Star), R(4), // B(CallRuntime), U16(Runtime::kDefineGetterPropertyUnchecked), // R(1), U8(4), // B(LdaConstant), U8(3), // - B(ToName), // B(Star), R(2), // - B(LdaConstant), U8(5), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(5), U8(0), // B(Star), R(3), // B(LdaZero), // B(Star), R(4), // @@ -3382,6 +4012,42 @@ TEST(ObjectLiterals) { } +TEST(ObjectLiteralsWide) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + Zone zone; + + int deep_elements_flags = + ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; + int wide_idx = 0; + + ExpectedSnippet<InstanceType, 257> snippets[] = { + {"var a;" REPEAT_256(SPACE, + "a = 1.23;") "return { name: 'string', val: 9.2 };", + 1 * kPointerSize, + 1, + 1031, + { + REPEAT_256(COMMA, // + B(LdaConstant), U8(wide_idx++), // + B(Star), R(0)), // + B(CreateObjectLiteralWide), U16(256), U16(0), // + U8(deep_elements_flags), // + B(Return) // + }, + 257, + {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), + InstanceType::FIXED_ARRAY_TYPE}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + Handle<BytecodeArray> bytecode_array = + helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + + TEST(TopLevelObjectLiterals) { InitializedHandleScope handle_scope; BytecodeGeneratorHelper helper; @@ -3393,7 +4059,7 @@ TEST(TopLevelObjectLiterals) { {"var a = { func: function() { } };", 5 * kPointerSize, 1, - 50, + 48, { B(LdaConstant), U8(0), // B(Star), R(1), // @@ -3404,12 +4070,10 @@ TEST(TopLevelObjectLiterals) { B(Star), R(1), // B(LdaZero), // B(Star), R(2), // - B(LdaConstant), U8(2), // - B(CreateObjectLiteral), U8(0), U8(has_function_flags), // + B(CreateObjectLiteral), U8(2), U8(0), U8(has_function_flags), // B(Star), R(4), // - B(LdaConstant), U8(4), // - B(CreateClosure), U8(1), // - B(StoreICSloppy), R(4), U8(3), U8(5), // + B(CreateClosure), U8(3), U8(1), // + B(StoreICSloppy), R(4), U8(4), U8(3), // B(CallRuntime), U16(Runtime::kToFastProperties), R(4), U8(1), // B(Ldar), R(4), // B(Star), R(3), // @@ -3421,8 +4085,8 @@ TEST(TopLevelObjectLiterals) { {InstanceType::FIXED_ARRAY_TYPE, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, InstanceType::FIXED_ARRAY_TYPE, - InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, - InstanceType::SHARED_FUNCTION_INFO_TYPE}}, + InstanceType::SHARED_FUNCTION_INFO_TYPE, + InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, }; for (size_t i = 0; i < arraysize(snippets); i++) { @@ -3532,11 +4196,10 @@ TEST(Throw) { {"var a = 1; if (a) { throw 'Error'; };", 1 * kPointerSize, 1, - 13, + 11, { B(LdaSmi8), U8(1), // B(Star), R(0), // - B(Ldar), R(0), // B(JumpIfToBooleanFalse), U8(5), // B(LdaConstant), U8(0), // B(Throw), // @@ -3637,20 +4300,34 @@ TEST(CallNew) { TEST(ContextVariables) { InitializedHandleScope handle_scope; BytecodeGeneratorHelper helper; + Zone zone; + + FeedbackVectorSpec feedback_spec(&zone); + FeedbackVectorSlot slot = feedback_spec.AddCallICSlot(); + + Handle<i::TypeFeedbackVector> vector = + i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); int closure = Register::function_closure().index(); + int new_target = Register::new_target().index(); int first_context_slot = Context::MIN_CONTEXT_SLOTS; + + // The wide check below relies on MIN_CONTEXT_SLOTS + 3 + 249 == 256, if this + // ever changes, the REPEAT_XXX should be changed to output the correct number + // of unique variables to trigger the wide slot load / store. + STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS + 3 + 249 == 256); + int wide_slot = first_context_slot + 3; + ExpectedSnippet<InstanceType> snippets[] = { {"var a; return function() { a = 1; };", 1 * kPointerSize, 1, - 12, + 11, { B(CallRuntime), U16(Runtime::kNewFunctionContext), // R(closure), U8(1), // B(PushContext), R(0), // - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(0), U8(0), // B(Return), // }, 1, @@ -3658,15 +4335,14 @@ TEST(ContextVariables) { {"var a = 1; return function() { a = 2; };", 1 * kPointerSize, 1, - 17, + 16, { B(CallRuntime), U16(Runtime::kNewFunctionContext), // R(closure), U8(1), // B(PushContext), R(0), // B(LdaSmi8), U8(1), // B(StaContextSlot), R(0), U8(first_context_slot), // - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(0), U8(0), // B(Return), // }, 1, @@ -3674,7 +4350,7 @@ TEST(ContextVariables) { {"var a = 1; var b = 2; return function() { a = 2; b = 3 };", 1 * kPointerSize, 1, - 22, + 21, { B(CallRuntime), U16(Runtime::kNewFunctionContext), // R(closure), U8(1), // @@ -3683,8 +4359,7 @@ TEST(ContextVariables) { B(StaContextSlot), R(0), U8(first_context_slot), // B(LdaSmi8), U8(2), // B(StaContextSlot), R(0), U8(first_context_slot + 1), // - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(0), U8(0), // B(Return), // }, 1, @@ -3694,24 +4369,23 @@ TEST(ContextVariables) { 1, 24, { - B(CallRuntime), U16(Runtime::kNewFunctionContext), // - R(closure), U8(1), // - B(PushContext), R(0), // - B(LdaUndefined), // - B(Star), R(2), // - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // - B(Star), R(1), // - B(Call), R(1), R(2), U8(0), // - B(LdaContextSlot), R(0), U8(first_context_slot), // - B(Return), // + B(CallRuntime), U16(Runtime::kNewFunctionContext), // + R(closure), U8(1), // + B(PushContext), R(0), // + B(LdaUndefined), // + B(Star), R(2), // + B(CreateClosure), U8(0), U8(0), // + B(Star), R(1), // + B(Call), R(1), R(2), U8(0), U8(vector->GetIndex(slot)), // + B(LdaContextSlot), R(0), U8(first_context_slot), // + B(Return), // }, 1, {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, {"'use strict'; let a = 1; { let b = 2; return function() { a + b; }; }", 4 * kPointerSize, 1, - 45, + 44, { B(CallRuntime), U16(Runtime::kNewFunctionContext), // R(closure), U8(1), // @@ -3730,13 +4404,45 @@ TEST(ContextVariables) { B(StaContextSlot), R(1), U8(first_context_slot), // B(LdaSmi8), U8(2), // B(StaContextSlot), R(1), U8(first_context_slot), // - B(LdaConstant), U8(1), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(1), U8(0), // B(Return), // }, 2, {InstanceType::FIXED_ARRAY_TYPE, InstanceType::SHARED_FUNCTION_INFO_TYPE}}, + {"'use strict';\n" + REPEAT_249_UNIQUE_VARS() + "eval();" + "var b = 100;" + "return b", + 3 * kPointerSize, + 1, + 1041, + { + B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // + U8(1), // + B(PushContext), R(0), // + B(Ldar), THIS(1), // + B(StaContextSlot), R(0), U8(first_context_slot), // + B(CreateUnmappedArguments), // + B(StaContextSlot), R(0), U8(first_context_slot + 1), // + B(Ldar), R(new_target), // + B(StaContextSlot), R(0), U8(first_context_slot + 2), // + REPEAT_249(COMMA, // + B(LdaZero), // + B(StaContextSlot), R(0), U8(wide_slot++)), // + B(LdaUndefined), // + B(Star), R(2), // + B(LdaGlobalStrict), U8(0), U8(1), // + B(Star), R(1), // + B(Call), R(1), R(2), U8(0), U8(0), // + B(LdaSmi8), U8(100), // + B(StaContextSlotWide), R(0), U16(256), // + B(LdaContextSlotWide), R(0), U16(256), // + B(Return), // + }, + 1, + {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, }; for (size_t i = 0; i < arraysize(snippets); i++) { @@ -3758,15 +4464,14 @@ TEST(ContextParameters) { {"function f(arg1) { return function() { arg1 = 2; }; }", 1 * kPointerSize, 2, - 17, + 16, { B(CallRuntime), U16(Runtime::kNewFunctionContext), // R(closure), U8(1), // B(PushContext), R(0), // B(Ldar), R(helper.kLastParamIndex), // B(StaContextSlot), R(0), U8(first_context_slot), // - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(0), U8(0), // B(Return), // }, 1, @@ -3774,15 +4479,14 @@ TEST(ContextParameters) { {"function f(arg1) { var a = function() { arg1 = 2; }; return arg1; }", 2 * kPointerSize, 2, - 22, + 21, { B(CallRuntime), U16(Runtime::kNewFunctionContext), // R(closure), U8(1), // B(PushContext), R(1), // B(Ldar), R(helper.kLastParamIndex), // B(StaContextSlot), R(1), U8(first_context_slot), // - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(0), U8(0), // B(Star), R(0), // B(LdaContextSlot), R(1), U8(first_context_slot), // B(Return), // @@ -3792,7 +4496,7 @@ TEST(ContextParameters) { {"function f(a1, a2, a3, a4) { return function() { a1 = a3; }; }", 1 * kPointerSize, 5, - 22, + 21, { B(CallRuntime), U16(Runtime::kNewFunctionContext), // R(closure), U8(1), // @@ -3801,8 +4505,7 @@ TEST(ContextParameters) { B(StaContextSlot), R(0), U8(first_context_slot + 1), // B(Ldar), R(helper.kLastParamIndex -1), // B(StaContextSlot), R(0), U8(first_context_slot), // - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(0), U8(0), // B(Return), // }, 1, @@ -3810,15 +4513,14 @@ TEST(ContextParameters) { {"function f() { var self = this; return function() { self = 2; }; }", 1 * kPointerSize, 1, - 17, + 16, { B(CallRuntime), U16(Runtime::kNewFunctionContext), // R(closure), U8(1), // B(PushContext), R(0), // B(Ldar), R(helper.kLastParamIndex), // B(StaContextSlot), R(0), U8(first_context_slot), // - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(0), U8(0), // B(Return), // }, 1, @@ -3924,11 +4626,10 @@ TEST(CountOperators) { {"var a = 1; return ++a;", 1 * kPointerSize, 1, - 11, + 9, { B(LdaSmi8), U8(1), // B(Star), R(0), // - B(Ldar), R(0), // B(ToNumber), // B(Inc), // B(Star), R(0), // @@ -3937,11 +4638,10 @@ TEST(CountOperators) { {"var a = 1; return a++;", 2 * kPointerSize, 1, - 15, + 13, { B(LdaSmi8), U8(1), // B(Star), R(0), // - B(Ldar), R(0), // B(ToNumber), // B(Star), R(1), // B(Inc), // @@ -3952,11 +4652,10 @@ TEST(CountOperators) { {"var a = 1; return --a;", 1 * kPointerSize, 1, - 11, + 9, { B(LdaSmi8), U8(1), // B(Star), R(0), // - B(Ldar), R(0), // B(ToNumber), // B(Dec), // B(Star), R(0), // @@ -3965,11 +4664,10 @@ TEST(CountOperators) { {"var a = 1; return a--;", 2 * kPointerSize, 1, - 15, + 13, { B(LdaSmi8), U8(1), // B(Star), R(0), // - B(Ldar), R(0), // B(ToNumber), // B(Star), R(1), // B(Dec), // @@ -3978,80 +4676,80 @@ TEST(CountOperators) { B(Return), // }}, {"var a = { val: 1 }; return a.val++;", - 2 * kPointerSize, + 3 * kPointerSize, 1, - 22, + 23, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(object_literal_flags), // - B(Star), R(0), // - B(LoadICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), // - B(ToNumber), // - B(Star), R(1), // - B(Inc), // - B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot2)), // - B(Ldar), R(1), // - B(Return), // + B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags), // + B(Star), R(0), // + B(Star), R(1), // + B(LoadICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)), // + B(ToNumber), // + B(Star), R(2), // + B(Inc), // + B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot2)), // + B(Ldar), R(2), // + B(Return), // }, 2, {InstanceType::FIXED_ARRAY_TYPE, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, {"var a = { val: 1 }; return --a.val;", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 18, + 19, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(object_literal_flags), // - B(Star), R(0), // - B(LoadICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), // - B(ToNumber), // - B(Dec), // - B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot2)), // - B(Return), // + B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags), // + B(Star), R(0), // + B(Star), R(1), // + B(LoadICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)), // + B(ToNumber), // + B(Dec), // + B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot2)), // + B(Return), // }, 2, {InstanceType::FIXED_ARRAY_TYPE, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, {"var name = 'var'; var a = { val: 1 }; return a[name]--;", - 4 * kPointerSize, + 5 * kPointerSize, 1, - 29, + 30, { B(LdaConstant), U8(0), // B(Star), R(0), // - B(LdaConstant), U8(1), // - B(CreateObjectLiteral), U8(0), U8(object_literal_flags), // + B(CreateObjectLiteral), U8(1), U8(0), U8(object_literal_flags), // B(Star), R(1), // - B(Ldar), R(0), // B(Star), R(2), // - B(KeyedLoadICSloppy), R(1), U8(vector->GetIndex(slot1)), // - B(ToNumber), // + B(Ldar), R(0), // B(Star), R(3), // + B(KeyedLoadICSloppy), R(2), U8(vector->GetIndex(slot1)), // + B(ToNumber), // + B(Star), R(4), // B(Dec), // - B(KeyedStoreICSloppy), R(1), R(2), U8(vector->GetIndex(slot2)), // - B(Ldar), R(3), // + B(KeyedStoreICSloppy), R(2), R(3), U8(vector->GetIndex(slot2)), // + B(Ldar), R(4), // B(Return), // }, 2, {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, InstanceType::FIXED_ARRAY_TYPE}}, {"var name = 'var'; var a = { val: 1 }; return ++a[name];", - 3 * kPointerSize, + 4 * kPointerSize, 1, - 25, + 26, { B(LdaConstant), U8(0), // B(Star), R(0), // - B(LdaConstant), U8(1), // - B(CreateObjectLiteral), U8(0), U8(object_literal_flags), // + B(CreateObjectLiteral), U8(1), U8(0), U8(object_literal_flags), // B(Star), R(1), // - B(Ldar), R(0), // B(Star), R(2), // - B(KeyedLoadICSloppy), R(1), U8(vector->GetIndex(slot1)), // + B(Ldar), R(0), // + B(Star), R(3), // + B(KeyedLoadICSloppy), R(2), U8(vector->GetIndex(slot1)), // B(ToNumber), // B(Inc), // - B(KeyedStoreICSloppy), R(1), R(2), U8(vector->GetIndex(slot2)), // + B(KeyedStoreICSloppy), R(2), R(3), U8(vector->GetIndex(slot2)), // B(Return), // }, 2, @@ -4060,15 +4758,14 @@ TEST(CountOperators) { {"var a = 1; var b = function() { return a }; return ++a;", 2 * kPointerSize, 1, - 27, + 26, { B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // U8(1), // B(PushContext), R(1), // B(LdaSmi8), U8(1), // B(StaContextSlot), R(1), U8(first_context_slot), // - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(0), U8(0), // B(Star), R(0), // B(LdaContextSlot), R(1), U8(first_context_slot), // B(ToNumber), // @@ -4081,15 +4778,14 @@ TEST(CountOperators) { {"var a = 1; var b = function() { return a }; return a--;", 3 * kPointerSize, 1, - 31, + 30, { B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // U8(1), // B(PushContext), R(1), // B(LdaSmi8), U8(1), // B(StaContextSlot), R(1), U8(first_context_slot), // - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(0), U8(0), // B(Star), R(0), // B(LdaContextSlot), R(1), U8(first_context_slot), // B(ToNumber), // @@ -4102,22 +4798,22 @@ TEST(CountOperators) { 1, {InstanceType::SHARED_FUNCTION_INFO_TYPE}}, {"var idx = 1; var a = [1, 2]; return a[idx++] = 2;", - 3 * kPointerSize, + 4 * kPointerSize, 1, - 26, + 27, { B(LdaSmi8), U8(1), // B(Star), R(0), // - B(LdaConstant), U8(0), // - B(CreateArrayLiteral), U8(0), U8(array_literal_flags), // + B(CreateArrayLiteral), U8(0), U8(0), U8(array_literal_flags), // B(Star), R(1), // + B(Star), R(2), // B(Ldar), R(0), // B(ToNumber), // - B(Star), R(2), // + B(Star), R(3), // B(Inc), // B(Star), R(0), // B(LdaSmi8), U8(2), // - B(KeyedStoreICSloppy), R(1), R(2), // + B(KeyedStoreICSloppy), R(2), R(3), // U8(store_vector->GetIndex(store_slot)), // B(Return), // }, @@ -4232,65 +4928,67 @@ TEST(CompoundExpressions) { ObjectLiteral::kFastElements | ObjectLiteral::kDisableMementos; ExpectedSnippet<InstanceType> snippets[] = { {"var a = 1; a += 2;", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 12, + 14, { B(LdaSmi8), U8(1), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(2), // - B(Add), R(0), // + B(Add), R(1), // B(Star), R(0), // B(LdaUndefined), // B(Return), // }}, {"var a = 1; a /= 2;", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 12, + 14, { B(LdaSmi8), U8(1), // B(Star), R(0), // + B(Star), R(1), // B(LdaSmi8), U8(2), // - B(Div), R(0), // + B(Div), R(1), // B(Star), R(0), // B(LdaUndefined), // B(Return), // }}, {"var a = { val: 2 }; a.name *= 2;", - 2 * kPointerSize, + 3 * kPointerSize, 1, - 23, + 24, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(object_literal_flags), // - B(Star), R(0), // - B(LoadICSloppy), R(0), U8(1), U8(vector->GetIndex(slot1)), // - B(Star), R(1), // - B(LdaSmi8), U8(2), // - B(Mul), R(1), // - B(StoreICSloppy), R(0), U8(1), U8(vector->GetIndex(slot2)), // - B(LdaUndefined), // - B(Return), // + B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags), // + B(Star), R(0), // + B(Star), R(1), // + B(LoadICSloppy), R(1), U8(1), U8(vector->GetIndex(slot1)), // + B(Star), R(2), // + B(LdaSmi8), U8(2), // + B(Mul), R(2), // + B(StoreICSloppy), R(1), U8(1), U8(vector->GetIndex(slot2)), // + B(LdaUndefined), // + B(Return), // }, 2, {InstanceType::FIXED_ARRAY_TYPE, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, {"var a = { 1: 2 }; a[1] ^= 2;", - 3 * kPointerSize, + 4 * kPointerSize, 1, - 26, + 27, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(object_literal_flags), // + B(CreateObjectLiteral), U8(0), U8(0), U8(object_literal_flags), // B(Star), R(0), // - B(LdaSmi8), U8(1), // B(Star), R(1), // - B(KeyedLoadICSloppy), R(0), U8(vector->GetIndex(slot1)), // + B(LdaSmi8), U8(1), // B(Star), R(2), // + B(KeyedLoadICSloppy), R(1), U8(vector->GetIndex(slot1)), // + B(Star), R(3), // B(LdaSmi8), U8(2), // - B(BitwiseXor), R(2), // - B(KeyedStoreICSloppy), R(0), R(1), U8(vector->GetIndex(slot2)), // + B(BitwiseXor), R(3), // + B(KeyedStoreICSloppy), R(1), R(2), U8(vector->GetIndex(slot2)), // B(LdaUndefined), // B(Return), // }, @@ -4299,15 +4997,14 @@ TEST(CompoundExpressions) { {"var a = 1; (function f() { return a; }); a |= 24;", 2 * kPointerSize, 1, - 30, + 29, { B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // U8(1), // B(PushContext), R(0), // B(LdaSmi8), U8(1), // B(StaContextSlot), R(0), U8(first_context_slot), // - B(LdaConstant), U8(0), // - B(CreateClosure), U8(0), // + B(CreateClosure), U8(0), U8(0), // B(LdaContextSlot), R(0), U8(first_context_slot), // B(Star), R(1), // B(LdaSmi8), U8(24), // @@ -4397,38 +5094,37 @@ TEST(CreateArguments) { {"function f() { return arguments; }", 1 * kPointerSize, 1, - 6, + 4, { B(CreateMappedArguments), // B(Star), R(0), // - B(Ldar), R(0), // B(Return), // }}, {"function f() { return arguments[0]; }", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 8, + 10, { B(CreateMappedArguments), // B(Star), R(0), // + B(Star), R(1), // B(LdaZero), // - B(KeyedLoadICSloppy), R(0), U8(vector->GetIndex(slot)), // + B(KeyedLoadICSloppy), R(1), U8(vector->GetIndex(slot)), // B(Return), // }}, {"function f() { 'use strict'; return arguments; }", 1 * kPointerSize, 1, - 6, + 4, { B(CreateUnmappedArguments), // B(Star), R(0), // - B(Ldar), R(0), // B(Return), // }}, {"function f(a) { return arguments[0]; }", - 2 * kPointerSize, + 3 * kPointerSize, 2, - 20, + 22, { B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // U8(1), // @@ -4437,14 +5133,15 @@ TEST(CreateArguments) { B(StaContextSlot), R(1), U8(first_context_slot), // B(CreateMappedArguments), // B(Star), R(0), // + B(Star), R(2), // B(LdaZero), // - B(KeyedLoadICSloppy), R(0), U8(vector->GetIndex(slot)), // + B(KeyedLoadICSloppy), R(2), U8(vector->GetIndex(slot)), // B(Return), // }}, {"function f(a, b, c) { return arguments; }", 2 * kPointerSize, 4, - 28, + 26, { B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // U8(1), // @@ -4457,17 +5154,15 @@ TEST(CreateArguments) { B(StaContextSlot), R(1), U8(first_context_slot), // B(CreateMappedArguments), // B(Star), R(0), // - B(Ldar), R(0), // B(Return), // }}, {"function f(a, b, c) { 'use strict'; return arguments; }", 1 * kPointerSize, 4, - 6, + 4, { B(CreateUnmappedArguments), // B(Star), R(0), // - B(Ldar), R(0), // B(Return), // }}, }; @@ -4484,21 +5179,25 @@ TEST(IllegalRedeclaration) { InitializedHandleScope handle_scope; BytecodeGeneratorHelper helper; - ExpectedSnippet<const char*> snippets[] = { + CHECK_GE(MessageTemplate::kVarRedeclaration, 128); + // Must adapt bytecode if this changes. + + ExpectedSnippet<Handle<Object>, 2> snippets[] = { {"const a = 1; { var a = 2; }", 3 * kPointerSize, 1, 14, { - B(LdaSmi8), U8(MessageTemplate::kVarRedeclaration), // - B(Star), R(1), // B(LdaConstant), U8(0), // + B(Star), R(1), // + B(LdaConstant), U8(1), // B(Star), R(2), // B(CallRuntime), U16(Runtime::kNewSyntaxError), R(1), U8(2), // B(Throw), // }, - 1, - {"a"}}, + 2, + {helper.factory()->NewNumberFromInt(MessageTemplate::kVarRedeclaration), + helper.factory()->NewStringFromAsciiChecked("a")}}, }; for (size_t i = 0; i < arraysize(snippets); i++) { @@ -4540,77 +5239,76 @@ TEST(ForIn) { 2, {B(LdaUndefined), B(Return)}, 0}, + {"for (var p in undefined) {}", + 2 * kPointerSize, + 1, + 2, + {B(LdaUndefined), B(Return)}, + 0}, {"var x = 'potatoes';\n" "for (var p in x) { return p; }", - 5 * kPointerSize, + 8 * kPointerSize, 1, - 52, + 45, { - B(LdaConstant), U8(0), // - B(Star), R(1), // - B(Ldar), R(1), // - B(JumpIfUndefined), U8(44), // - B(JumpIfNull), U8(42), // - B(ToObject), // - B(Star), R(3), // - B(CallRuntime), U16(Runtime::kGetPropertyNamesFast), R(3), U8(1), // - B(ForInPrepare), R(3), // - B(JumpIfUndefined), U8(30), // - B(Star), R(4), // - B(LdaZero), // - B(Star), R(3), // - B(ForInDone), R(4), // - B(JumpIfTrue), U8(21), // - B(ForInNext), R(4), R(3), // - B(JumpIfUndefined), U8(11), // - B(Star), R(0), // - B(Ldar), R(0), // - B(Star), R(2), // - B(Ldar), R(2), // - B(Return), // - B(Ldar), R(3), // - B(Inc), // - B(Jump), U8(-23), // - B(LdaUndefined), // - B(Return), // + B(LdaConstant), U8(0), // + B(Star), R(1), // + B(JumpIfUndefined), U8(39), // + B(JumpIfNull), U8(37), // + B(ToObject), // + B(JumpIfNull), U8(34), // + B(Star), R(3), // + B(ForInPrepare), R(4), R(5), R(6), // + B(LdaZero), // + B(Star), R(7), // + B(ForInDone), R(7), R(6), // + B(JumpIfTrue), U8(20), // + B(ForInNext), R(3), R(4), R(5), R(7), // + B(JumpIfUndefined), U8(7), // + B(Star), R(0), // + B(Star), R(2), // + B(Return), // + B(ForInStep), R(7), // + B(Star), R(7), // + B(Jump), U8(-21), // + B(LdaUndefined), // + B(Return), // }, 1, {InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, {"var x = 0;\n" "for (var p in [1,2,3]) { x += p; }", - 5 * kPointerSize, + 9 * kPointerSize, 1, 57, { - B(LdaZero), // - B(Star), R(1), // - B(LdaConstant), U8(0), // - B(CreateArrayLiteral), U8(0), U8(simple_flags), // - B(JumpIfUndefined), U8(47), // - B(JumpIfNull), U8(45), // - B(ToObject), // - B(Star), R(3), // - B(CallRuntime), U16(Runtime::kGetPropertyNamesFast), R(3), U8(1), // - B(ForInPrepare), R(3), // - B(JumpIfUndefined), U8(33), // - B(Star), R(4), // - B(LdaZero), // - B(Star), R(3), // - B(ForInDone), R(4), // - B(JumpIfTrue), U8(24), // - B(ForInNext), R(4), R(3), // - B(JumpIfUndefined), U8(14), // - B(Star), R(0), // - B(Ldar), R(0), // - B(Star), R(2), // - B(Ldar), R(2), // - B(Add), R(1), // - B(Star), R(1), // - B(Ldar), R(3), // - B(Inc), // - B(Jump), U8(-26), // - B(LdaUndefined), // - B(Return), // + B(LdaZero), // + B(Star), R(1), // + B(CreateArrayLiteral), U8(0), U8(0), U8(3), // + B(JumpIfUndefined), U8(48), // + B(JumpIfNull), U8(46), // + B(ToObject), // + B(JumpIfNull), U8(43), // + B(Star), R(3), // + B(ForInPrepare), R(4), R(5), R(6), // + B(LdaZero), // + B(Star), R(7), // + B(ForInDone), R(7), R(6), // + B(JumpIfTrue), U8(29), // + B(ForInNext), R(3), R(4), R(5), R(7), // + B(JumpIfUndefined), U8(16), // + B(Star), R(0), // + B(Star), R(2), // + B(Ldar), R(1), // + B(Star), R(8), // + B(Ldar), R(2), // + B(Add), R(8), // + B(Star), R(1), // + B(ForInStep), R(7), // + B(Star), R(7), // + B(Jump), U8(-30), // + B(LdaUndefined), // + B(Return), // }, 1, {InstanceType::FIXED_ARRAY_TYPE}}, @@ -4619,90 +5317,93 @@ TEST(ForIn) { " if (x['a'] == 10) continue;\n" " if (x['a'] == 20) break;\n" "}", - 4 * kPointerSize, + 8 * kPointerSize, 1, - 83, + 94, { - B(LdaConstant), U8(0), // - B(CreateObjectLiteral), U8(0), U8(deep_elements_flags), // - B(Star), R(0), // - B(LdaConstant), U8(1), // - B(CreateArrayLiteral), U8(1), U8(simple_flags), // - B(JumpIfUndefined), U8(69), // - B(JumpIfNull), U8(67), // - B(ToObject), // - B(Star), R(1), // - B(CallRuntime), U16(Runtime::kGetPropertyNamesFast), R(1), U8(1), // - B(ForInPrepare), R(1), // - B(JumpIfUndefined), U8(55), // - B(Star), R(2), // - B(LdaZero), // - B(Star), R(1), // - B(ForInDone), R(2), // - B(JumpIfTrue), U8(46), // - B(ForInNext), R(2), R(1), // - B(JumpIfUndefined), U8(36), // - B(Star), R(3), // - B(StoreICSloppy), R(0), U8(2), U8(vector->GetIndex(slot4)), // - B(LoadICSloppy), R(0), U8(2), U8(vector->GetIndex(slot2)), // - B(Star), R(3), // - B(LdaSmi8), U8(10), // - B(TestEqual), R(3), // - B(JumpIfFalse), U8(4), // - B(Jump), U8(16), // - B(LoadICSloppy), R(0), U8(2), U8(vector->GetIndex(slot3)), // - B(Star), R(3), // - B(LdaSmi8), U8(20), // - B(TestEqual), R(3), // - B(JumpIfFalse), U8(4), // - B(Jump), U8(7), // - B(Ldar), R(1), // - B(Inc), // - B(Jump), U8(-48), // - B(LdaUndefined), // - B(Return), // + B(CreateObjectLiteral), U8(0), U8(0), U8(deep_elements_flags), // + B(Star), R(0), // + B(CreateArrayLiteral), U8(1), U8(1), U8(simple_flags), // + B(JumpIfUndefined), U8(82), // + B(JumpIfNull), U8(80), // + B(ToObject), // + B(JumpIfNull), U8(77), // + B(Star), R(1), // + B(ForInPrepare), R(2), R(3), R(4), // + B(LdaZero), // + B(Star), R(5), // + B(ForInDone), R(5), R(4), // + B(JumpIfTrue), U8(63), // + B(ForInNext), R(1), R(2), R(3), R(5), // + B(JumpIfUndefined), U8(50), // + B(Star), R(6), // + B(Ldar), R(0), // + B(Star), R(7), // + B(Ldar), R(6), // + B(StoreICSloppy), R(7), U8(2), U8(vector->GetIndex(slot4)), // + B(Ldar), R(0), // + B(Star), R(6), // + B(LoadICSloppy), R(6), U8(2), U8(vector->GetIndex(slot2)), // + B(Star), R(7), // + B(LdaSmi8), U8(10), // + B(TestEqual), R(7), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(20), // + B(Ldar), R(0), // + B(Star), R(6), // + B(LoadICSloppy), R(6), U8(2), U8(vector->GetIndex(slot3)), // + B(Star), R(7), // + B(LdaSmi8), U8(20), // + B(TestEqual), R(7), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(8), // + B(ForInStep), R(5), // + B(Star), R(5), // + B(Jump), U8(-64), // + B(LdaUndefined), // + B(Return), // }, 3, {InstanceType::FIXED_ARRAY_TYPE, InstanceType::FIXED_ARRAY_TYPE, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, {"var x = [ 10, 11, 12 ] ;\n" "for (x[0] in [1,2,3]) { return x[3]; }", - 5 * kPointerSize, + 9 * kPointerSize, 1, - 66, + 71, { - B(LdaConstant), U8(0), // - B(CreateArrayLiteral), U8(0), U8(simple_flags), // - B(Star), R(0), // - B(LdaConstant), U8(1), // - B(CreateArrayLiteral), U8(1), U8(simple_flags), // - B(JumpIfUndefined), U8(52), // - B(JumpIfNull), U8(50), // - B(ToObject), // - B(Star), R(1), // - B(CallRuntime), U16(Runtime::kGetPropertyNamesFast), R(1), U8(1), // - B(ForInPrepare), R(1), // - B(JumpIfUndefined), U8(38), // - B(Star), R(2), // - B(LdaZero), // - B(Star), R(1), // - B(ForInDone), R(2), // - B(JumpIfTrue), U8(29), // - B(ForInNext), R(2), R(1), // - B(JumpIfUndefined), U8(19), // - B(Star), R(3), // - B(LdaZero), // - B(Star), R(4), // - B(Ldar), R(3), // - B(KeyedStoreICSloppy), R(0), R(4), U8(vector->GetIndex(slot3)), // - B(LdaSmi8), U8(3), // - B(KeyedLoadICSloppy), R(0), U8(vector->GetIndex(slot2)), // - B(Return), // - B(Ldar), R(1), // - B(Inc), // - B(Jump), U8(-31), // - B(LdaUndefined), // - B(Return), // + B(CreateArrayLiteral), U8(0), U8(0), U8(simple_flags), // + B(Star), R(0), // + B(CreateArrayLiteral), U8(1), U8(1), U8(simple_flags), // + B(JumpIfUndefined), U8(59), // + B(JumpIfNull), U8(57), // + B(ToObject), // + B(JumpIfNull), U8(54), // + B(Star), R(1), // + B(ForInPrepare), R(2), R(3), R(4), // + B(LdaZero), // + B(Star), R(5), // + B(ForInDone), R(5), R(4), // + B(JumpIfTrue), U8(40), // + B(ForInNext), R(1), R(2), R(3), R(5), // + B(JumpIfUndefined), U8(27), // + B(Star), R(6), // + B(Ldar), R(0), // + B(Star), R(7), // + B(LdaZero), // + B(Star), R(8), // + B(Ldar), R(6), // + B(KeyedStoreICSloppy), R(7), R(8), U8(vector->GetIndex(slot3)), // + B(Ldar), R(0), // + B(Star), R(6), // + B(LdaSmi8), U8(3), // + B(KeyedLoadICSloppy), R(6), U8(vector->GetIndex(slot2)), // + B(Return), // + B(ForInStep), R(5), // + B(Star), R(5), // + B(Jump), U8(-41), // + B(LdaUndefined), // + B(Return), // }, 2, {InstanceType::FIXED_ARRAY_TYPE, InstanceType::FIXED_ARRAY_TYPE}}, @@ -4769,19 +5470,19 @@ TEST(Switch) { " case 1: return 2;\n" " case 2: return 3;\n" "}\n", - 2 * kPointerSize, + 3 * kPointerSize, 1, 30, { B(LdaSmi8), U8(1), // B(Star), R(1), // The tag variable is allocated as a - B(Ldar), R(1), // local by the parser, hence this - B(Star), R(0), // strange shuffling. + B(Star), R(0), // local by the parser, hence the store + B(Star), R(2), // to another local register. B(LdaSmi8), U8(1), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfTrue), U8(10), // B(LdaSmi8), U8(2), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfTrue), U8(7), // B(Jump), U8(8), // B(LdaSmi8), U8(2), // @@ -4796,19 +5497,19 @@ TEST(Switch) { " case 1: a = 2; break;\n" " case 2: a = 3; break;\n" "}\n", - 2 * kPointerSize, + 3 * kPointerSize, 1, 36, { B(LdaSmi8), U8(1), // B(Star), R(1), // - B(Ldar), R(1), // B(Star), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(1), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfTrue), U8(10), // B(LdaSmi8), U8(2), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfTrue), U8(10), // B(Jump), U8(14), // B(LdaSmi8), U8(2), // @@ -4825,19 +5526,19 @@ TEST(Switch) { " case 1: a = 2; // fall-through\n" " case 2: a = 3; break;\n" "}\n", - 2 * kPointerSize, + 3 * kPointerSize, 1, 34, { B(LdaSmi8), U8(1), // B(Star), R(1), // - B(Ldar), R(1), // B(Star), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(1), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfTrue), U8(10), // B(LdaSmi8), U8(2), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfTrue), U8(8), // B(Jump), U8(12), // B(LdaSmi8), U8(2), // @@ -4854,19 +5555,19 @@ TEST(Switch) { " case 3: break;\n" " default: a = 1; break;\n" "}\n", - 2 * kPointerSize, + 3 * kPointerSize, 1, 34, { B(LdaSmi8), U8(1), // B(Star), R(1), // - B(Ldar), R(1), // B(Star), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(2), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfTrue), U8(10), // B(LdaSmi8), U8(3), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfTrue), U8(6), // B(Jump), U8(6), // B(Jump), U8(10), // @@ -4883,20 +5584,20 @@ TEST(Switch) { " case 3: a = 2; break;\n" " default: a = 3; break;\n" "}\n", - 2 * kPointerSize, + 3 * kPointerSize, 1, 43, { B(LdaSmi8), U8(1), // B(Star), R(1), // - B(Ldar), R(1), // B(TypeOf), // B(Star), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(2), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfTrue), U8(10), // B(LdaSmi8), U8(3), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfTrue), U8(10), // B(Jump), U8(14), // B(LdaSmi8), U8(1), // @@ -4916,17 +5617,17 @@ TEST(Switch) { " case typeof(a): a = 1; break;\n" " default: a = 2; break;\n" "}\n", - 2 * kPointerSize, + 3 * kPointerSize, 1, 31, { B(LdaSmi8), U8(1), // B(Star), R(1), // - B(Ldar), R(1), // B(Star), R(0), // + B(Star), R(2), // B(Ldar), R(1), // B(TypeOf), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfTrue), U8(4), // B(Jump), U8(8), // B(LdaSmi8), U8(1), // @@ -4944,24 +5645,24 @@ TEST(Switch) { "break;\n" " case 2: a = 3; break;" "}\n", - 2 * kPointerSize, + 3 * kPointerSize, 1, 288, { B(LdaSmi8), U8(1), // B(Star), R(1), // - B(Ldar), R(1), // B(Star), R(0), // + B(Star), R(2), // B(LdaSmi8), U8(1), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfTrue), U8(10), // B(LdaSmi8), U8(2), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(2), // B(JumpIfTrueConstant), U8(0), // B(JumpConstant), U8(1), // REPEAT_64(COMMA, // - B(LdaSmi8), U8(2), // - B(Star), R(1)), // + B(LdaSmi8), U8(2), // + B(Star), R(1)), // B(Jump), U8(8), // B(LdaSmi8), U8(3), // B(Star), R(1), // @@ -4980,26 +5681,29 @@ TEST(Switch) { " } // fall-through\n" " case 2: a = 3;\n" "}\n", - 3 * kPointerSize, + 5 * kPointerSize, 1, - 54, + 60, { B(LdaSmi8), U8(1), // B(Star), R(2), // - B(Ldar), R(2), // B(Star), R(0), // + B(Star), R(3), // B(LdaSmi8), U8(1), // - B(TestEqualStrict), R(0), // + B(TestEqualStrict), R(3), // B(JumpIfTrue), U8(10), // B(LdaSmi8), U8(2), // - B(TestEqualStrict), R(0), // - B(JumpIfTrue), U8(30), // - B(Jump), U8(32), // + B(TestEqualStrict), R(3), // + B(JumpIfTrue), U8(36), // + B(Jump), U8(38), // + B(Ldar), R(2), // + B(Star), R(4), // B(LdaSmi8), U8(1), // - B(Add), R(2), // + B(Add), R(4), // B(Star), R(1), // + B(Star), R(4), // B(LdaSmi8), U8(2), // - B(TestEqualStrict), R(1), // + B(TestEqualStrict), R(4), // B(JumpIfTrue), U8(4), // B(Jump), U8(8), // B(LdaSmi8), U8(1), // @@ -5027,20 +5731,21 @@ TEST(BasicBlockToBoolean) { InitializedHandleScope handle_scope; BytecodeGeneratorHelper helper; - // Check that we don't omit ToBoolean calls if they are at the start of basic + // Check that we generate JumpIfToBoolean if they are at the start of basic // blocks. ExpectedSnippet<int> snippets[] = { {"var a = 1; if (a || a < 0) { return 1; }", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 18, + 20, { B(LdaSmi8), U8(1), // B(Star), R(0), // + B(JumpIfToBooleanTrue), U8(9), // B(Ldar), R(0), // - B(JumpIfToBooleanTrue), U8(5), // + B(Star), R(1), // B(LdaZero), // - B(TestLessThan), R(0), // + B(TestLessThan), R(1), // B(JumpIfToBooleanFalse), U8(5), // B(LdaSmi8), U8(1), // B(Return), // @@ -5048,16 +5753,17 @@ TEST(BasicBlockToBoolean) { B(Return), // }}, {"var a = 1; if (a && a < 0) { return 1; }", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 18, + 20, { B(LdaSmi8), U8(1), // B(Star), R(0), // + B(JumpIfToBooleanFalse), U8(9), // B(Ldar), R(0), // - B(JumpIfToBooleanFalse), U8(5), // + B(Star), R(1), // B(LdaZero), // - B(TestLessThan), R(0), // + B(TestLessThan), R(1), // B(JumpIfToBooleanFalse), U8(5), // B(LdaSmi8), U8(1), // B(Return), // @@ -5065,16 +5771,17 @@ TEST(BasicBlockToBoolean) { B(Return), // }}, {"var a = 1; a = (a || a < 0) ? 2 : 3;", - 1 * kPointerSize, + 2 * kPointerSize, 1, - 23, + 25, { B(LdaSmi8), U8(1), // B(Star), R(0), // + B(JumpIfToBooleanTrue), U8(9), // B(Ldar), R(0), // - B(JumpIfToBooleanTrue), U8(5), // + B(Star), R(1), // B(LdaZero), // - B(TestLessThan), R(0), // + B(TestLessThan), R(1), // B(JumpIfToBooleanFalse), U8(6), // B(LdaSmi8), U8(2), // B(Jump), U8(4), // @@ -5127,11 +5834,10 @@ TEST(DeadCodeRemoval) { {"var a = 1; if (a) { return 1; }; return 2;", 1 * kPointerSize, 1, - 14, + 12, { B(LdaSmi8), U8(1), // B(Star), R(0), // - B(Ldar), R(0), // B(JumpIfToBooleanFalse), U8(5), // B(LdaSmi8), U8(1), // B(Return), // @@ -5170,13 +5876,12 @@ TEST(ThisFunction) { {"var f;\n f = function f() { return f; }", 1 * kPointerSize, 1, - 10, + 8, { B(LdaTheHole), // B(Star), R(0), // B(Ldar), R(closure), // B(Star), R(0), // - B(Ldar), R(0), // B(Return), // }}, }; @@ -5193,17 +5898,27 @@ TEST(NewTarget) { InitializedHandleScope handle_scope; BytecodeGeneratorHelper helper; + int new_target = Register::new_target().index(); + ExpectedSnippet<int> snippets[] = { {"return new.target;", 1 * kPointerSize, 1, - 10, + 5, { - B(CallRuntime), U16(Runtime::kGetOriginalConstructor), R(0), // - U8(0), // - B(Star), R(0), // - B(Ldar), R(0), // - B(Return), // + B(Ldar), R(new_target), // + B(Star), R(0), // + B(Return), // + }}, + {"new.target;", + 1 * kPointerSize, + 1, + 6, + { + B(Ldar), R(new_target), // + B(Star), R(0), // + B(LdaUndefined), // + B(Return), // }}, }; @@ -5214,6 +5929,799 @@ TEST(NewTarget) { } } + +TEST(RemoveRedundantLdar) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + + ExpectedSnippet<int> snippets[] = { + {"var ld_a = 1;\n" // This test is to check Ldar does not + "while(true) {\n" // get removed if the preceding Star is + " ld_a = ld_a + ld_a;\n" // in a different basicblock. + " if (ld_a > 10) break;\n" + "}\n" + "return ld_a;", + 2 * kPointerSize, + 1, + 29, + {B(LdaSmi8), U8(1), // + B(Star), R(0), // + B(Ldar), R(0), // This load should not be removed as it + B(Star), R(1), // is the target of the branch. + B(Ldar), R(0), // + B(Add), R(1), // + B(Star), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(10), // + B(TestGreaterThan), R(1), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(4), // + B(Jump), U8(-20), // + B(Ldar), R(0), // + B(Return)}}, + {"var ld_a = 1;\n" + "do {\n" + " ld_a = ld_a + ld_a;\n" + " if (ld_a > 10) continue;\n" + "} while(false);\n" + "return ld_a;", + 2 * kPointerSize, + 1, + 27, + {B(LdaSmi8), U8(1), // + B(Star), R(0), // + B(Ldar), R(0), // + B(Star), R(1), // + B(Ldar), R(0), // + B(Add), R(1), // + B(Star), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(10), // + B(TestGreaterThan), R(1), // + B(JumpIfFalse), U8(4), // + B(Jump), U8(2), // + B(Ldar), R(0), // + B(Return)}}, + {"var ld_a = 1;\n" + " ld_a = ld_a + ld_a;\n" + " return ld_a;", + 2 * kPointerSize, + 1, + 13, + { + B(LdaSmi8), U8(1), // + B(Star), R(0), // + B(Star), R(1), // + B(Ldar), R(0), // + B(Add), R(1), // + B(Star), R(0), // + B(Return) // + }}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + Handle<BytecodeArray> bytecode_array = + helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + + +TEST(AssignmentsInBinaryExpression) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + + ExpectedSnippet<const char*> snippets[] = { + {"var x = 0, y = 1;\n" + "return (x = 2, y = 3, x = 4, y = 5)", + 2 * kPointerSize, + 1, + 24, + { + B(LdaZero), B(Star), R(0), // + B(LdaSmi8), U8(1), // + B(Star), R(1), // + B(LdaSmi8), U8(2), // + B(Star), R(0), // + B(LdaSmi8), U8(3), // + B(Star), R(1), // + B(LdaSmi8), U8(4), // + B(Star), R(0), // + B(LdaSmi8), U8(5), // + B(Star), R(1), // + B(Return), // + }, + 0}, + {"var x = 55;\n" + "var y = (x = 100);\n" + "return y", + 2 * kPointerSize, + 1, + 11, + { + B(LdaSmi8), U8(55), // + B(Star), R(0), // + B(LdaSmi8), U8(100), // + B(Star), R(0), // + B(Star), R(1), // + B(Return), // + }, + 0}, + {"var x = 55;\n" + "x = x + (x = 100) + (x = 101);\n" + "return x;", + 3 * kPointerSize, + 1, + 23, + { + B(LdaSmi8), U8(55), // + B(Star), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(100), // + B(Star), R(0), // + B(Add), R(1), // + B(Star), R(2), // + B(LdaSmi8), U8(101), // + B(Star), R(0), // + B(Add), R(2), // + B(Star), R(0), // + B(Return), // + }, + 0}, + {"var x = 55;\n" + "x = (x = 56) - x + (x = 57);\n" + "x++;\n" + "return x;", + 3 * kPointerSize, + 1, + 31, + { + B(LdaSmi8), U8(55), // + B(Star), R(0), // + B(LdaSmi8), U8(56), // + B(Star), R(0), // + B(Star), R(1), // + B(Ldar), R(0), // + B(Sub), R(1), // + B(Star), R(2), // + B(LdaSmi8), U8(57), // + B(Star), R(0), // + B(Add), R(2), // + B(Star), R(0), // + B(ToNumber), // + B(Star), R(1), // + B(Inc), // + B(Star), R(0), // + B(Return), // + }, + 0}, + {"var x = 55;\n" + "var y = x + (x = 1) + (x = 2) + (x = 3);\n" + "return y;", + 4 * kPointerSize, + 1, + 31, + { + B(LdaSmi8), U8(55), // + B(Star), R(0), // + B(Star), R(2), // + B(LdaSmi8), U8(1), // + B(Star), R(0), // + B(Add), R(2), // + B(Star), R(3), // + B(LdaSmi8), U8(2), // + B(Star), R(0), // + B(Add), R(3), // + B(Star), R(2), // + B(LdaSmi8), U8(3), // + B(Star), R(0), // + B(Add), R(2), // + B(Star), R(1), // + B(Return), // + }, + 0}, + {"var x = 55;\n" + "var x = x + (x = 1) + (x = 2) + (x = 3);\n" + "return x;", + 3 * kPointerSize, + 1, + 31, + { + B(LdaSmi8), U8(55), // + B(Star), R(0), // + B(Star), R(1), // + B(LdaSmi8), U8(1), // + B(Star), R(0), // + B(Add), R(1), // + B(Star), R(2), // + B(LdaSmi8), U8(2), // + B(Star), R(0), // + B(Add), R(2), // + B(Star), R(1), // + B(LdaSmi8), U8(3), // + B(Star), R(0), // + B(Add), R(1), // + B(Star), R(0), // + B(Return), // + }, + 0}, + {"var x = 10, y = 20;\n" + "return x + (x = 1) + (x + 1) * (y = 2) + (y = 3) + (x = 4) + (y = 5) + " + "y;\n", + 5 * kPointerSize, + 1, + 69, + { + B(LdaSmi8), U8(10), // + B(Star), R(0), // + B(LdaSmi8), U8(20), // + B(Star), R(1), // + B(Ldar), R(0), // + B(Star), R(2), // + B(LdaSmi8), U8(1), // + B(Star), R(0), // + B(Add), R(2), // + B(Star), R(3), // + B(Ldar), R(0), // + B(Star), R(2), // + B(LdaSmi8), U8(1), // + B(Add), R(2), // + B(Star), R(4), // + B(LdaSmi8), U8(2), // + B(Star), R(1), // + B(Mul), R(4), // + B(Add), R(3), // + B(Star), R(2), // + B(LdaSmi8), U8(3), // + B(Star), R(1), // + B(Add), R(2), // + B(Star), R(3), // + B(LdaSmi8), U8(4), // + B(Star), R(0), // + B(Add), R(3), // + B(Star), R(2), // + B(LdaSmi8), U8(5), // + B(Star), R(1), // + B(Add), R(2), // + B(Star), R(3), // + B(Ldar), R(1), // + B(Add), R(3), // + B(Return), // + }, + 0}, + {"var x = 17;\n" + "return 1 + x + (x++) + (++x);\n", + 4 * kPointerSize, + 1, + 37, + { + B(LdaSmi8), U8(17), // + B(Star), R(0), // + B(LdaSmi8), U8(1), // + B(Star), R(1), // + B(Ldar), R(0), // + B(Add), R(1), // + B(Star), R(2), // + B(Ldar), R(0), // + B(ToNumber), // + B(Star), R(1), // + B(Inc), // + B(Star), R(0), // + B(Ldar), R(1), // + B(Add), R(2), // + B(Star), R(3), // + B(Ldar), R(0), // + B(ToNumber), // + B(Inc), // + B(Star), R(0), // + B(Add), R(3), // + B(Return), // + }, + 0}}; + + for (size_t i = 0; i < arraysize(snippets); i++) { + Handle<BytecodeArray> bytecode_array = + helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + + +TEST(Eval) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + Zone zone; + + int closure = Register::function_closure().index(); + int context = Register::function_context().index(); + int new_target = Register::new_target().index(); + + int first_context_slot = Context::MIN_CONTEXT_SLOTS; + + ExpectedSnippet<const char*> snippets[] = { + {"return eval('1;');", + 9 * kPointerSize, + 1, + 67, + { + B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // + U8(1), // + B(PushContext), R(0), // + B(Ldar), THIS(1), // + B(StaContextSlot), R(0), U8(first_context_slot), // + B(CreateMappedArguments), // + B(StaContextSlot), R(0), U8(first_context_slot + 1), // + B(Ldar), R(new_target), // + B(StaContextSlot), R(0), U8(first_context_slot + 2), // + B(Mov), R(context), R(3), // + B(LdaConstant), U8(0), // + B(Star), R(4), // + B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot), // + R(3), U8(2), R(1), // + B(LdaConstant), U8(1), // + B(Star), R(3), // + B(Mov), R(1), R(4), // + B(Mov), R(3), R(5), // + B(Mov), R(closure), R(6), // + B(LdaZero), // + B(Star), R(7), // + B(LdaSmi8), U8(10), // + B(Star), R(8), // + B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), // + U8(5), // + B(Star), R(1), // + B(Call), R(1), R(2), U8(1), U8(0), // + B(Return), // + }, + 2, + {"eval", "1;"}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + Handle<BytecodeArray> bytecode_array = + helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + + +TEST(LookupSlot) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + + int closure = Register::function_closure().index(); + int first_context_slot = Context::MIN_CONTEXT_SLOTS; + int context = Register::function_context().index(); + int new_target = Register::new_target().index(); + + ExpectedSnippet<const char*> snippets[] = { + {"eval('var x = 10;'); return x;", + 9 * kPointerSize, + 1, + 69, + { + B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // + U8(1), // + B(PushContext), R(0), // + B(Ldar), THIS(1), // + B(StaContextSlot), R(0), U8(first_context_slot), // + B(CreateMappedArguments), // + B(StaContextSlot), R(0), U8(first_context_slot + 1), // + B(Ldar), R(new_target), // + B(StaContextSlot), R(0), U8(first_context_slot + 2), // + B(Mov), R(context), R(3), // + B(LdaConstant), U8(0), // + B(Star), R(4), // + B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot), // + R(3), U8(2), R(1), // + B(LdaConstant), U8(1), // + B(Star), R(3), // + B(Mov), R(1), R(4), // + B(Mov), R(3), R(5), // + B(Mov), R(closure), R(6), // + B(LdaZero), // + B(Star), R(7), // + B(LdaSmi8), U8(10), // + B(Star), R(8), // + B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), // + U8(5), // + B(Star), R(1), // + B(Call), R(1), R(2), U8(1), U8(0), // + B(LdaLookupSlot), U8(2), // + B(Return), // + }, + 3, + {"eval", "var x = 10;", "x"}}, + {"eval('var x = 10;'); return typeof x;", + 9 * kPointerSize, + 1, + 70, + { + B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // + U8(1), // + B(PushContext), R(0), // + B(Ldar), THIS(1), // + B(StaContextSlot), R(0), U8(first_context_slot), // + B(CreateMappedArguments), // + B(StaContextSlot), R(0), U8(first_context_slot + 1), // + B(Ldar), R(new_target), // + B(StaContextSlot), R(0), U8(first_context_slot + 2), // + B(Mov), R(context), R(3), // + B(LdaConstant), U8(0), // + B(Star), R(4), // + B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot), // + R(3), U8(2), R(1), // + B(LdaConstant), U8(1), // + B(Star), R(3), // + B(Mov), R(1), R(4), // + B(Mov), R(3), R(5), // + B(Mov), R(closure), R(6), // + B(LdaZero), // + B(Star), R(7), // + B(LdaSmi8), U8(10), // + B(Star), R(8), // + B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), // + U8(5), // + B(Star), R(1), // + B(Call), R(1), R(2), U8(1), U8(0), // + B(LdaLookupSlotInsideTypeof), U8(2), // + B(TypeOf), // + B(Return), // + }, + 3, + {"eval", "var x = 10;", "x"}}, + {"x = 20; return eval('');", + 9 * kPointerSize, + 1, + 71, + { + B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // + U8(1), // + B(PushContext), R(0), // + B(Ldar), THIS(1), // + B(StaContextSlot), R(0), U8(first_context_slot), // + B(CreateMappedArguments), // + B(StaContextSlot), R(0), U8(first_context_slot + 1), // + B(Ldar), R(new_target), // + B(StaContextSlot), R(0), U8(first_context_slot + 2), // + B(LdaSmi8), U8(20), // + B(StaLookupSlotSloppy), U8(0), // + B(Mov), R(context), R(3), // + B(LdaConstant), U8(1), // + B(Star), R(4), // + B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot), // + R(3), U8(2), R(1), // + B(LdaConstant), U8(2), // + B(Star), R(3), // + B(Mov), R(1), R(4), // + B(Mov), R(3), R(5), // + B(Mov), R(closure), R(6), // + B(LdaZero), // + B(Star), R(7), // + B(LdaSmi8), U8(10), // + B(Star), R(8), // + B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), // + U8(5), // + B(Star), R(1), // + B(Call), R(1), R(2), U8(1), U8(0), // + B(Return), // + }, + 3, + {"x", "eval", ""}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + Handle<BytecodeArray> bytecode_array = + helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + + +TEST(CallLookupSlot) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + Zone zone; + + FeedbackVectorSpec feedback_spec(&zone); + FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); + FeedbackVectorSlot slot2 = feedback_spec.AddCallICSlot(); + USE(slot1); + + Handle<i::TypeFeedbackVector> vector = + i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); + + int closure = Register::function_closure().index(); + int context = Register::function_context().index(); + int new_target = Register::new_target().index(); + + ExpectedSnippet<InstanceType> snippets[] = { + {"g = function(){}; eval(''); return g();", + 9 * kPointerSize, + 1, + 90, + { + B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), // + U8(1), // + B(PushContext), R(0), // + B(Ldar), THIS(1), // + B(StaContextSlot), R(0), U8(4), // + B(CreateMappedArguments), // + B(StaContextSlot), R(0), U8(5), // + B(Ldar), R(new_target), // + B(StaContextSlot), R(0), U8(6), // + B(CreateClosure), U8(0), U8(0), // + B(StaLookupSlotSloppy), U8(1), // + B(Mov), R(context), R(3), // + B(LdaConstant), U8(2), // + B(Star), R(4), // + B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot), // + R(3), U8(2), R(1), // + B(LdaConstant), U8(3), // + B(Star), R(3), // + B(Mov), R(1), R(4), // + B(Mov), R(3), R(5), // + B(Mov), R(closure), R(6), // + B(LdaZero), // + B(Star), R(7), // + B(LdaSmi8), U8(10), // + B(Star), R(8), // + B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(4), // + U8(5), // + B(Star), R(1), // + B(Call), R(1), R(2), U8(1), U8(0), // + B(Mov), R(context), R(3), // + B(LdaConstant), U8(1), // + B(Star), R(4), // + B(CallRuntimeForPair), U16(Runtime::kLoadLookupSlot), // + R(3), U8(2), R(1), // + B(Call), R(1), R(2), U8(0), U8(vector->GetIndex(slot2)), // + B(Return), // + }, + 4, + {InstanceType::SHARED_FUNCTION_INFO_TYPE, + InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, + InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, + InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + Handle<BytecodeArray> bytecode_array = + helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + + +TEST(LookupSlotInEval) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + + const char* function_prologue = "var f;" + "var x = 1;" + "function f1() {" + " eval(\"function t() {"; + const char* function_epilogue = " }; f = t; f();\");" + "}" + "f1();"; + + ExpectedSnippet<const char*> snippets[] = { + {"return x;", + 0 * kPointerSize, + 1, + 3, + { + B(LdaLookupSlot), U8(0), // + B(Return) // + }, + 1, + {"x"}}, + {"x = 10;", + 0 * kPointerSize, + 1, + 6, + { + B(LdaSmi8), U8(10), // + B(StaLookupSlotSloppy), U8(0), // + B(LdaUndefined), // + B(Return), // + }, + 1, + {"x"}}, + {"'use strict'; x = 10;", + 0 * kPointerSize, + 1, + 6, + { + B(LdaSmi8), U8(10), // + B(StaLookupSlotStrict), U8(0), // + B(LdaUndefined), // + B(Return), // + }, + 1, + {"x"}}, + {"return typeof x;", + 0 * kPointerSize, + 1, + 4, + { + B(LdaLookupSlotInsideTypeof), U8(0), // + B(TypeOf), // + B(Return), // + }, + 1, + {"x"}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + std::string script = std::string(function_prologue) + + std::string(snippets[i].code_snippet) + + std::string(function_epilogue); + // TODO(mythria): use * as filter when function declarations are supported + // inside eval. + Handle<BytecodeArray> bytecode_array = + helper.MakeBytecode(script.c_str(), "t", "f"); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + + +TEST(LookupSlotWideInEval) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + + const char* function_prologue = + "var f;" + "var x = 1;" + "function f1() {" + " eval(\"function t() {"; + const char* function_epilogue = + " }; f = t; f();\");" + "}" + "f1();"; + + int const_count[] = {0, 0, 0, 0}; + ExpectedSnippet<InstanceType, 257> snippets[] = { + {REPEAT_256(SPACE, "var y = 2.3;") + "return x;", + 1 * kPointerSize, + 1, + 1028, + { + REPEAT_256(SPACE, // + B(LdaConstant), U8(const_count[0]++), // + B(Star), R(0), ) // + B(LdaLookupSlotWide), U16(256), // + B(Return) // + }, + 257, + {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), + InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, + {REPEAT_256(SPACE, "var y = 2.3;") + "return typeof x;", + 1 * kPointerSize, + 1, + 1029, + { + REPEAT_256(SPACE, // + B(LdaConstant), U8(const_count[1]++), // + B(Star), R(0), ) // + B(LdaLookupSlotInsideTypeofWide), U16(256), // + B(TypeOf), // + B(Return) // + }, + 257, + {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), + InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, + {REPEAT_256(SPACE, "var y = 2.3;") + "x = 10;", + 1 * kPointerSize, + 1, + 1031, + { + REPEAT_256(SPACE, // + B(LdaConstant), U8(const_count[2]++), // + B(Star), R(0), ) // + B(LdaSmi8), U8(10), // + B(StaLookupSlotSloppyWide), U16(256), // + B(LdaUndefined), // + B(Return) // + }, + 257, + {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), + InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, + {"'use strict';" + REPEAT_256(SPACE, "var y = 2.3;") + "x = 10;", + 1 * kPointerSize, + 1, + 1031, + { + REPEAT_256(SPACE, + B(LdaConstant), U8(const_count[3]++), // + B(Star), R(0), ) // + B(LdaSmi8), U8(10), // + B(StaLookupSlotStrictWide), U16(256), // + B(LdaUndefined), // + B(Return) // + }, + 257, + {REPEAT_256(COMMA, InstanceType::HEAP_NUMBER_TYPE), + InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + std::string script = std::string(function_prologue) + + std::string(snippets[i].code_snippet) + + std::string(function_epilogue); + // TODO(mythria): use * as filter when function declarations are supported + // inside eval. + Handle<BytecodeArray> bytecode_array = + helper.MakeBytecode(script.c_str(), "t", "f"); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + + +TEST(DeleteLookupSlotInEval) { + InitializedHandleScope handle_scope; + BytecodeGeneratorHelper helper; + + const char* function_prologue = "var f;" + "var x = 1;" + "z = 10;" + "function f1() {" + " var y;" + " eval(\"function t() {"; + const char* function_epilogue = " }; f = t; f();\");" + "}" + "f1();"; + + ExpectedSnippet<const char*> snippets[] = { + {"delete x;", + 0 * kPointerSize, + 1, + 5, + { + B(LdaConstant), U8(0), // + B(DeleteLookupSlot), // + B(LdaUndefined), // + B(Return) // + }, + 1, + {"x"}}, + {"return delete y;", + 0 * kPointerSize, + 1, + 2, + { + B(LdaFalse), // + B(Return) // + }, + 0}, + {"return delete z;", + 0 * kPointerSize, + 1, + 4, + { + B(LdaConstant), U8(0), // + B(DeleteLookupSlot), // + B(Return) // + }, + 1, + {"z"}}, + }; + + for (size_t i = 0; i < arraysize(snippets); i++) { + std::string script = std::string(function_prologue) + + std::string(snippets[i].code_snippet) + + std::string(function_epilogue); + Handle<BytecodeArray> bytecode_array = + helper.MakeBytecode(script.c_str(), "t", "f"); + CheckBytecodeArrayEqual(snippets[i], bytecode_array); + } +} + } // namespace interpreter } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/interpreter/test-interpreter.cc b/deps/v8/test/cctest/interpreter/test-interpreter.cc index d274fa73cb..506cf00cd0 100644 --- a/deps/v8/test/cctest/interpreter/test-interpreter.cc +++ b/deps/v8/test/cctest/interpreter/test-interpreter.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(rmcilroy): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "src/execution.h" @@ -67,9 +64,9 @@ class InterpreterTester { source_(source), bytecode_(bytecode), feedback_vector_(feedback_vector) { - i::FLAG_vector_stores = true; i::FLAG_ignition = true; i::FLAG_ignition_fake_try_catch = true; + i::FLAG_ignition_fallback_on_eval_and_catch = false; i::FLAG_always_opt = false; // Set ignition filter flag via SetFlagsFromString to avoid double-free // (or potential leak with StrDup() based on ownership confusion). @@ -344,7 +341,7 @@ TEST(InterpreterLoadLiteral) { TEST(InterpreterLoadStoreRegisters) { HandleAndZoneScope handles; Handle<Object> true_value = handles.main_isolate()->factory()->true_value(); - for (int i = 0; i <= Register::kMaxRegisterIndex; i++) { + for (int i = 0; i <= kMaxInt8; i++) { BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); builder.set_locals_count(i + 1); builder.set_context_count(0); @@ -365,6 +362,117 @@ TEST(InterpreterLoadStoreRegisters) { } +TEST(InterpreterExchangeRegisters) { + for (int locals_count = 2; locals_count < 300; locals_count += 126) { + HandleAndZoneScope handles; + for (int exchanges = 1; exchanges < 4; exchanges++) { + BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); + builder.set_locals_count(locals_count); + builder.set_context_count(0); + builder.set_parameter_count(0); + + Register r0(0); + Register r1(locals_count - 1); + builder.LoadTrue(); + builder.StoreAccumulatorInRegister(r0); + builder.ExchangeRegisters(r0, r1); + builder.LoadFalse(); + builder.StoreAccumulatorInRegister(r0); + + bool expected = false; + for (int i = 0; i < exchanges; i++) { + builder.ExchangeRegisters(r0, r1); + expected = !expected; + } + builder.LoadAccumulatorWithRegister(r0); + builder.Return(); + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); + InterpreterTester tester(handles.main_isolate(), bytecode_array); + auto callable = tester.GetCallable<>(); + Handle<Object> return_val = callable().ToHandleChecked(); + Handle<Object> expected_val = + handles.main_isolate()->factory()->ToBoolean(expected); + CHECK(return_val.is_identical_to(expected_val)); + } + } +} + + +TEST(InterpreterExchangeRegistersWithParameter) { + for (int locals_count = 2; locals_count < 300; locals_count += 126) { + HandleAndZoneScope handles; + for (int exchanges = 1; exchanges < 4; exchanges++) { + BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); + builder.set_locals_count(locals_count); + builder.set_context_count(0); + builder.set_parameter_count(3); + + Register r0 = Register::FromParameterIndex(2, 3); + Register r1(locals_count - 1); + builder.LoadTrue(); + builder.StoreAccumulatorInRegister(r0); + builder.ExchangeRegisters(r0, r1); + builder.LoadFalse(); + builder.StoreAccumulatorInRegister(r0); + + bool expected = false; + for (int i = 0; i < exchanges; i++) { + builder.ExchangeRegisters(r0, r1); + expected = !expected; + } + builder.LoadAccumulatorWithRegister(r0); + builder.Return(); + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); + InterpreterTester tester(handles.main_isolate(), bytecode_array); + auto callable = tester.GetCallable<>(); + Handle<Object> return_val = callable().ToHandleChecked(); + Handle<Object> expected_val = + handles.main_isolate()->factory()->ToBoolean(expected); + CHECK(return_val.is_identical_to(expected_val)); + } + } +} + + +TEST(InterpreterExchangeWideRegisters) { + for (int locals_count = 3; locals_count < 300; locals_count += 126) { + HandleAndZoneScope handles; + for (int exchanges = 0; exchanges < 7; exchanges++) { + BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); + builder.set_locals_count(locals_count); + builder.set_context_count(0); + builder.set_parameter_count(0); + + Register r0(0); + Register r1(locals_count - 1); + Register r2(locals_count - 2); + builder.LoadLiteral(Smi::FromInt(200)); + builder.StoreAccumulatorInRegister(r0); + builder.ExchangeRegisters(r0, r1); + builder.LoadLiteral(Smi::FromInt(100)); + builder.StoreAccumulatorInRegister(r0); + builder.ExchangeRegisters(r0, r2); + builder.LoadLiteral(Smi::FromInt(0)); + builder.StoreAccumulatorInRegister(r0); + for (int i = 0; i < exchanges; i++) { + builder.ExchangeRegisters(r1, r2); + builder.ExchangeRegisters(r0, r1); + } + builder.LoadAccumulatorWithRegister(r0); + builder.Return(); + Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); + InterpreterTester tester(handles.main_isolate(), bytecode_array); + auto callable = tester.GetCallable<>(); + Handle<Object> return_val = callable().ToHandleChecked(); + Handle<Object> expected_val = + handles.main_isolate()->factory()->NewNumberFromInt(100 * + (exchanges % 3)); + CHECK(return_val.is_identical_to(expected_val)); + } + } +} + + static const Token::Value kShiftOperators[] = { Token::Value::SHL, Token::Value::SAR, Token::Value::SHR}; @@ -778,9 +886,8 @@ TEST(InterpreterLoadNamedProperty) { builder.set_locals_count(0); builder.set_context_count(0); builder.set_parameter_count(1); - size_t name_index = builder.GetConstantPoolEntry(name); - builder.LoadNamedProperty(builder.Parameter(0), name_index, - vector->GetIndex(slot), i::SLOPPY) + builder.LoadNamedProperty(builder.Parameter(0), name, vector->GetIndex(slot), + i::SLOPPY) .Return(); Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); @@ -880,10 +987,9 @@ TEST(InterpreterStoreNamedProperty) { builder.set_locals_count(0); builder.set_context_count(0); builder.set_parameter_count(1); - size_t name_index = builder.GetConstantPoolEntry(name); builder.LoadLiteral(Smi::FromInt(999)) - .StoreNamedProperty(builder.Parameter(0), name_index, - vector->GetIndex(slot), i::STRICT) + .StoreNamedProperty(builder.Parameter(0), name, vector->GetIndex(slot), + i::STRICT) .Return(); Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); @@ -995,11 +1101,9 @@ TEST(InterpreterCall) { builder.set_locals_count(1); builder.set_context_count(0); builder.set_parameter_count(1); - size_t name_index = builder.GetConstantPoolEntry(name); - builder.LoadNamedProperty(builder.Parameter(0), name_index, slot_index, - i::SLOPPY) + builder.LoadNamedProperty(builder.Parameter(0), name, slot_index, i::SLOPPY) .StoreAccumulatorInRegister(Register(0)) - .Call(Register(0), builder.Parameter(0), 0) + .Call(Register(0), builder.Parameter(0), 0, 0) .Return(); Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); @@ -1018,11 +1122,9 @@ TEST(InterpreterCall) { builder.set_locals_count(1); builder.set_context_count(0); builder.set_parameter_count(1); - size_t name_index = builder.GetConstantPoolEntry(name); - builder.LoadNamedProperty(builder.Parameter(0), name_index, slot_index, - i::SLOPPY) + builder.LoadNamedProperty(builder.Parameter(0), name, slot_index, i::SLOPPY) .StoreAccumulatorInRegister(Register(0)) - .Call(Register(0), builder.Parameter(0), 0) + .Call(Register(0), builder.Parameter(0), 0, 0) .Return(); Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); @@ -1044,9 +1146,7 @@ TEST(InterpreterCall) { builder.set_locals_count(4); builder.set_context_count(0); builder.set_parameter_count(1); - size_t name_index = builder.GetConstantPoolEntry(name); - builder.LoadNamedProperty(builder.Parameter(0), name_index, slot_index, - i::SLOPPY) + builder.LoadNamedProperty(builder.Parameter(0), name, slot_index, i::SLOPPY) .StoreAccumulatorInRegister(Register(0)) .LoadAccumulatorWithRegister(builder.Parameter(0)) .StoreAccumulatorInRegister(Register(1)) @@ -1054,7 +1154,7 @@ TEST(InterpreterCall) { .StoreAccumulatorInRegister(Register(2)) .LoadLiteral(Smi::FromInt(11)) .StoreAccumulatorInRegister(Register(3)) - .Call(Register(0), Register(1), 2) + .Call(Register(0), Register(1), 2, 0) .Return(); Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); @@ -1075,9 +1175,7 @@ TEST(InterpreterCall) { builder.set_locals_count(12); builder.set_context_count(0); builder.set_parameter_count(1); - size_t name_index = builder.GetConstantPoolEntry(name); - builder.LoadNamedProperty(builder.Parameter(0), name_index, slot_index, - i::SLOPPY) + builder.LoadNamedProperty(builder.Parameter(0), name, slot_index, i::SLOPPY) .StoreAccumulatorInRegister(Register(0)) .LoadAccumulatorWithRegister(builder.Parameter(0)) .StoreAccumulatorInRegister(Register(1)) @@ -1101,7 +1199,7 @@ TEST(InterpreterCall) { .StoreAccumulatorInRegister(Register(10)) .LoadLiteral(factory->NewStringFromAsciiChecked("j")) .StoreAccumulatorInRegister(Register(11)) - .Call(Register(0), Register(1), 10) + .Call(Register(0), Register(1), 10, 0) .Return(); Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); @@ -1245,8 +1343,8 @@ TEST(InterpreterConditionalJumps2) { static const Token::Value kComparisonTypes[] = { - Token::Value::EQ, Token::Value::NE, Token::Value::EQ_STRICT, - Token::Value::NE_STRICT, Token::Value::LTE, Token::Value::LTE, + Token::Value::EQ, Token::Value::NE, Token::Value::EQ_STRICT, + Token::Value::NE_STRICT, Token::Value::LT, Token::Value::LTE, Token::Value::GT, Token::Value::GTE}; @@ -1566,43 +1664,6 @@ static void LoadAny(BytecodeArrayBuilder* builder, } -TEST(InterpreterToBoolean) { - HandleAndZoneScope handles; - i::Factory* factory = handles.main_isolate()->factory(); - - std::pair<Handle<Object>, bool> object_type_tuples[] = { - std::make_pair(factory->undefined_value(), false), - std::make_pair(factory->null_value(), false), - std::make_pair(factory->false_value(), false), - std::make_pair(factory->true_value(), true), - std::make_pair(factory->NewNumber(9.1), true), - std::make_pair(factory->NewNumberFromInt(0), false), - std::make_pair( - Handle<Object>::cast(factory->NewStringFromStaticChars("hello")), - true), - std::make_pair( - Handle<Object>::cast(factory->NewStringFromStaticChars("")), false), - }; - - for (size_t i = 0; i < arraysize(object_type_tuples); i++) { - BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone()); - Register r0(0); - builder.set_locals_count(0); - builder.set_context_count(0); - builder.set_parameter_count(0); - LoadAny(&builder, factory, object_type_tuples[i].first); - builder.CastAccumulatorToBoolean(); - builder.Return(); - Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); - InterpreterTester tester(handles.main_isolate(), bytecode_array); - auto callable = tester.GetCallable<>(); - Handle<Object> return_value = callable().ToHandleChecked(); - CHECK(return_value->IsBoolean()); - CHECK_EQ(return_value->BooleanValue(), object_type_tuples[i].second); - } -} - - TEST(InterpreterUnaryNotNonBoolean) { HandleAndZoneScope handles; i::Factory* factory = handles.main_isolate()->factory(); @@ -1883,7 +1944,11 @@ TEST(InterpreterContextVariables) { HandleAndZoneScope handles; i::Isolate* isolate = handles.main_isolate(); - std::pair<const char*, Handle<Object>> context_vars[] = { + std::ostringstream unique_vars; + for (int i = 0; i < 250; i++) { + unique_vars << "var a" << i << " = 0;"; + } + std::pair<std::string, Handle<Object>> context_vars[] = { std::make_pair("var a; (function() { a = 1; })(); return a;", handle(Smi::FromInt(1), isolate)), std::make_pair("var a = 10; (function() { a; })(); return a;", @@ -1898,10 +1963,14 @@ TEST(InterpreterContextVariables) { "{ let b = 20; var c = function() { [a, b] };\n" " return a + b; }", handle(Smi::FromInt(30), isolate)), + std::make_pair("'use strict';" + unique_vars.str() + + "eval(); var b = 100; return b;", + handle(Smi::FromInt(100), isolate)), }; for (size_t i = 0; i < arraysize(context_vars); i++) { - std::string source(InterpreterTester::SourceForBody(context_vars[i].first)); + std::string source( + InterpreterTester::SourceForBody(context_vars[i].first.c_str())); InterpreterTester tester(handles.main_isolate(), source.c_str()); auto callable = tester.GetCallable<>(); @@ -2162,6 +2231,19 @@ TEST(InterpreterCountOperators) { handle(Smi::FromInt(3), isolate)), std::make_pair("var a = 1; (function() { a = 2 })(); return a--;", handle(Smi::FromInt(2), isolate)), + std::make_pair("var i = 5; while(i--) {}; return i;", + handle(Smi::FromInt(-1), isolate)), + std::make_pair("var i = 1; if(i--) { return 1; } else { return 2; };", + handle(Smi::FromInt(1), isolate)), + std::make_pair("var i = -2; do {} while(i++) {}; return i;", + handle(Smi::FromInt(1), isolate)), + std::make_pair("var i = -1; for(; i++; ) {}; return i", + handle(Smi::FromInt(1), isolate)), + std::make_pair("var i = 20; switch(i++) {\n" + " case 20: return 1;\n" + " default: return 2;\n" + "}", + handle(Smi::FromInt(1), isolate)), }; for (size_t i = 0; i < arraysize(count_ops); i++) { @@ -2618,7 +2700,6 @@ TEST(InterpreterBasicLoops) { TEST(InterpreterForIn) { HandleAndZoneScope handles; - // TODO(oth): Add a test here for delete mid-loop when delete is ready. std::pair<const char*, int> for_in_samples[] = { {"function f() {\n" " var r = -1;\n" @@ -2795,7 +2876,27 @@ TEST(InterpreterForIn) { " }\n" " return flags;\n" " }", - 0}}; + 0}, + {"function f() {\n" + " var data = {x:23, y:34};\n" + " var result = 0;\n" + " var o = {};\n" + " var arr = [o];\n" + " for (arr[0].p in data)\n" // This is to test if value is loaded + " result += data[arr[0].p];\n" // back from accumulator before storing + " return result;\n" // named properties. + "}", + 57}, + {"function f() {\n" + " var data = {x:23, y:34};\n" + " var result = 0;\n" + " var o = {};\n" + " var i = 0;\n" + " for (o[i++] in data)\n" // This is to test if value is loaded + " result += data[o[i-1]];\n" // back from accumulator before + " return result;\n" // storing keyed properties. + "}", + 57}}; for (size_t i = 0; i < arraysize(for_in_samples); i++) { InterpreterTester tester(handles.main_isolate(), for_in_samples[i].first); @@ -2951,6 +3052,516 @@ TEST(InterpreterNewTarget) { CHECK(new_target_name->SameValue(*factory->NewStringFromStaticChars("f"))); } + +TEST(InterpreterAssignmentInExpressions) { + HandleAndZoneScope handles; + + std::pair<const char*, int> samples[] = { + {"function f() {\n" + " var x = 7;\n" + " var y = x + (x = 1) + (x = 2);\n" + " return y;\n" + "}", + 10}, + {"function f() {\n" + " var x = 7;\n" + " var y = x + (x = 1) + (x = 2);\n" + " return x;\n" + "}", + 2}, + {"function f() {\n" + " var x = 55;\n" + " x = x + (x = 100) + (x = 101);\n" + " return x;\n" + "}", + 256}, + {"function f() {\n" + " var x = 7;\n" + " return ++x + x + x++;\n" + "}", + 24}, + {"function f() {\n" + " var x = 7;\n" + " var y = 1 + ++x + x + x++;\n" + " return x;\n" + "}", + 9}, + {"function f() {\n" + " var x = 7;\n" + " var y = ++x + x + x++;\n" + " return x;\n" + "}", + 9}, + {"function f() {\n" + " var x = 7, y = 100, z = 1000;\n" + " return x + (x += 3) + y + (y *= 10) + (z *= 7) + z;\n" + "}", + 15117}, + {"function f() {\n" + " var inner = function (x) { return x + (x = 2) + (x = 4) + x; };\n" + " return inner(1);\n" + "}", + 11}, + {"function f() {\n" + " var x = 1, y = 2;\n" + " x = x + (x = 3) + y + (y = 4), y = y + (y = 5) + y + x;\n" + " return x + y;\n" + "}", + 10 + 24}, + {"function f() {\n" + " var x = 0;\n" + " var y = x | (x = 1) | (x = 2);\n" + " return x;\n" + "}", + 2}, + {"function f() {\n" + " var x = 0;\n" + " var y = x || (x = 1);\n" + " return x;\n" + "}", + 1}, + {"function f() {\n" + " var x = 1;\n" + " var y = x && (x = 2) && (x = 3);\n" + " return x;\n" + "}", + 3}, + {"function f() {\n" + " var x = 1;\n" + " var y = x || (x = 2);\n" + " return x;\n" + "}", + 1}, + {"function f() {\n" + " var x = 1;\n" + " x = (x << (x = 3)) | (x = 16);\n" + " return x;\n" + "}", + 24}, + {"function f() {\n" + " var r = 7;\n" + " var s = 11;\n" + " var t = 13;\n" + " var u = r + s + t + (r = 10) + (s = 20) +" + " (t = (r + s)) + r + s + t;\n" + " return r + s + t + u;\n" + "}", + 211}, + {"function f() {\n" + " var r = 7;\n" + " var s = 11;\n" + " var t = 13;\n" + " return r > (3 * s * (s = 1)) ? (t + (t += 1)) : (r + (r = 4));\n" + "}", + 11}, + {"function f() {\n" + " var r = 7;\n" + " var s = 11;\n" + " var t = 13;\n" + " return r > (3 * s * (s = 0)) ? (t + (t += 1)) : (r + (r = 4));\n" + "}", + 27}, + {"function f() {\n" + " var r = 7;\n" + " var s = 11;\n" + " var t = 13;\n" + " return (r + (r = 5)) > s ? r : t;\n" + "}", + 5}, + {"function f(a) {\n" + " return a + (arguments[0] = 10);\n" + "}", + 50}, + {"function f(a) {\n" + " return a + (arguments[0] = 10) + a;\n" + "}", + 60}, + {"function f(a) {\n" + " return a + (arguments[0] = 10) + arguments[0];\n" + "}", + 60}, + }; + + const int arg_value = 40; + for (size_t i = 0; i < arraysize(samples); i++) { + InterpreterTester tester(handles.main_isolate(), samples[i].first); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_val = + callable(handle(Smi::FromInt(arg_value), handles.main_isolate())) + .ToHandleChecked(); + CHECK_EQ(Handle<Smi>::cast(return_val)->value(), samples[i].second); + } +} + + +TEST(InterpreterToName) { + HandleAndZoneScope handles; + i::Isolate* isolate = handles.main_isolate(); + i::Factory* factory = isolate->factory(); + + std::pair<const char*, Handle<Object>> to_name_tests[] = { + {"var a = 'val'; var obj = {[a] : 10}; return obj.val;", + factory->NewNumberFromInt(10)}, + {"var a = 20; var obj = {[a] : 10}; return obj['20'];", + factory->NewNumberFromInt(10)}, + {"var a = 20; var obj = {[a] : 10}; return obj[20];", + factory->NewNumberFromInt(10)}, + {"var a = {val:23}; var obj = {[a] : 10}; return obj[a];", + factory->NewNumberFromInt(10)}, + {"var a = {val:23}; var obj = {[a] : 10};\n" + "return obj['[object Object]'];", + factory->NewNumberFromInt(10)}, + {"var a = {toString : function() { return 'x'}};\n" + "var obj = {[a] : 10};\n" + "return obj.x;", + factory->NewNumberFromInt(10)}, + {"var a = {valueOf : function() { return 'x'}};\n" + "var obj = {[a] : 10};\n" + "return obj.x;", + factory->undefined_value()}, + {"var a = {[Symbol.toPrimitive] : function() { return 'x'}};\n" + "var obj = {[a] : 10};\n" + "return obj.x;", + factory->NewNumberFromInt(10)}, + }; + + for (size_t i = 0; i < arraysize(to_name_tests); i++) { + std::string source( + InterpreterTester::SourceForBody(to_name_tests[i].first)); + InterpreterTester tester(handles.main_isolate(), source.c_str()); + auto callable = tester.GetCallable<>(); + + Handle<i::Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*to_name_tests[i].second)); + } +} + + +TEST(TemporaryRegisterAllocation) { + HandleAndZoneScope handles; + i::Isolate* isolate = handles.main_isolate(); + i::Factory* factory = isolate->factory(); + + std::pair<const char*, Handle<Object>> reg_tests[] = { + {"function add(a, b, c) {" + " return a + b + c;" + "}" + "function f() {" + " var a = 10, b = 10;" + " return add(a, b++, b);" + "}", + factory->NewNumberFromInt(31)}, + {"function add(a, b, c, d) {" + " return a + b + c + d;" + "}" + "function f() {" + " var x = 10, y = 20, z = 30;" + " return x + add(x, (y= x++), x, z);" + "}", + factory->NewNumberFromInt(71)}, + }; + + for (size_t i = 0; i < arraysize(reg_tests); i++) { + InterpreterTester tester(handles.main_isolate(), reg_tests[i].first); + auto callable = tester.GetCallable<>(); + + Handle<i::Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*reg_tests[i].second)); + } +} + + +TEST(InterpreterLookupSlot) { + HandleAndZoneScope handles; + i::Isolate* isolate = handles.main_isolate(); + i::Factory* factory = isolate->factory(); + + // TODO(mythria): Add more tests when we have support for eval/with. + const char* function_prologue = "var f;" + "var x = 1;" + "function f1() {" + " eval(\"function t() {"; + const char* function_epilogue = " }; f = t;\");" + "}" + "f1();"; + + + std::pair<const char*, Handle<Object>> lookup_slot[] = { + {"return x;", handle(Smi::FromInt(1), isolate)}, + {"return typeof x;", factory->NewStringFromStaticChars("number")}, + {"return typeof dummy;", factory->NewStringFromStaticChars("undefined")}, + {"x = 10; return x;", handle(Smi::FromInt(10), isolate)}, + {"'use strict'; x = 20; return x;", handle(Smi::FromInt(20), isolate)}, + }; + + for (size_t i = 0; i < arraysize(lookup_slot); i++) { + std::string script = std::string(function_prologue) + + std::string(lookup_slot[i].first) + + std::string(function_epilogue); + + InterpreterTester tester(handles.main_isolate(), script.c_str(), "t"); + auto callable = tester.GetCallable<>(); + + Handle<i::Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*lookup_slot[i].second)); + } +} + + +TEST(InterpreterCallLookupSlot) { + HandleAndZoneScope handles; + i::Isolate* isolate = handles.main_isolate(); + + std::pair<const char*, Handle<Object>> call_lookup[] = { + {"g = function(){ return 2 }; eval(''); return g();", + handle(Smi::FromInt(2), isolate)}, + {"g = function(){ return 2 }; eval('g = function() {return 3}');\n" + "return g();", + handle(Smi::FromInt(3), isolate)}, + {"g = { x: function(){ return this.y }, y: 20 };\n" + "eval('g = { x: g.x, y: 30 }');\n" + "return g.x();", + handle(Smi::FromInt(30), isolate)}, + }; + + for (size_t i = 0; i < arraysize(call_lookup); i++) { + std::string source(InterpreterTester::SourceForBody(call_lookup[i].first)); + InterpreterTester tester(handles.main_isolate(), source.c_str()); + auto callable = tester.GetCallable<>(); + + Handle<i::Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*call_lookup[i].second)); + } +} + + +TEST(InterpreterLookupSlotWide) { + HandleAndZoneScope handles; + i::Isolate* isolate = handles.main_isolate(); + i::Factory* factory = isolate->factory(); + + const char* function_prologue = + "var f;" + "var x = 1;" + "function f1() {" + " eval(\"function t() {"; + const char* function_epilogue = + " }; f = t;\");" + "}" + "f1();"; + std::ostringstream str; + str << "var y = 2.3;"; + for (int i = 1; i < 256; i++) { + str << "y = " << 2.3 + i << ";"; + } + std::string init_function_body = str.str(); + + std::pair<std::string, Handle<Object>> lookup_slot[] = { + {init_function_body + "return x;", handle(Smi::FromInt(1), isolate)}, + {init_function_body + "return typeof x;", + factory->NewStringFromStaticChars("number")}, + {init_function_body + "return x = 10;", + handle(Smi::FromInt(10), isolate)}, + {"'use strict';" + init_function_body + "x = 20; return x;", + handle(Smi::FromInt(20), isolate)}, + }; + + for (size_t i = 0; i < arraysize(lookup_slot); i++) { + std::string script = std::string(function_prologue) + lookup_slot[i].first + + std::string(function_epilogue); + + InterpreterTester tester(handles.main_isolate(), script.c_str(), "t"); + auto callable = tester.GetCallable<>(); + + Handle<i::Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*lookup_slot[i].second)); + } +} + + +TEST(InterpreterDeleteLookupSlot) { + HandleAndZoneScope handles; + i::Isolate* isolate = handles.main_isolate(); + i::Factory* factory = isolate->factory(); + + // TODO(mythria): Add more tests when we have support for eval/with. + const char* function_prologue = "var f;" + "var x = 1;" + "y = 10;" + "var obj = {val:10};" + "var z = 30;" + "function f1() {" + " var z = 20;" + " eval(\"function t() {"; + const char* function_epilogue = " }; f = t;\");" + "}" + "f1();"; + + + std::pair<const char*, Handle<Object>> delete_lookup_slot[] = { + {"return delete x;", factory->false_value()}, + {"return delete y;", factory->true_value()}, + {"return delete z;", factory->false_value()}, + {"return delete obj.val;", factory->true_value()}, + {"'use strict'; return delete obj.val;", factory->true_value()}, + }; + + for (size_t i = 0; i < arraysize(delete_lookup_slot); i++) { + std::string script = std::string(function_prologue) + + std::string(delete_lookup_slot[i].first) + + std::string(function_epilogue); + + InterpreterTester tester(handles.main_isolate(), script.c_str(), "t"); + auto callable = tester.GetCallable<>(); + + Handle<i::Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*delete_lookup_slot[i].second)); + } +} + + +TEST(JumpWithConstantsAndWideConstants) { + HandleAndZoneScope handles; + auto isolate = handles.main_isolate(); + auto factory = isolate->factory(); + const int kStep = 13; + for (int constants = 3; constants < 256 + 3 * kStep; constants += kStep) { + std::ostringstream filler_os; + // Generate a string that consumes constant pool entries and + // spread out branch distances in script below. + for (int i = 0; i < constants; i++) { + filler_os << "var x_ = 'x_" << i << "';\n"; + } + std::string filler(filler_os.str()); + std::ostringstream script_os; + script_os << "function " << InterpreterTester::function_name() << "(a) {\n"; + script_os << " " << filler; + script_os << " for (var i = a; i < 2; i++) {\n"; + script_os << " " << filler; + script_os << " if (i == 0) { " << filler << "i = 10; continue; }\n"; + script_os << " else if (i == a) { " << filler << "i = 12; break; }\n"; + script_os << " else { " << filler << " }\n"; + script_os << " }\n"; + script_os << " return i;\n"; + script_os << "}\n"; + std::string script(script_os.str()); + for (int a = 0; a < 3; a++) { + InterpreterTester tester(handles.main_isolate(), script.c_str()); + auto callable = tester.GetCallable<Handle<Object>>(); + Handle<Object> return_val = + callable(factory->NewNumberFromInt(a)).ToHandleChecked(); + static const int results[] = {11, 12, 2}; + CHECK_EQ(Handle<Smi>::cast(return_val)->value(), results[a]); + } + } +} + + +TEST(InterpreterEval) { + HandleAndZoneScope handles; + i::Isolate* isolate = handles.main_isolate(); + i::Factory* factory = isolate->factory(); + + std::pair<const char*, Handle<Object>> eval[] = { + {"return eval('1;');", handle(Smi::FromInt(1), isolate)}, + {"return eval('100 * 20;');", handle(Smi::FromInt(2000), isolate)}, + {"var x = 10; return eval('x + 20;');", + handle(Smi::FromInt(30), isolate)}, + {"var x = 10; eval('x = 33;'); return x;", + handle(Smi::FromInt(33), isolate)}, + {"'use strict'; var x = 20; var z = 0;\n" + "eval('var x = 33; z = x;'); return x + z;", + handle(Smi::FromInt(53), isolate)}, + {"eval('var x = 33;'); eval('var y = x + 20'); return x + y;", + handle(Smi::FromInt(86), isolate)}, + {"var x = 1; eval('for(i = 0; i < 10; i++) x = x + 1;'); return x", + handle(Smi::FromInt(11), isolate)}, + {"var x = 10; eval('var x = 20;'); return x;", + handle(Smi::FromInt(20), isolate)}, + {"var x = 1; eval('\"use strict\"; var x = 2;'); return x;", + handle(Smi::FromInt(1), isolate)}, + {"'use strict'; var x = 1; eval('var x = 2;'); return x;", + handle(Smi::FromInt(1), isolate)}, + {"var x = 10; eval('x + 20;'); return typeof x;", + factory->NewStringFromStaticChars("number")}, + {"eval('var y = 10;'); return typeof unallocated;", + factory->NewStringFromStaticChars("undefined")}, + {"'use strict'; eval('var y = 10;'); return typeof unallocated;", + factory->NewStringFromStaticChars("undefined")}, + {"eval('var x = 10;'); return typeof x;", + factory->NewStringFromStaticChars("number")}, + {"var x = {}; eval('var x = 10;'); return typeof x;", + factory->NewStringFromStaticChars("number")}, + {"'use strict'; var x = {}; eval('var x = 10;'); return typeof x;", + factory->NewStringFromStaticChars("object")}, + }; + + for (size_t i = 0; i < arraysize(eval); i++) { + std::string source(InterpreterTester::SourceForBody(eval[i].first)); + InterpreterTester tester(handles.main_isolate(), source.c_str()); + auto callable = tester.GetCallable<>(); + + Handle<i::Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*eval[i].second)); + } +} + + +TEST(InterpreterEvalParams) { + HandleAndZoneScope handles; + i::Isolate* isolate = handles.main_isolate(); + + std::pair<const char*, Handle<Object>> eval_params[] = { + {"var x = 10; return eval('x + p1;');", + handle(Smi::FromInt(30), isolate)}, + {"var x = 10; eval('p1 = x;'); return p1;", + handle(Smi::FromInt(10), isolate)}, + {"var a = 10;" + "function inner() { return eval('a + p1;');}" + "return inner();", + handle(Smi::FromInt(30), isolate)}, + }; + + for (size_t i = 0; i < arraysize(eval_params); i++) { + std::string source = "function " + InterpreterTester::function_name() + + "(p1) {" + eval_params[i].first + "}"; + InterpreterTester tester(handles.main_isolate(), source.c_str()); + auto callable = tester.GetCallable<Handle<Object>>(); + + Handle<i::Object> return_value = + callable(handle(Smi::FromInt(20), isolate)).ToHandleChecked(); + CHECK(return_value->SameValue(*eval_params[i].second)); + } +} + + +TEST(InterpreterEvalGlobal) { + HandleAndZoneScope handles; + i::Isolate* isolate = handles.main_isolate(); + i::Factory* factory = isolate->factory(); + + std::pair<const char*, Handle<Object>> eval_global[] = { + {"function add_global() { eval('function test() { z = 33; }; test()'); };" + "function f() { add_global(); return z; }; f();", + handle(Smi::FromInt(33), isolate)}, + {"function add_global() {\n" + " eval('\"use strict\"; function test() { y = 33; };" + " try { test() } catch(e) {}');\n" + "}\n" + "function f() { add_global(); return typeof y; } f();", + factory->NewStringFromStaticChars("undefined")}, + }; + + for (size_t i = 0; i < arraysize(eval_global); i++) { + InterpreterTester tester(handles.main_isolate(), eval_global[i].first, + "test"); + auto callable = tester.GetCallable<>(); + + Handle<i::Object> return_value = callable().ToHandleChecked(); + CHECK(return_value->SameValue(*eval_global[i].second)); + } +} + } // namespace interpreter } // namespace internal } // namespace v8 diff --git a/deps/v8/test/cctest/print-extension.cc b/deps/v8/test/cctest/print-extension.cc index 33f33cafc2..b5f6fb549e 100644 --- a/deps/v8/test/cctest/print-extension.cc +++ b/deps/v8/test/cctest/print-extension.cc @@ -30,9 +30,8 @@ namespace v8 { namespace internal { -v8::Handle<v8::FunctionTemplate> PrintExtension::GetNativeFunctionTemplate( - v8::Isolate* isolate, - v8::Handle<v8::String> str) { +v8::Local<v8::FunctionTemplate> PrintExtension::GetNativeFunctionTemplate( + v8::Isolate* isolate, v8::Local<v8::String> str) { return v8::FunctionTemplate::New(isolate, PrintExtension::Print); } diff --git a/deps/v8/test/cctest/print-extension.h b/deps/v8/test/cctest/print-extension.h index c2961d0dd1..74d74ef81b 100644 --- a/deps/v8/test/cctest/print-extension.h +++ b/deps/v8/test/cctest/print-extension.h @@ -36,9 +36,8 @@ namespace internal { class PrintExtension : public v8::Extension { public: PrintExtension() : v8::Extension("v8/print", "native function print();") { } - virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( - v8::Isolate* isolate, - v8::Handle<v8::String> name); + virtual v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate( + v8::Isolate* isolate, v8::Local<v8::String> name); static void Print(const v8::FunctionCallbackInfo<v8::Value>& args); }; diff --git a/deps/v8/test/cctest/profiler-extension.cc b/deps/v8/test/cctest/profiler-extension.cc index c8cb0fb7ca..a917932978 100644 --- a/deps/v8/test/cctest/profiler-extension.cc +++ b/deps/v8/test/cctest/profiler-extension.cc @@ -39,17 +39,25 @@ const char* ProfilerExtension::kSource = "native function startProfiling();" "native function stopProfiling();"; -v8::Handle<v8::FunctionTemplate> ProfilerExtension::GetNativeFunctionTemplate( - v8::Isolate* isolate, v8::Handle<v8::String> name) { - if (name->Equals(v8::String::NewFromUtf8(isolate, "startProfiling"))) { +v8::Local<v8::FunctionTemplate> ProfilerExtension::GetNativeFunctionTemplate( + v8::Isolate* isolate, v8::Local<v8::String> name) { + v8::Local<v8::Context> context = isolate->GetCurrentContext(); + if (name->Equals(context, v8::String::NewFromUtf8(isolate, "startProfiling", + v8::NewStringType::kNormal) + .ToLocalChecked()) + .FromJust()) { return v8::FunctionTemplate::New(isolate, ProfilerExtension::StartProfiling); - } else if (name->Equals(v8::String::NewFromUtf8(isolate, "stopProfiling"))) { + } else if (name->Equals(context, + v8::String::NewFromUtf8(isolate, "stopProfiling", + v8::NewStringType::kNormal) + .ToLocalChecked()) + .FromJust()) { return v8::FunctionTemplate::New(isolate, ProfilerExtension::StopProfiling); } else { CHECK(false); - return v8::Handle<v8::FunctionTemplate>(); + return v8::Local<v8::FunctionTemplate>(); } } diff --git a/deps/v8/test/cctest/test-accessors.cc b/deps/v8/test/cctest/test-accessors.cc index 9b68820bd8..0687c33500 100644 --- a/deps/v8/test/cctest/test-accessors.cc +++ b/deps/v8/test/cctest/test-accessors.cc @@ -25,9 +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. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdlib.h> #include "src/v8.h" diff --git a/deps/v8/test/cctest/test-api-accessors.cc b/deps/v8/test/cctest/test-api-accessors.cc index f6d1ef0718..cda16cdbcb 100644 --- a/deps/v8/test/cctest/test-api-accessors.cc +++ b/deps/v8/test/cctest/test-api-accessors.cc @@ -2,23 +2,32 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "test/cctest/cctest.h" #include "include/v8.h" +#include "include/v8-experimental.h" + +namespace i = v8::internal; -#ifdef V8_JS_ACCESSORS -static void CppAccessor(const v8::FunctionCallbackInfo<v8::Value>& info) { +static void CppAccessor42(const v8::FunctionCallbackInfo<v8::Value>& info) { info.GetReturnValue().Set(42); } -static const char* JsAccessor = - "function firstChildJS(value) { return 41; }; firstChildJS"; -TEST(JavascriptAccessors) { +static void CppAccessor41(const v8::FunctionCallbackInfo<v8::Value>& info) { + info.GetReturnValue().Set(41); +} + + +v8::experimental::FastAccessorBuilder* FastAccessor(v8::Isolate* isolate) { + auto builder = v8::experimental::FastAccessorBuilder::New(isolate); + builder->ReturnValue(builder->IntegerConstant(41)); + return builder; +} + + +TEST(FastAccessors) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); LocalContext env; @@ -38,13 +47,15 @@ TEST(JavascriptAccessors) { // cpp accessor as "firstChild": parent->PrototypeTemplate()->SetAccessorProperty( v8_str("firstChild"), - v8::FunctionTemplate::New(isolate, CppAccessor, v8::Local<v8::Value>(), - signature)); + v8::FunctionTemplate::New(isolate, CppAccessor42, + v8::Local<v8::Value>(), signature)); - // JS accessor as "firstChildJS": - auto js_accessor = v8::Local<v8::Function>::Cast(CompileRun(JsAccessor)); - parent->PrototypeTemplate()->SetAccessorProperty(v8_str("firstChildJS"), - js_accessor); + // JS accessor as "firstChildRaw": + parent->PrototypeTemplate()->SetAccessorProperty( + v8_str("firstChildRaw"), + v8::FunctionTemplate::NewWithFastHandler( + isolate, CppAccessor41, FastAccessor(isolate), + v8::Local<v8::Value>(), signature)); } // Setup child object ( =~ a specific DOM Node, e.g. a <div> ). @@ -61,18 +72,18 @@ TEST(JavascriptAccessors) { // The simple case: Run it once. ExpectInt32("var n = new Node(); n.firstChild", 42); - ExpectInt32("var n = new Node(); n.firstChildJS", 41); + ExpectInt32("var n = new Node(); n.firstChildRaw", 41); // Run them in a loop. This will likely trigger the optimizing compiler: ExpectInt32( "var m = new Node(); " "var sum = 0; " - "for (var i = 0; i < 3; ++i) { " + "for (var i = 0; i < 10; ++i) { " " sum += m.firstChild; " - " sum += m.firstChildJS; " + " sum += m.firstChildRaw; " "}; " "sum;", - 3 * (42 + 41)); + 10 * (42 + 41)); // Obtain the accessor and call it via apply on the Node: ExpectInt32( @@ -84,10 +95,19 @@ TEST(JavascriptAccessors) { ExpectInt32( "var n = new Node(); " "var g = Object.getOwnPropertyDescriptor(" - " n.__proto__.__proto__, 'firstChildJS')['get']; " + " n.__proto__.__proto__, 'firstChildRaw')['get']; " "g.apply(n);", 41); - // TODO(vogelheim): Verify compatible receiver check works. + ExpectInt32( + "var n = new Node();" + "var g = Object.getOwnPropertyDescriptor(" + " n.__proto__.__proto__, 'firstChildRaw')['get'];" + "try {" + " var f = { firstChildRaw: '51' };" + " g.apply(f);" + "} catch(e) {" + " 31415;" + "}", + 31415); } -#endif // V8_JS_ACCESSORS diff --git a/deps/v8/test/cctest/test-api-fast-accessor-builder.cc b/deps/v8/test/cctest/test-api-fast-accessor-builder.cc new file mode 100644 index 0000000000..1e1c972694 --- /dev/null +++ b/deps/v8/test/cctest/test-api-fast-accessor-builder.cc @@ -0,0 +1,288 @@ +// 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 <stdlib.h> + +#include "include/v8.h" +#include "include/v8-experimental.h" + +#include "src/api.h" +#include "test/cctest/cctest.h" + +namespace { + +// These tests mean to exercise v8::FastAccessorBuilder. Since initially the +// "native" accessor will get called, we need to "warmup" any accessor first, +// to make sure we're actually testing the v8::FastAccessorBuilder result. +// To accomplish this, we will +// - call each accesssor N times before the actual test. +// - wrap that call in a function, so that all such calls will go +// through a single call site. +// - bloat that function with a very long comment to prevent its inlining. +// - register a native accessor which is different from the build one +// (so that our tests will always fail if we don't end up in the 'fast' +// accessor). +// +// FN_WARMUP(name, src) define a JS function "name" with body "src". +// It adds the INLINE_SPOILER to prevent inlining and will call name() +// repeatedly to guarantee it's "warm". +// +// Use: +// CompileRun(FN_WARMUP("fn", "return something();")); +// ExpectXXX("fn(1234)", 5678); + +#define INLINE_SPOILER \ + " /* " \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \ + "*/ " // 16 lines * 64 'X' =~ 1024 character comment. +#define FN_WARMUP(name, src) \ + "function " name "() { " src INLINE_SPOILER \ + " }; for(i = 0; i < 2; i++) { " name "() } " + +static void NativePropertyAccessor( + const v8::FunctionCallbackInfo<v8::Value>& info) { + info.GetReturnValue().Set(v8_num(123)); +} + +} // anonymous namespace + + +// Build a simple "fast accessor" and verify that it is being called. +TEST(FastAccessor) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + + v8::Local<v8::FunctionTemplate> foo = v8::FunctionTemplate::New(isolate); + + // Native accessor, bar, returns 123. + foo->PrototypeTemplate()->SetAccessorProperty( + v8_str("bar"), + v8::FunctionTemplate::New(isolate, NativePropertyAccessor)); + + // Fast accessor, barf, returns 124. + auto fab = v8::experimental::FastAccessorBuilder::New(isolate); + fab->ReturnValue(fab->IntegerConstant(124)); + foo->PrototypeTemplate()->SetAccessorProperty( + v8_str("barf"), v8::FunctionTemplate::NewWithFastHandler( + isolate, NativePropertyAccessor, fab)); + + // Install foo on the global object. + CHECK(env->Global() + ->Set(env.local(), v8_str("foo"), + foo->GetFunction(env.local()).ToLocalChecked()) + .FromJust()); + + // Wrap f.barf + IC warmup. + CompileRun(FN_WARMUP("barf", "f = new foo(); return f.barf")); + + ExpectInt32("f = new foo(); f.bar", 123); + ExpectInt32("f = new foo(); f.barf", 123); // First call in this call site. + ExpectInt32("barf()", 124); // Call via warmed-up callsite. +} + + +void AddInternalFieldAccessor(v8::Isolate* isolate, + v8::Local<v8::Template> templ, const char* name, + int field_no) { + auto builder = v8::experimental::FastAccessorBuilder::New(isolate); + builder->ReturnValue( + builder->LoadInternalField(builder->GetReceiver(), field_no)); + templ->SetAccessorProperty(v8_str(name), + v8::FunctionTemplate::NewWithFastHandler( + isolate, NativePropertyAccessor, builder)); +} + + +// "Fast" accessor that accesses an internal field. +TEST(FastAccessorWithInternalField) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + + v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); + foo->SetInternalFieldCount(3); + AddInternalFieldAccessor(isolate, foo, "field0", 0); + AddInternalFieldAccessor(isolate, foo, "field1", 1); + AddInternalFieldAccessor(isolate, foo, "field2", 2); + + // Create an instance w/ 3 internal fields, put in a string, a Smi, nothing. + v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked(); + obj->SetInternalField(0, v8_str("Hi there!")); + obj->SetInternalField(1, v8::Integer::New(isolate, 4321)); + CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); + + // Warmup. + CompileRun(FN_WARMUP("field0", "return obj.field0")); + CompileRun(FN_WARMUP("field1", "return obj.field1")); + CompileRun(FN_WARMUP("field2", "return obj.field2")); + + // Access fields. + ExpectString("field0()", "Hi there!"); + ExpectInt32("field1()", 4321); + ExpectUndefined("field2()"); +} + + +// "Fast" accessor with control flow via ...OrReturnNull methods. +TEST(FastAccessorOrReturnNull) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + + v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); + foo->SetInternalFieldCount(2); + { + // accessor "nullcheck": Return null if field 0 is non-null object; else 5. + auto builder = v8::experimental::FastAccessorBuilder::New(isolate); + auto val = builder->LoadInternalField(builder->GetReceiver(), 0); + builder->CheckNotZeroOrReturnNull(val); + builder->ReturnValue(builder->IntegerConstant(5)); + foo->SetAccessorProperty(v8_str("nullcheck"), + v8::FunctionTemplate::NewWithFastHandler( + isolate, NativePropertyAccessor, builder)); + } + { + // accessor "maskcheck": Return null if field 1 has 3rd bit set. + auto builder = v8::experimental::FastAccessorBuilder::New(isolate); + auto val = builder->LoadInternalField(builder->GetReceiver(), 1); + builder->CheckFlagSetOrReturnNull(val, 0x4); + builder->ReturnValue(builder->IntegerConstant(42)); + foo->SetAccessorProperty(v8_str("maskcheck"), + v8::FunctionTemplate::NewWithFastHandler( + isolate, NativePropertyAccessor, builder)); + } + + // Create an instance. + v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked(); + CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); + + // CheckNotZeroOrReturnNull: + CompileRun(FN_WARMUP("nullcheck", "return obj.nullcheck")); + obj->SetAlignedPointerInInternalField(0, /* anything != nullptr */ isolate); + ExpectInt32("nullcheck()", 5); + obj->SetAlignedPointerInInternalField(0, nullptr); + ExpectNull("nullcheck()"); + + // CheckFlagSetOrReturnNull: + CompileRun(FN_WARMUP("maskcheck", "return obj.maskcheck")); + obj->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(0xf0)); + ExpectInt32("maskcheck()", 42); + obj->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(0xfe)); + ExpectNull("maskcheck()"); +} + + +// "Fast" accessor with simple control flow via explicit labels. +TEST(FastAccessorControlFlowWithLabels) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + + v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); + foo->SetInternalFieldCount(1); + { + // accessor isnull: 0 for nullptr, else 1. + auto builder = v8::experimental::FastAccessorBuilder::New(isolate); + auto label = builder->MakeLabel(); + auto val = builder->LoadInternalField(builder->GetReceiver(), 0); + builder->CheckNotZeroOrJump(val, label); + builder->ReturnValue(builder->IntegerConstant(0)); + builder->SetLabel(label); + builder->ReturnValue(builder->IntegerConstant(1)); + foo->SetAccessorProperty(v8_str("isnull"), + v8::FunctionTemplate::NewWithFastHandler( + isolate, NativePropertyAccessor, builder)); + } + + // Create an instance. + v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked(); + CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); + + // CheckNotZeroOrReturnNull: + CompileRun(FN_WARMUP("isnull", "return obj.isnull")); + obj->SetAlignedPointerInInternalField(0, /* anything != nullptr */ isolate); + ExpectInt32("isnull()", 1); + obj->SetAlignedPointerInInternalField(0, nullptr); + ExpectInt32("isnull()", 0); +} + + +// "Fast" accessor, loading things. +TEST(FastAccessorLoad) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + + v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); + foo->SetInternalFieldCount(1); + + // Internal field 0 is a pointer to a C++ data structure that we wish to load + // field values from. + struct { + size_t intval; + v8::Local<v8::String> v8val; + } val = {54321, v8_str("Hello")}; + + { + // accessor intisnonzero + int intval_offset = + static_cast<int>(reinterpret_cast<intptr_t>(&val.intval) - + reinterpret_cast<intptr_t>(&val)); + auto builder = v8::experimental::FastAccessorBuilder::New(isolate); + auto label = builder->MakeLabel(); + auto val = builder->LoadValue( + builder->LoadInternalField(builder->GetReceiver(), 0), intval_offset); + builder->CheckNotZeroOrJump(val, label); + builder->ReturnValue(builder->IntegerConstant(0)); + builder->SetLabel(label); + builder->ReturnValue(builder->IntegerConstant(1)); + foo->SetAccessorProperty(v8_str("nonzero"), + v8::FunctionTemplate::NewWithFastHandler( + isolate, NativePropertyAccessor, builder)); + } + { + // accessor loadval + int v8val_offset = static_cast<int>(reinterpret_cast<intptr_t>(&val.v8val) - + reinterpret_cast<intptr_t>(&val)); + auto builder = v8::experimental::FastAccessorBuilder::New(isolate); + builder->ReturnValue(builder->LoadObject( + builder->LoadInternalField(builder->GetReceiver(), 0), v8val_offset)); + foo->SetAccessorProperty(v8_str("loadval"), + v8::FunctionTemplate::NewWithFastHandler( + isolate, NativePropertyAccessor, builder)); + } + + // Create an instance. + v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked(); + obj->SetAlignedPointerInInternalField(0, &val); + CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); + + // Access val.intval: + CompileRun(FN_WARMUP("nonzero", "return obj.nonzero")); + ExpectInt32("nonzero()", 1); + val.intval = 0; + ExpectInt32("nonzero()", 0); + val.intval = 27; + ExpectInt32("nonzero()", 1); + + // Access val.v8val: + CompileRun(FN_WARMUP("loadval", "return obj.loadval")); + ExpectString("loadval()", "Hello"); +} diff --git a/deps/v8/test/cctest/test-api-interceptors.cc b/deps/v8/test/cctest/test-api-interceptors.cc index 3327d782f7..9f5eb21954 100644 --- a/deps/v8/test/cctest/test-api-interceptors.cc +++ b/deps/v8/test/cctest/test-api-interceptors.cc @@ -13,7 +13,7 @@ #include "src/compilation-cache.h" #include "src/execution.h" #include "src/objects.h" -#include "src/parser.h" +#include "src/parsing/parser.h" #include "src/unicode-inl.h" #include "src/utils.h" #include "src/vm-state.h" @@ -24,7 +24,6 @@ using ::v8::Context; using ::v8::Extension; using ::v8::Function; using ::v8::FunctionTemplate; -using ::v8::Handle; using ::v8::HandleScope; using ::v8::Local; using ::v8::Name; @@ -69,15 +68,18 @@ void EmptyInterceptorSetter(Local<Name> name, Local<Value> value, void SimpleAccessorGetter(Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { - Handle<Object> self = Handle<Object>::Cast(info.This()); - info.GetReturnValue().Set( - self->Get(String::Concat(v8_str("accessor_"), name))); + Local<Object> self = Local<Object>::Cast(info.This()); + info.GetReturnValue().Set(self->Get(info.GetIsolate()->GetCurrentContext(), + String::Concat(v8_str("accessor_"), name)) + .ToLocalChecked()); } void SimpleAccessorSetter(Local<String> name, Local<Value> value, const v8::PropertyCallbackInfo<void>& info) { - Handle<Object> self = Handle<Object>::Cast(info.This()); - self->Set(String::Concat(v8_str("accessor_"), name), value); + Local<Object> self = Local<Object>::Cast(info.This()); + self->Set(info.GetIsolate()->GetCurrentContext(), + String::Concat(v8_str("accessor_"), name), value) + .FromJust(); } @@ -108,7 +110,7 @@ void StringInterceptorGetter( for (i = 0; name_str[i] && prefix[i]; ++i) { if (name_str[i] != prefix[i]) return; } - Handle<Object> self = Handle<Object>::Cast(info.This()); + Local<Object> self = Local<Object>::Cast(info.This()); info.GetReturnValue().Set( self->GetPrivate( info.GetIsolate()->GetCurrentContext(), @@ -130,10 +132,10 @@ void StringInterceptorSetter(Local<String> name, Local<Value> value, } if (!prefix[i]) return; - if (value->IsInt32() && value->Int32Value() < 10000) { - Handle<Object> self = Handle<Object>::Cast(info.This()); - Handle<Context> context = info.GetIsolate()->GetCurrentContext(); - Handle<v8::Private> symbol = v8::Private::ForApi(info.GetIsolate(), name); + Local<Context> context = info.GetIsolate()->GetCurrentContext(); + if (value->IsInt32() && value->Int32Value(context).FromJust() < 10000) { + Local<Object> self = Local<Object>::Cast(info.This()); + Local<v8::Private> symbol = v8::Private::ForApi(info.GetIsolate(), name); self->SetPrivate(context, symbol, value).FromJust(); info.GetReturnValue().Set(value); } @@ -166,8 +168,9 @@ void GenericInterceptorGetter(Local<Name> generic_name, str = String::Concat(v8_str("_str_"), name); } - Handle<Object> self = Handle<Object>::Cast(info.This()); - info.GetReturnValue().Set(self->Get(str)); + Local<Object> self = Local<Object>::Cast(info.This()); + info.GetReturnValue().Set( + self->Get(info.GetIsolate()->GetCurrentContext(), str).ToLocalChecked()); } void GenericInterceptorSetter(Local<Name> generic_name, Local<Value> value, @@ -185,31 +188,31 @@ void GenericInterceptorSetter(Local<Name> generic_name, Local<Value> value, str = String::Concat(v8_str("_str_"), name); } - Handle<Object> self = Handle<Object>::Cast(info.This()); - self->Set(str, value); + Local<Object> self = Local<Object>::Cast(info.This()); + self->Set(info.GetIsolate()->GetCurrentContext(), str, value).FromJust(); info.GetReturnValue().Set(value); } -void AddAccessor(Handle<FunctionTemplate> templ, Handle<String> name, +void AddAccessor(Local<FunctionTemplate> templ, Local<String> name, v8::AccessorGetterCallback getter, v8::AccessorSetterCallback setter) { templ->PrototypeTemplate()->SetAccessor(name, getter, setter); } -void AddInterceptor(Handle<FunctionTemplate> templ, +void AddInterceptor(Local<FunctionTemplate> templ, v8::NamedPropertyGetterCallback getter, v8::NamedPropertySetterCallback setter) { templ->InstanceTemplate()->SetNamedPropertyHandler(getter, setter); } -void AddAccessor(Handle<FunctionTemplate> templ, Handle<Name> name, +void AddAccessor(Local<FunctionTemplate> templ, Local<Name> name, v8::AccessorNameGetterCallback getter, v8::AccessorNameSetterCallback setter) { templ->PrototypeTemplate()->SetAccessor(name, getter, setter); } -void AddInterceptor(Handle<FunctionTemplate> templ, +void AddInterceptor(Local<FunctionTemplate> templ, v8::GenericNamedPropertyGetterCallback getter, v8::GenericNamedPropertySetterCallback setter) { templ->InstanceTemplate()->SetHandler( @@ -217,20 +220,24 @@ void AddInterceptor(Handle<FunctionTemplate> templ, } -v8::Handle<v8::Object> bottom; +v8::Local<v8::Object> bottom; void CheckThisIndexedPropertyHandler( uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) { CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyHandler)); ApiTestFuzzer::Fuzz(); - CHECK(info.This()->Equals(bottom)); + CHECK(info.This() + ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) + .FromJust()); } void CheckThisNamedPropertyHandler( Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyHandler)); ApiTestFuzzer::Fuzz(); - CHECK(info.This()->Equals(bottom)); + CHECK(info.This() + ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) + .FromJust()); } void CheckThisIndexedPropertySetter( @@ -238,7 +245,9 @@ void CheckThisIndexedPropertySetter( const v8::PropertyCallbackInfo<v8::Value>& info) { CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertySetter)); ApiTestFuzzer::Fuzz(); - CHECK(info.This()->Equals(bottom)); + CHECK(info.This() + ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) + .FromJust()); } @@ -247,14 +256,18 @@ void CheckThisNamedPropertySetter( const v8::PropertyCallbackInfo<v8::Value>& info) { CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertySetter)); ApiTestFuzzer::Fuzz(); - CHECK(info.This()->Equals(bottom)); + CHECK(info.This() + ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) + .FromJust()); } void CheckThisIndexedPropertyQuery( uint32_t index, const v8::PropertyCallbackInfo<v8::Integer>& info) { CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyQuery)); ApiTestFuzzer::Fuzz(); - CHECK(info.This()->Equals(bottom)); + CHECK(info.This() + ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) + .FromJust()); } @@ -262,7 +275,9 @@ void CheckThisNamedPropertyQuery( Local<Name> property, const v8::PropertyCallbackInfo<v8::Integer>& info) { CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyQuery)); ApiTestFuzzer::Fuzz(); - CHECK(info.This()->Equals(bottom)); + CHECK(info.This() + ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) + .FromJust()); } @@ -270,7 +285,9 @@ void CheckThisIndexedPropertyDeleter( uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info) { CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyDeleter)); ApiTestFuzzer::Fuzz(); - CHECK(info.This()->Equals(bottom)); + CHECK(info.This() + ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) + .FromJust()); } @@ -278,7 +295,9 @@ void CheckThisNamedPropertyDeleter( Local<Name> property, const v8::PropertyCallbackInfo<v8::Boolean>& info) { CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyDeleter)); ApiTestFuzzer::Fuzz(); - CHECK(info.This()->Equals(bottom)); + CHECK(info.This() + ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) + .FromJust()); } @@ -286,7 +305,9 @@ void CheckThisIndexedPropertyEnumerator( const v8::PropertyCallbackInfo<v8::Array>& info) { CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyEnumerator)); ApiTestFuzzer::Fuzz(); - CHECK(info.This()->Equals(bottom)); + CHECK(info.This() + ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) + .FromJust()); } @@ -294,7 +315,9 @@ void CheckThisNamedPropertyEnumerator( const v8::PropertyCallbackInfo<v8::Array>& info) { CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyEnumerator)); ApiTestFuzzer::Fuzz(); - CHECK(info.This()->Equals(bottom)); + CHECK(info.This() + ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) + .FromJust()); } @@ -304,7 +327,9 @@ int echo_named_call_count; void EchoNamedProperty(Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - CHECK(v8_str("data")->Equals(info.Data())); + CHECK(v8_str("data") + ->Equals(info.GetIsolate()->GetCurrentContext(), info.Data()) + .FromJust()); echo_named_call_count++; info.GetReturnValue().Set(name); } @@ -331,20 +356,23 @@ THREADED_TEST(InterceptorHasOwnProperty) { Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); instance_templ->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorHasOwnPropertyGetter)); - Local<Function> function = fun_templ->GetFunction(); - context->Global()->Set(v8_str("constructor"), function); - v8::Handle<Value> value = CompileRun( + Local<Function> function = + fun_templ->GetFunction(context.local()).ToLocalChecked(); + context->Global() + ->Set(context.local(), v8_str("constructor"), function) + .FromJust(); + v8::Local<Value> value = CompileRun( "var o = new constructor();" "o.hasOwnProperty('ostehaps');"); - CHECK_EQ(false, value->BooleanValue()); + CHECK_EQ(false, value->BooleanValue(context.local()).FromJust()); value = CompileRun( "o.ostehaps = 42;" "o.hasOwnProperty('ostehaps');"); - CHECK_EQ(true, value->BooleanValue()); + CHECK_EQ(true, value->BooleanValue(context.local()).FromJust()); value = CompileRun( "var p = new constructor();" "p.hasOwnProperty('ostehaps');"); - CHECK_EQ(false, value->BooleanValue()); + CHECK_EQ(false, value->BooleanValue(context.local()).FromJust()); } @@ -356,8 +384,11 @@ THREADED_TEST(InterceptorHasOwnPropertyCausingGC) { Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); instance_templ->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorHasOwnPropertyGetterGC)); - Local<Function> function = fun_templ->GetFunction(); - context->Global()->Set(v8_str("constructor"), function); + Local<Function> function = + fun_templ->GetFunction(context.local()).ToLocalChecked(); + context->Global() + ->Set(context.local(), v8_str("constructor"), function) + .FromJust(); // Let's first make some stuff so we can be sure to get a good GC. CompileRun( "function makestr(size) {" @@ -371,11 +402,11 @@ THREADED_TEST(InterceptorHasOwnPropertyCausingGC) { "var x = makestr(12345);" "x = makestr(31415);" "x = makestr(23456);"); - v8::Handle<Value> value = CompileRun( + v8::Local<Value> value = CompileRun( "var o = new constructor();" "o.__proto__ = new String(x);" "o.hasOwnProperty('ostehaps');"); - CHECK_EQ(false, value->BooleanValue()); + CHECK_EQ(false, value->BooleanValue(context.local()).FromJust()); } @@ -384,13 +415,16 @@ static void CheckInterceptorLoadIC( int expected) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration(getter, 0, 0, 0, 0, v8_str("data"))); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); - v8::Handle<Value> value = CompileRun(source); - CHECK_EQ(expected, value->Int32Value()); + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + v8::Local<Value> value = CompileRun(source); + CHECK_EQ(expected, value->Int32Value(context.local()).FromJust()); } @@ -399,8 +433,9 @@ static void InterceptorLoadICGetter( ApiTestFuzzer::Fuzz(); v8::Isolate* isolate = CcTest::isolate(); CHECK_EQ(isolate, info.GetIsolate()); - CHECK(v8_str("data")->Equals(info.Data())); - CHECK(v8_str("x")->Equals(name)); + v8::Local<v8::Context> context = isolate->GetCurrentContext(); + CHECK(v8_str("data")->Equals(context, info.Data()).FromJust()); + CHECK(v8_str("x")->Equals(context, name).FromJust()); info.GetReturnValue().Set(v8::Integer::New(isolate, 42)); } @@ -424,9 +459,11 @@ static void InterceptorLoadXICGetter( Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); info.GetReturnValue().Set( - v8_str("x")->Equals(name) - ? v8::Handle<v8::Value>(v8::Integer::New(info.GetIsolate(), 42)) - : v8::Handle<v8::Value>()); + v8_str("x") + ->Equals(info.GetIsolate()->GetCurrentContext(), name) + .FromJust() + ? v8::Local<v8::Value>(v8::Integer::New(info.GetIsolate(), 42)) + : v8::Local<v8::Value>()); } @@ -592,28 +629,33 @@ THREADED_TEST(InterceptorLoadICInvalidatedFieldViaGlobal) { static void SetOnThis(Local<String> name, Local<Value> value, const v8::PropertyCallbackInfo<void>& info) { - Local<Object>::Cast(info.This())->ForceSet(name, value); + Local<Object>::Cast(info.This()) + ->CreateDataProperty(info.GetIsolate()->GetCurrentContext(), name, value) + .FromJust(); } THREADED_TEST(InterceptorLoadICWithCallbackOnHolder) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); templ->SetAccessor(v8_str("y"), Return239Callback); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); // Check the case when receiver and interceptor's holder // are the same objects. - v8::Handle<Value> value = CompileRun( + v8::Local<Value> value = CompileRun( "var result = 0;" "for (var i = 0; i < 7; i++) {" " result = o.y;" "}"); - CHECK_EQ(239, value->Int32Value()); + CHECK_EQ(239, value->Int32Value(context.local()).FromJust()); // Check the case when interceptor's holder is in proto chain // of receiver. @@ -623,32 +665,38 @@ THREADED_TEST(InterceptorLoadICWithCallbackOnHolder) { "for (var i = 0; i < 7; i++) {" " result = r.y;" "}"); - CHECK_EQ(239, value->Int32Value()); + CHECK_EQ(239, value->Int32Value(context.local()).FromJust()); } THREADED_TEST(InterceptorLoadICWithCallbackOnProto) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); - v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); templ_p->SetAccessor(v8_str("y"), Return239Callback); LocalContext context; - context->Global()->Set(v8_str("o"), templ_o->NewInstance()); - context->Global()->Set(v8_str("p"), templ_p->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("o"), + templ_o->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + context->Global() + ->Set(context.local(), v8_str("p"), + templ_p->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); // Check the case when receiver and interceptor's holder // are the same objects. - v8::Handle<Value> value = CompileRun( + v8::Local<Value> value = CompileRun( "o.__proto__ = p;" "var result = 0;" "for (var i = 0; i < 7; i++) {" " result = o.x + o.y;" "}"); - CHECK_EQ(239 + 42, value->Int32Value()); + CHECK_EQ(239 + 42, value->Int32Value(context.local()).FromJust()); // Check the case when interceptor's holder is in proto chain // of receiver. @@ -658,22 +706,25 @@ THREADED_TEST(InterceptorLoadICWithCallbackOnProto) { "for (var i = 0; i < 7; i++) {" " result = r.x + r.y;" "}"); - CHECK_EQ(239 + 42, value->Int32Value()); + CHECK_EQ(239 + 42, value->Int32Value(context.local()).FromJust()); } THREADED_TEST(InterceptorLoadICForCallbackWithOverride) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); templ->SetAccessor(v8_str("y"), Return239Callback); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); - v8::Handle<Value> value = CompileRun( + v8::Local<Value> value = CompileRun( "fst = new Object(); fst.__proto__ = o;" "snd = new Object(); snd.__proto__ = fst;" "var result1 = 0;" @@ -686,7 +737,7 @@ THREADED_TEST(InterceptorLoadICForCallbackWithOverride) { " result = snd.x;" "}" "result + result1"); - CHECK_EQ(239 + 42, value->Int32Value()); + CHECK_EQ(239 + 42, value->Int32Value(context.local()).FromJust()); } @@ -695,17 +746,23 @@ THREADED_TEST(InterceptorLoadICForCallbackWithOverride) { THREADED_TEST(InterceptorLoadICCallbackNotNeeded) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); - v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); templ_p->SetAccessor(v8_str("y"), Return239Callback); LocalContext context; - context->Global()->Set(v8_str("o"), templ_o->NewInstance()); - context->Global()->Set(v8_str("p"), templ_p->NewInstance()); - - v8::Handle<Value> value = CompileRun( + context->Global() + ->Set(context.local(), v8_str("o"), + templ_o->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + context->Global() + ->Set(context.local(), v8_str("p"), + templ_p->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + + v8::Local<Value> value = CompileRun( "o.__proto__ = p;" "for (var i = 0; i < 7; i++) {" " o.x;" @@ -716,7 +773,7 @@ THREADED_TEST(InterceptorLoadICCallbackNotNeeded) { " result += o.x;" "}" "result"); - CHECK_EQ(42 * 7, value->Int32Value()); + CHECK_EQ(42 * 7, value->Int32Value(context.local()).FromJust()); } @@ -725,17 +782,23 @@ THREADED_TEST(InterceptorLoadICCallbackNotNeeded) { THREADED_TEST(InterceptorLoadICInvalidatedCallback) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); - v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis); LocalContext context; - context->Global()->Set(v8_str("o"), templ_o->NewInstance()); - context->Global()->Set(v8_str("p"), templ_p->NewInstance()); - - v8::Handle<Value> value = CompileRun( + context->Global() + ->Set(context.local(), v8_str("o"), + templ_o->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + context->Global() + ->Set(context.local(), v8_str("p"), + templ_p->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + + v8::Local<Value> value = CompileRun( "inbetween = new Object();" "o.__proto__ = inbetween;" "inbetween.__proto__ = p;" @@ -749,7 +812,7 @@ THREADED_TEST(InterceptorLoadICInvalidatedCallback) { " result += o.y;" "}" "result"); - CHECK_EQ(42 * 10, value->Int32Value()); + CHECK_EQ(42 * 10, value->Int32Value(context.local()).FromJust()); } @@ -759,17 +822,23 @@ THREADED_TEST(InterceptorLoadICInvalidatedCallback) { THREADED_TEST(InterceptorLoadICInvalidatedCallbackViaGlobal) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); - v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis); LocalContext context; - context->Global()->Set(v8_str("o"), templ_o->NewInstance()); - context->Global()->Set(v8_str("p"), templ_p->NewInstance()); - - v8::Handle<Value> value = CompileRun( + context->Global() + ->Set(context.local(), v8_str("o"), + templ_o->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + context->Global() + ->Set(context.local(), v8_str("p"), + templ_p->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + + v8::Local<Value> value = CompileRun( "o.__proto__ = this;" "this.__proto__ = p;" "for (var i = 0; i < 10; i++) {" @@ -782,14 +851,16 @@ THREADED_TEST(InterceptorLoadICInvalidatedCallbackViaGlobal) { " result += o.y;" "}" "result"); - CHECK_EQ(42 * 10, value->Int32Value()); + CHECK_EQ(42 * 10, value->Int32Value(context.local()).FromJust()); } static void InterceptorLoadICGetter0( Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - CHECK(v8_str("x")->Equals(name)); + CHECK(v8_str("x") + ->Equals(info.GetIsolate()->GetCurrentContext(), name) + .FromJust()); info.GetReturnValue().Set(v8::Integer::New(info.GetIsolate(), 0)); } @@ -803,8 +874,9 @@ THREADED_TEST(InterceptorReturningZero) { static void InterceptorStoreICSetter( Local<Name> key, Local<Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) { - CHECK(v8_str("x")->Equals(key)); - CHECK_EQ(42, value->Int32Value()); + v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); + CHECK(v8_str("x")->Equals(context, key).FromJust()); + CHECK_EQ(42, value->Int32Value(context).FromJust()); info.GetReturnValue().Set(value); } @@ -813,12 +885,15 @@ static void InterceptorStoreICSetter( THREADED_TEST(InterceptorStoreIC) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration( InterceptorLoadICGetter, InterceptorStoreICSetter, 0, 0, 0, v8_str("data"))); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); CompileRun( "for (var i = 0; i < 1000; i++) {" " o.x = 42;" @@ -829,30 +904,36 @@ THREADED_TEST(InterceptorStoreIC) { THREADED_TEST(InterceptorStoreICWithNoSetter) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); - v8::Handle<Value> value = CompileRun( + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + v8::Local<Value> value = CompileRun( "for (var i = 0; i < 1000; i++) {" " o.y = 239;" "}" "42 + o.y"); - CHECK_EQ(239 + 42, value->Int32Value()); + CHECK_EQ(239 + 42, value->Int32Value(context.local()).FromJust()); } THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); - Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); child->Inherit(parent); AddAccessor(parent, v8_str("age"), SimpleAccessorGetter, SimpleAccessorSetter); AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Child"), child->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Child"), + child->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var child = new Child;" "child.age = 10;"); @@ -866,16 +947,19 @@ THREADED_TEST(LegacyInterceptorDoesNotSeeSymbols) { LocalContext env; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); - Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); + Local<FunctionTemplate> parent = FunctionTemplate::New(isolate); + Local<FunctionTemplate> child = FunctionTemplate::New(isolate); v8::Local<v8::Symbol> age = v8::Symbol::New(isolate, v8_str("age")); child->Inherit(parent); AddAccessor(parent, age, SymbolAccessorGetter, SymbolAccessorSetter); AddInterceptor(child, StringInterceptorGetter, StringInterceptorSetter); - env->Global()->Set(v8_str("Child"), child->GetFunction()); - env->Global()->Set(v8_str("age"), age); + env->Global() + ->Set(env.local(), v8_str("Child"), + child->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); + env->Global()->Set(env.local(), v8_str("age"), age).FromJust(); CompileRun( "var child = new Child;" "child[age] = 10;"); @@ -889,8 +973,8 @@ THREADED_TEST(GenericInterceptorDoesSeeSymbols) { LocalContext env; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); - Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); + Local<FunctionTemplate> parent = FunctionTemplate::New(isolate); + Local<FunctionTemplate> child = FunctionTemplate::New(isolate); v8::Local<v8::Symbol> age = v8::Symbol::New(isolate, v8_str("age")); v8::Local<v8::Symbol> anon = v8::Symbol::New(isolate); @@ -898,9 +982,12 @@ THREADED_TEST(GenericInterceptorDoesSeeSymbols) { AddAccessor(parent, age, SymbolAccessorGetter, SymbolAccessorSetter); AddInterceptor(child, GenericInterceptorGetter, GenericInterceptorSetter); - env->Global()->Set(v8_str("Child"), child->GetFunction()); - env->Global()->Set(v8_str("age"), age); - env->Global()->Set(v8_str("anon"), anon); + env->Global() + ->Set(env.local(), v8_str("Child"), + child->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); + env->Global()->Set(env.local(), v8_str("age"), age).FromJust(); + env->Global()->Set(env.local(), v8_str("anon"), anon).FromJust(); CompileRun( "var child = new Child;" "child[age] = 10;"); @@ -921,23 +1008,40 @@ THREADED_TEST(GenericInterceptorDoesSeeSymbols) { THREADED_TEST(NamedPropertyHandlerGetter) { echo_named_call_count = 0; v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::FunctionTemplate> templ = + v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(CcTest::isolate()); templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( EchoNamedProperty, 0, 0, 0, 0, v8_str("data"))); LocalContext env; - env->Global()->Set(v8_str("obj"), templ->GetFunction()->NewInstance()); + env->Global() + ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked()) + .FromJust(); CHECK_EQ(echo_named_call_count, 0); - v8_compile("obj.x")->Run(); + v8_compile("obj.x")->Run(env.local()).ToLocalChecked(); CHECK_EQ(echo_named_call_count, 1); const char* code = "var str = 'oddle'; obj[str] + obj.poddle;"; - v8::Handle<Value> str = CompileRun(code); + v8::Local<Value> str = CompileRun(code); String::Utf8Value value(str); CHECK_EQ(0, strcmp(*value, "oddlepoddle")); // Check default behavior - CHECK_EQ(10, v8_compile("obj.flob = 10;")->Run()->Int32Value()); - CHECK(v8_compile("'myProperty' in obj")->Run()->BooleanValue()); - CHECK(v8_compile("delete obj.myProperty")->Run()->BooleanValue()); + CHECK_EQ(10, v8_compile("obj.flob = 10;") + ->Run(env.local()) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK(v8_compile("'myProperty' in obj") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); + CHECK(v8_compile("delete obj.myProperty") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); } @@ -947,7 +1051,9 @@ int echo_indexed_call_count = 0; static void EchoIndexedProperty( uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - CHECK(v8_num(637)->Equals(info.Data())); + CHECK(v8_num(637) + ->Equals(info.GetIsolate()->GetCurrentContext(), info.Data()) + .FromJust()); echo_indexed_call_count++; info.GetReturnValue().Set(v8_num(index)); } @@ -956,13 +1062,22 @@ static void EchoIndexedProperty( THREADED_TEST(IndexedPropertyHandlerGetter) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); + v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration( EchoIndexedProperty, 0, 0, 0, 0, v8_num(637))); LocalContext env; - env->Global()->Set(v8_str("obj"), templ->GetFunction()->NewInstance()); + env->Global() + ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked()) + .FromJust(); Local<Script> script = v8_compile("obj[900]"); - CHECK_EQ(script->Run()->Int32Value(), 900); + CHECK_EQ(script->Run(env.local()) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust(), + 900); } @@ -972,7 +1087,7 @@ THREADED_TEST(PropertyHandlerInPrototype) { v8::HandleScope scope(isolate); // Set up a prototype chain with three interceptors. - v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); + v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration( CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter, CheckThisIndexedPropertyQuery, CheckThisIndexedPropertyDeleter, @@ -983,13 +1098,22 @@ THREADED_TEST(PropertyHandlerInPrototype) { CheckThisNamedPropertyQuery, CheckThisNamedPropertyDeleter, CheckThisNamedPropertyEnumerator)); - bottom = templ->GetFunction()->NewInstance(); - Local<v8::Object> top = templ->GetFunction()->NewInstance(); - Local<v8::Object> middle = templ->GetFunction()->NewInstance(); - - bottom->SetPrototype(middle); - middle->SetPrototype(top); - env->Global()->Set(v8_str("obj"), bottom); + bottom = templ->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked(); + Local<v8::Object> top = templ->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked(); + Local<v8::Object> middle = templ->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked(); + + bottom->SetPrototype(env.local(), middle).FromJust(); + middle->SetPrototype(env.local(), top).FromJust(); + env->Global()->Set(env.local(), v8_str("obj"), bottom).FromJust(); // Indexed and named get. CompileRun("obj[0]"); @@ -1016,7 +1140,10 @@ bool is_bootstrapping = false; static void PrePropertyHandlerGet( Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - if (!is_bootstrapping && v8_str("pre")->Equals(key)) { + if (!is_bootstrapping && + v8_str("pre") + ->Equals(info.GetIsolate()->GetCurrentContext(), key) + .FromJust()) { info.GetReturnValue().Set(v8_str("PrePropertyHandler: pre")); } } @@ -1024,7 +1151,10 @@ static void PrePropertyHandlerGet( static void PrePropertyHandlerQuery( Local<Name> key, const v8::PropertyCallbackInfo<v8::Integer>& info) { - if (!is_bootstrapping && v8_str("pre")->Equals(key)) { + if (!is_bootstrapping && + v8_str("pre") + ->Equals(info.GetIsolate()->GetCurrentContext(), key) + .FromJust()) { info.GetReturnValue().Set(static_cast<int32_t>(v8::None)); } } @@ -1033,28 +1163,33 @@ static void PrePropertyHandlerQuery( THREADED_TEST(PrePropertyHandler) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); + v8::Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); desc->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( PrePropertyHandlerGet, 0, PrePropertyHandlerQuery)); is_bootstrapping = true; LocalContext env(NULL, desc->InstanceTemplate()); is_bootstrapping = false; CompileRun("var pre = 'Object: pre'; var on = 'Object: on';"); - v8::Handle<Value> result_pre = CompileRun("pre"); - CHECK(v8_str("PrePropertyHandler: pre")->Equals(result_pre)); - v8::Handle<Value> result_on = CompileRun("on"); - CHECK(v8_str("Object: on")->Equals(result_on)); - v8::Handle<Value> result_post = CompileRun("post"); + v8::Local<Value> result_pre = CompileRun("pre"); + CHECK(v8_str("PrePropertyHandler: pre") + ->Equals(env.local(), result_pre) + .FromJust()); + v8::Local<Value> result_on = CompileRun("on"); + CHECK(v8_str("Object: on")->Equals(env.local(), result_on).FromJust()); + v8::Local<Value> result_post = CompileRun("post"); CHECK(result_post.IsEmpty()); } THREADED_TEST(EmptyInterceptorBreakTransitions) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Constructor"), templ->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Constructor"), + templ->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var o1 = new Constructor;" "o1.a = 1;" // Ensure a and x share the descriptor array. @@ -1069,12 +1204,15 @@ THREADED_TEST(EmptyInterceptorBreakTransitions) { THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); - Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); + Local<FunctionTemplate> parent = FunctionTemplate::New(isolate); + Local<FunctionTemplate> child = FunctionTemplate::New(isolate); child->Inherit(parent); AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Child"), child->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Child"), + child->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var child = new Child;" "var parent = child.__proto__;" @@ -1092,14 +1230,17 @@ THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { THREADED_TEST(EmptyInterceptorDoesNotShadowApiAccessors) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); + Local<FunctionTemplate> parent = FunctionTemplate::New(isolate); auto returns_42 = FunctionTemplate::New(isolate, Returns42); parent->PrototypeTemplate()->SetAccessorProperty(v8_str("age"), returns_42); - Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); + Local<FunctionTemplate> child = FunctionTemplate::New(isolate); child->Inherit(parent); AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Child"), child->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Child"), + child->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var child = new Child;" "var parent = child.__proto__;"); @@ -1119,12 +1260,15 @@ THREADED_TEST(EmptyInterceptorDoesNotShadowApiAccessors) { THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); - Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); + Local<FunctionTemplate> parent = FunctionTemplate::New(isolate); + Local<FunctionTemplate> child = FunctionTemplate::New(isolate); child->Inherit(parent); AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Child"), child->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Child"), + child->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var child = new Child;" "var parent = child.__proto__;" @@ -1140,11 +1284,14 @@ THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) { THREADED_TEST(SwitchFromInterceptorToAccessor) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddAccessor(templ, v8_str("age"), SimpleAccessorGetter, SimpleAccessorSetter); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Obj"), templ->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Obj"), + templ->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var obj = new Obj;" "function setAge(i){ obj.age = i; };" @@ -1158,11 +1305,14 @@ THREADED_TEST(SwitchFromInterceptorToAccessor) { THREADED_TEST(SwitchFromAccessorToInterceptor) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddAccessor(templ, v8_str("age"), SimpleAccessorGetter, SimpleAccessorSetter); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Obj"), templ->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Obj"), + templ->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var obj = new Obj;" "function setAge(i){ obj.age = i; };" @@ -1176,14 +1326,17 @@ THREADED_TEST(SwitchFromAccessorToInterceptor) { THREADED_TEST(SwitchFromInterceptorToAccessorWithInheritance) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); - Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); child->Inherit(parent); AddAccessor(parent, v8_str("age"), SimpleAccessorGetter, SimpleAccessorSetter); AddInterceptor(child, InterceptorGetter, InterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Child"), child->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Child"), + child->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var child = new Child;" "function setAge(i){ child.age = i; };" @@ -1197,14 +1350,17 @@ THREADED_TEST(SwitchFromInterceptorToAccessorWithInheritance) { THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); - Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); child->Inherit(parent); AddAccessor(parent, v8_str("age"), SimpleAccessorGetter, SimpleAccessorSetter); AddInterceptor(child, InterceptorGetter, InterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Child"), child->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Child"), + child->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var child = new Child;" "function setAge(i){ child.age = i; };" @@ -1218,10 +1374,13 @@ THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) { THREADED_TEST(SwitchFromInterceptorToJSAccessor) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Obj"), templ->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Obj"), + templ->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var obj = new Obj;" "function setter(i) { this.accessor_age = i; };" @@ -1244,10 +1403,13 @@ THREADED_TEST(SwitchFromInterceptorToJSAccessor) { THREADED_TEST(SwitchFromJSAccessorToInterceptor) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Obj"), templ->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Obj"), + templ->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var obj = new Obj;" "function setter(i) { this.accessor_age = i; };" @@ -1270,12 +1432,15 @@ THREADED_TEST(SwitchFromJSAccessorToInterceptor) { THREADED_TEST(SwitchFromInterceptorToProperty) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); - Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); child->Inherit(parent); AddInterceptor(child, InterceptorGetter, InterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Child"), child->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Child"), + child->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var child = new Child;" "function setAge(i){ child.age = i; };" @@ -1289,12 +1454,15 @@ THREADED_TEST(SwitchFromInterceptorToProperty) { THREADED_TEST(SwitchFromPropertyToInterceptor) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); - Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); child->Inherit(parent); AddInterceptor(child, InterceptorGetter, InterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Child"), child->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Child"), + child->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var child = new Child;" "function setAge(i){ child.age = i; };" @@ -1328,13 +1496,16 @@ THREADED_TEST(HiddenPropertiesWithInterceptors) { Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); instance_templ->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorForHiddenProperties)); - Local<v8::Function> function = fun_templ->GetFunction(); - Local<v8::Object> obj = function->NewInstance(); + Local<v8::Function> function = + fun_templ->GetFunction(context.local()).ToLocalChecked(); + Local<v8::Object> obj = + function->NewInstance(context.local()).ToLocalChecked(); CHECK(obj->SetPrivate(context.local(), key, v8::Integer::New(isolate, 2302)) .FromJust()); - CHECK_EQ( - 2302, - obj->GetPrivate(context.local(), key).ToLocalChecked()->Int32Value()); + CHECK_EQ(2302, obj->GetPrivate(context.local(), key) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); CHECK(!interceptor_for_hidden_properties_called); } @@ -1353,11 +1524,14 @@ THREADED_TEST(NamedInterceptorPropertyRead) { Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter)); LocalContext context; - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); Local<Script> script = v8_compile("obj.x"); for (int i = 0; i < 10; i++) { - Local<Value> result = script->Run(); - CHECK(result->Equals(v8_str("x"))); + Local<Value> result = script->Run(context.local()).ToLocalChecked(); + CHECK(result->Equals(context.local(), v8_str("x")).FromJust()); } } @@ -1369,11 +1543,14 @@ THREADED_TEST(NamedInterceptorDictionaryIC) { templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter)); LocalContext context; // Create an object with a named interceptor. - context->Global()->Set(v8_str("interceptor_obj"), templ->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("interceptor_obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); Local<Script> script = v8_compile("interceptor_obj.x"); for (int i = 0; i < 10; i++) { - Local<Value> result = script->Run(); - CHECK(result->Equals(v8_str("x"))); + Local<Value> result = script->Run(context.local()).ToLocalChecked(); + CHECK(result->Equals(context.local(), v8_str("x")).FromJust()); } // Create a slow case object and a function accessing a property in // that slow case object (with dictionary probing in generated @@ -1389,7 +1566,7 @@ THREADED_TEST(NamedInterceptorDictionaryIC) { "interceptor_obj.y = 10;" "delete interceptor_obj.y;" "get_x(interceptor_obj)"); - CHECK(result->Equals(v8_str("x"))); + CHECK(result->Equals(context.local(), v8_str("x")).FromJust()); } @@ -1402,8 +1579,10 @@ THREADED_TEST(NamedInterceptorDictionaryICMultipleContext) { Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter)); // Create an object with a named interceptor. - v8::Local<v8::Object> object = templ->NewInstance(); - context1->Global()->Set(v8_str("interceptor_obj"), object); + v8::Local<v8::Object> object = templ->NewInstance(context1).ToLocalChecked(); + context1->Global() + ->Set(context1, v8_str("interceptor_obj"), object) + .FromJust(); // Force the object into the slow case. CompileRun( @@ -1415,7 +1594,9 @@ THREADED_TEST(NamedInterceptorDictionaryICMultipleContext) { // Introduce the object into a different context. // Repeat named loads to exercise ICs. LocalContext context2; - context2->Global()->Set(v8_str("interceptor_obj"), object); + context2->Global() + ->Set(context2.local(), v8_str("interceptor_obj"), object) + .FromJust(); Local<Value> result = CompileRun( "function get_x(o) { return o.x; }" "interceptor_obj.x = 42;" @@ -1424,7 +1605,7 @@ THREADED_TEST(NamedInterceptorDictionaryICMultipleContext) { "}" "get_x(interceptor_obj)"); // Check that the interceptor was actually invoked. - CHECK(result->Equals(v8_str("x"))); + CHECK(result->Equals(context2.local(), v8_str("x")).FromJust()); } // Return to the original context and force some object to the slow case @@ -1438,9 +1619,11 @@ THREADED_TEST(NamedInterceptorDictionaryICMultipleContext) { static void SetXOnPrototypeGetter( Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) { // Set x on the prototype object and do not handle the get request. - v8::Handle<v8::Value> proto = info.Holder()->GetPrototype(); - proto.As<v8::Object>()->Set(v8_str("x"), - v8::Integer::New(info.GetIsolate(), 23)); + v8::Local<v8::Value> proto = info.Holder()->GetPrototype(); + proto.As<v8::Object>() + ->Set(info.GetIsolate()->GetCurrentContext(), v8_str("x"), + v8::Integer::New(info.GetIsolate(), 23)) + .FromJust(); } @@ -1456,12 +1639,15 @@ THREADED_TEST(NamedInterceptorMapTransitionRead) { instance_template->SetHandler( v8::NamedPropertyHandlerConfiguration(SetXOnPrototypeGetter)); LocalContext context; - context->Global()->Set(v8_str("F"), function_template->GetFunction()); + context->Global() + ->Set(context.local(), v8_str("F"), + function_template->GetFunction(context.local()).ToLocalChecked()) + .FromJust(); // Create an instance of F and introduce a map transition for x. CompileRun("var o = new F(); o.x = 23;"); // Create an instance of F and invoke the getter. The result should be 23. Local<Value> result = CompileRun("o = new F(); o.x"); - CHECK_EQ(result->Int32Value(), 23); + CHECK_EQ(result->Int32Value(context.local()).FromJust(), 23); } @@ -1491,7 +1677,10 @@ THREADED_TEST(IndexedInterceptorWithIndexedAccessor) { templ->SetHandler(v8::IndexedPropertyHandlerConfiguration( IndexedPropertyGetter, IndexedPropertySetter)); LocalContext context; - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); Local<Script> getter_script = v8_compile("obj.__defineGetter__(\"3\", function(){return 5;});obj[3];"); Local<Script> setter_script = v8_compile( @@ -1503,14 +1692,14 @@ THREADED_TEST(IndexedInterceptorWithIndexedAccessor) { "obj[39] = 47;" "obj.foo;"); // This setter should not run, due to the interceptor. Local<Script> interceptor_getter_script = v8_compile("obj[37];"); - Local<Value> result = getter_script->Run(); - CHECK(v8_num(5)->Equals(result)); - result = setter_script->Run(); - CHECK(v8_num(23)->Equals(result)); - result = interceptor_setter_script->Run(); - CHECK(v8_num(23)->Equals(result)); - result = interceptor_getter_script->Run(); - CHECK(v8_num(625)->Equals(result)); + Local<Value> result = getter_script->Run(context.local()).ToLocalChecked(); + CHECK(v8_num(5)->Equals(context.local(), result).FromJust()); + result = setter_script->Run(context.local()).ToLocalChecked(); + CHECK(v8_num(23)->Equals(context.local(), result).FromJust()); + result = interceptor_setter_script->Run(context.local()).ToLocalChecked(); + CHECK(v8_num(23)->Equals(context.local(), result).FromJust()); + result = interceptor_getter_script->Run(context.local()).ToLocalChecked(); + CHECK(v8_num(625)->Equals(context.local(), result).FromJust()); } @@ -1540,7 +1729,9 @@ void UnboxedDoubleIndexedPropertyEnumerator( "keys = new Array(); keys[125000] = 1;" "for(i = 0; i < 80000; i++) { keys[i] = i; };" "keys.length = 25; keys;"); - Local<Value> result = indexed_property_names_script->Run(); + Local<Value> result = + indexed_property_names_script->Run(info.GetIsolate()->GetCurrentContext()) + .ToLocalChecked(); info.GetReturnValue().Set(Local<v8::Array>::Cast(result)); } @@ -1555,18 +1746,25 @@ THREADED_TEST(IndexedInterceptorUnboxedDoubleWithIndexedAccessor) { UnboxedDoubleIndexedPropertyGetter, UnboxedDoubleIndexedPropertySetter, 0, 0, UnboxedDoubleIndexedPropertyEnumerator)); LocalContext context; - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); // When obj is created, force it to be Stored in a FastDoubleArray. Local<Script> create_unboxed_double_script = v8_compile( "obj[125000] = 1; for(i = 0; i < 80000; i+=2) { obj[i] = i; } " "key_count = 0; " "for (x in obj) {key_count++;};" "obj;"); - Local<Value> result = create_unboxed_double_script->Run(); - CHECK(result->ToObject(isolate)->HasRealIndexedProperty(2000)); + Local<Value> result = + create_unboxed_double_script->Run(context.local()).ToLocalChecked(); + CHECK(result->ToObject(context.local()) + .ToLocalChecked() + ->HasRealIndexedProperty(context.local(), 2000) + .FromJust()); Local<Script> key_count_check = v8_compile("key_count;"); - result = key_count_check->Run(); - CHECK(v8_num(40013)->Equals(result)); + result = key_count_check->Run(context.local()).ToLocalChecked(); + CHECK(v8_num(40013)->Equals(context.local(), result).FromJust()); } @@ -1579,10 +1777,12 @@ void SloppyArgsIndexedPropertyEnumerator( "}" "keys = f(0, 1, 2, 3);" "keys;"); - Local<Object> result = - Local<Object>::Cast(indexed_property_names_script->Run()); + Local<Object> result = Local<Object>::Cast( + indexed_property_names_script->Run(info.GetIsolate()->GetCurrentContext()) + .ToLocalChecked()); // Have to populate the handle manually, as it's not Cast-able. - i::Handle<i::JSObject> o = v8::Utils::OpenHandle<Object, i::JSObject>(result); + i::Handle<i::JSReceiver> o = + v8::Utils::OpenHandle<Object, i::JSReceiver>(result); i::Handle<i::JSArray> array(reinterpret_cast<i::JSArray*>(*o)); info.GetReturnValue().Set(v8::Utils::ToLocal(array)); } @@ -1607,12 +1807,16 @@ THREADED_TEST(IndexedInterceptorSloppyArgsWithIndexedAccessor) { SloppyIndexedPropertyGetter, 0, 0, 0, SloppyArgsIndexedPropertyEnumerator)); LocalContext context; - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); Local<Script> create_args_script = v8_compile( "var key_count = 0;" "for (x in obj) {key_count++;} key_count;"); - Local<Value> result = create_args_script->Run(); - CHECK(v8_num(4)->Equals(result)); + Local<Value> result = + create_args_script->Run(context.local()).ToLocalChecked(); + CHECK(v8_num(4)->Equals(context.local(), result).FromJust()); } @@ -1630,7 +1834,10 @@ THREADED_TEST(IndexedInterceptorWithGetOwnPropertyDescriptor) { v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); LocalContext context; - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); // Check fast object case. const char* fast_case_code = @@ -1653,7 +1860,10 @@ THREADED_TEST(IndexedInterceptorWithNoSetter) { v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); LocalContext context; - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); const char* code = "try {" @@ -1686,8 +1896,8 @@ THREADED_TEST(IndexedInterceptorWithAccessorCheck) { templ->SetAccessCheckCallback(AccessAlwaysBlocked); LocalContext context; - Local<v8::Object> obj = templ->NewInstance(); - context->Global()->Set(v8_str("obj"), obj); + Local<v8::Object> obj = templ->NewInstance(context.local()).ToLocalChecked(); + context->Global()->Set(context.local(), v8_str("obj"), obj).FromJust(); const char* code = "var result = 'PASSED';" @@ -1713,8 +1923,8 @@ THREADED_TEST(IndexedInterceptorWithDifferentIndices) { v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); LocalContext context; - Local<v8::Object> obj = templ->NewInstance(); - context->Global()->Set(v8_str("obj"), obj); + Local<v8::Object> obj = templ->NewInstance(context.local()).ToLocalChecked(); + context->Global()->Set(context.local(), v8_str("obj"), obj).FromJust(); const char* code = "try {" @@ -1738,8 +1948,8 @@ THREADED_TEST(IndexedInterceptorWithNegativeIndices) { v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); LocalContext context; - Local<v8::Object> obj = templ->NewInstance(); - context->Global()->Set(v8_str("obj"), obj); + Local<v8::Object> obj = templ->NewInstance(context.local()).ToLocalChecked(); + context->Global()->Set(context.local(), v8_str("obj"), obj).FromJust(); const char* code = "try {" @@ -1779,8 +1989,8 @@ THREADED_TEST(IndexedInterceptorWithNotSmiLookup) { v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); LocalContext context; - Local<v8::Object> obj = templ->NewInstance(); - context->Global()->Set(v8_str("obj"), obj); + Local<v8::Object> obj = templ->NewInstance(context.local()).ToLocalChecked(); + context->Global()->Set(context.local(), v8_str("obj"), obj).FromJust(); const char* code = "try {" @@ -1810,8 +2020,8 @@ THREADED_TEST(IndexedInterceptorGoingMegamorphic) { v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); LocalContext context; - Local<v8::Object> obj = templ->NewInstance(); - context->Global()->Set(v8_str("obj"), obj); + Local<v8::Object> obj = templ->NewInstance(context.local()).ToLocalChecked(); + context->Global()->Set(context.local(), v8_str("obj"), obj).FromJust(); const char* code = "var original = obj;" @@ -1842,8 +2052,8 @@ THREADED_TEST(IndexedInterceptorReceiverTurningSmi) { v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); LocalContext context; - Local<v8::Object> obj = templ->NewInstance(); - context->Global()->Set(v8_str("obj"), obj); + Local<v8::Object> obj = templ->NewInstance(context.local()).ToLocalChecked(); + context->Global()->Set(context.local(), v8_str("obj"), obj).FromJust(); const char* code = "var original = obj;" @@ -1874,8 +2084,8 @@ THREADED_TEST(IndexedInterceptorOnProto) { v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); LocalContext context; - Local<v8::Object> obj = templ->NewInstance(); - context->Global()->Set(v8_str("obj"), obj); + Local<v8::Object> obj = templ->NewInstance(context.local()).ToLocalChecked(); + context->Global()->Set(context.local(), v8_str("obj"), obj).FromJust(); const char* code = "var o = {__proto__: obj};" @@ -1902,7 +2112,8 @@ static void NoBlockGetterI(uint32_t index, static void PDeleter(Local<Name> name, const v8::PropertyCallbackInfo<v8::Boolean>& info) { - if (!name->Equals(v8_str("foo"))) { + if (!name->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("foo")) + .FromJust()) { return; // not intercepted } @@ -1923,37 +2134,66 @@ static void IDeleter(uint32_t index, THREADED_TEST(Deleter) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX, NULL, NULL, PDeleter, NULL)); obj->SetHandler(v8::IndexedPropertyHandlerConfiguration( NoBlockGetterI, NULL, NULL, IDeleter, NULL)); LocalContext context; - context->Global()->Set(v8_str("k"), obj->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("k"), + obj->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); CompileRun( "k.foo = 'foo';" "k.bar = 'bar';" "k[2] = 2;" "k[4] = 4;"); - CHECK(v8_compile("delete k.foo")->Run()->IsFalse()); - CHECK(v8_compile("delete k.bar")->Run()->IsTrue()); - - CHECK(v8_compile("k.foo")->Run()->Equals(v8_str("foo"))); - CHECK(v8_compile("k.bar")->Run()->IsUndefined()); - - CHECK(v8_compile("delete k[2]")->Run()->IsFalse()); - CHECK(v8_compile("delete k[4]")->Run()->IsTrue()); - - CHECK(v8_compile("k[2]")->Run()->Equals(v8_num(2))); - CHECK(v8_compile("k[4]")->Run()->IsUndefined()); + CHECK(v8_compile("delete k.foo") + ->Run(context.local()) + .ToLocalChecked() + ->IsFalse()); + CHECK(v8_compile("delete k.bar") + ->Run(context.local()) + .ToLocalChecked() + ->IsTrue()); + + CHECK(v8_compile("k.foo") + ->Run(context.local()) + .ToLocalChecked() + ->Equals(context.local(), v8_str("foo")) + .FromJust()); + CHECK(v8_compile("k.bar") + ->Run(context.local()) + .ToLocalChecked() + ->IsUndefined()); + + CHECK(v8_compile("delete k[2]") + ->Run(context.local()) + .ToLocalChecked() + ->IsFalse()); + CHECK(v8_compile("delete k[4]") + ->Run(context.local()) + .ToLocalChecked() + ->IsTrue()); + + CHECK(v8_compile("k[2]") + ->Run(context.local()) + .ToLocalChecked() + ->Equals(context.local(), v8_num(2)) + .FromJust()); + CHECK( + v8_compile("k[4]")->Run(context.local()).ToLocalChecked()->IsUndefined()); } static void GetK(Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - if (name->Equals(v8_str("foo")) || name->Equals(v8_str("bar")) || - name->Equals(v8_str("baz"))) { + v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); + if (name->Equals(context, v8_str("foo")).FromJust() || + name->Equals(context, v8_str("bar")).FromJust() || + name->Equals(context, v8_str("baz")).FromJust()) { info.GetReturnValue().SetUndefined(); } } @@ -1968,19 +2208,26 @@ static void IndexedGetK(uint32_t index, static void NamedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { ApiTestFuzzer::Fuzz(); - v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 3); - result->Set(v8::Integer::New(info.GetIsolate(), 0), v8_str("foo")); - result->Set(v8::Integer::New(info.GetIsolate(), 1), v8_str("bar")); - result->Set(v8::Integer::New(info.GetIsolate(), 2), v8_str("baz")); + v8::Local<v8::Array> result = v8::Array::New(info.GetIsolate(), 3); + v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); + result->Set(context, v8::Integer::New(info.GetIsolate(), 0), v8_str("foo")) + .FromJust(); + result->Set(context, v8::Integer::New(info.GetIsolate(), 1), v8_str("bar")) + .FromJust(); + result->Set(context, v8::Integer::New(info.GetIsolate(), 2), v8_str("baz")) + .FromJust(); info.GetReturnValue().Set(result); } static void IndexedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { ApiTestFuzzer::Fuzz(); - v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2); - result->Set(v8::Integer::New(info.GetIsolate(), 0), v8_str("0")); - result->Set(v8::Integer::New(info.GetIsolate(), 1), v8_str("1")); + v8::Local<v8::Array> result = v8::Array::New(info.GetIsolate(), 2); + v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); + result->Set(context, v8::Integer::New(info.GetIsolate(), 0), v8_str("0")) + .FromJust(); + result->Set(context, v8::Integer::New(info.GetIsolate(), 1), v8_str("1")) + .FromJust(); info.GetReturnValue().Set(result); } @@ -1988,31 +2235,34 @@ static void IndexedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { THREADED_TEST(Enumerators) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetHandler( v8::NamedPropertyHandlerConfiguration(GetK, NULL, NULL, NULL, NamedEnum)); obj->SetHandler(v8::IndexedPropertyHandlerConfiguration( IndexedGetK, NULL, NULL, NULL, IndexedEnum)); LocalContext context; - context->Global()->Set(v8_str("k"), obj->NewInstance()); - v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( - "k[10] = 0;" - "k.a = 0;" - "k[5] = 0;" - "k.b = 0;" - "k[4294967294] = 0;" - "k.c = 0;" - "k[4294967295] = 0;" - "k.d = 0;" - "k[140000] = 0;" - "k.e = 0;" - "k[30000000000] = 0;" - "k.f = 0;" - "var result = [];" - "for (var prop in k) {" - " result.push(prop);" - "}" - "result")); + context->Global() + ->Set(context.local(), v8_str("k"), + obj->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + v8::Local<v8::Array> result = + v8::Local<v8::Array>::Cast(CompileRun("k[10] = 0;" + "k.a = 0;" + "k[5] = 0;" + "k.b = 0;" + "k[4294967294] = 0;" + "k.c = 0;" + "k[4294967295] = 0;" + "k.d = 0;" + "k[140000] = 0;" + "k.e = 0;" + "k[30000000000] = 0;" + "k.f = 0;" + "var result = [];" + "for (var prop in k) {" + " result.push(prop);" + "}" + "result")); // Check that we get all the property names returned including the // ones from the enumerators in the right order: indexed properties // in numerical order, indexed interceptor properties, named @@ -2021,39 +2271,106 @@ THREADED_TEST(Enumerators) { // documenting our behavior. CHECK_EQ(17u, result->Length()); // Indexed properties + indexed interceptor properties in numerical order. - CHECK(v8_str("0")->Equals(result->Get(v8::Integer::New(isolate, 0)))); - CHECK(v8_str("1")->Equals(result->Get(v8::Integer::New(isolate, 1)))); - CHECK(v8_str("5")->Equals(result->Get(v8::Integer::New(isolate, 2)))); - CHECK(v8_str("10")->Equals(result->Get(v8::Integer::New(isolate, 3)))); - CHECK(v8_str("140000")->Equals(result->Get(v8::Integer::New(isolate, 4)))); - CHECK( - v8_str("4294967294")->Equals(result->Get(v8::Integer::New(isolate, 5)))); + CHECK(v8_str("0") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 0)) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str("1") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 1)) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str("5") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 2)) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str("10") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 3)) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str("140000") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 4)) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str("4294967294") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 5)) + .ToLocalChecked()) + .FromJust()); // Named properties in insertion order. - CHECK(v8_str("a")->Equals(result->Get(v8::Integer::New(isolate, 6)))); - CHECK(v8_str("b")->Equals(result->Get(v8::Integer::New(isolate, 7)))); - CHECK(v8_str("c")->Equals(result->Get(v8::Integer::New(isolate, 8)))); - CHECK( - v8_str("4294967295")->Equals(result->Get(v8::Integer::New(isolate, 9)))); - CHECK(v8_str("d")->Equals(result->Get(v8::Integer::New(isolate, 10)))); - CHECK(v8_str("e")->Equals(result->Get(v8::Integer::New(isolate, 11)))); + CHECK(v8_str("a") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 6)) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str("b") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 7)) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str("c") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 8)) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str("4294967295") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 9)) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str("d") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 10)) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str("e") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 11)) + .ToLocalChecked()) + .FromJust()); CHECK(v8_str("30000000000") - ->Equals(result->Get(v8::Integer::New(isolate, 12)))); - CHECK(v8_str("f")->Equals(result->Get(v8::Integer::New(isolate, 13)))); + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 12)) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str("f") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 13)) + .ToLocalChecked()) + .FromJust()); // Named interceptor properties. - CHECK(v8_str("foo")->Equals(result->Get(v8::Integer::New(isolate, 14)))); - CHECK(v8_str("bar")->Equals(result->Get(v8::Integer::New(isolate, 15)))); - CHECK(v8_str("baz")->Equals(result->Get(v8::Integer::New(isolate, 16)))); + CHECK(v8_str("foo") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 14)) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str("bar") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 15)) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str("baz") + ->Equals(context.local(), + result->Get(context.local(), v8::Integer::New(isolate, 16)) + .ToLocalChecked()) + .FromJust()); } -v8::Handle<Value> call_ic_function; -v8::Handle<Value> call_ic_function2; -v8::Handle<Value> call_ic_function3; +v8::Local<Value> call_ic_function; +v8::Local<Value> call_ic_function2; +v8::Local<Value> call_ic_function3; static void InterceptorCallICGetter( Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - CHECK(v8_str("x")->Equals(name)); + CHECK(v8_str("x") + ->Equals(info.GetIsolate()->GetCurrentContext(), name) + .FromJust()); info.GetReturnValue().Set(call_ic_function); } @@ -2062,18 +2379,23 @@ static void InterceptorCallICGetter( THREADED_TEST(InterceptorCallIC) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter)); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); - call_ic_function = v8_compile("function f(x) { return x + 1; }; f")->Run(); - v8::Handle<Value> value = CompileRun( + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + call_ic_function = v8_compile("function f(x) { return x + 1; }; f") + ->Run(context.local()) + .ToLocalChecked(); + v8::Local<Value> value = CompileRun( "var result = 0;" "for (var i = 0; i < 1000; i++) {" " result = o.x(41);" "}"); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(context.local()).FromJust()); } @@ -2082,25 +2404,30 @@ THREADED_TEST(InterceptorCallIC) { THREADED_TEST(InterceptorCallICSeesOthers) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); - v8::Handle<Value> value = CompileRun( + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + v8::Local<Value> value = CompileRun( "o.x = function f(x) { return x + 1; };" "var result = 0;" "for (var i = 0; i < 7; i++) {" " result = o.x(41);" "}"); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(context.local()).FromJust()); } -static v8::Handle<Value> call_ic_function4; +static v8::Local<Value> call_ic_function4; static void InterceptorCallICGetter4( Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - CHECK(v8_str("x")->Equals(name)); + CHECK(v8_str("x") + ->Equals(info.GetIsolate()->GetCurrentContext(), name) + .FromJust()); info.GetReturnValue().Set(call_ic_function4); } @@ -2111,19 +2438,24 @@ static void InterceptorCallICGetter4( THREADED_TEST(InterceptorCallICCacheableNotNeeded) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter4)); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); - call_ic_function4 = v8_compile("function f(x) { return x - 1; }; f")->Run(); - v8::Handle<Value> value = CompileRun( + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + call_ic_function4 = v8_compile("function f(x) { return x - 1; }; f") + ->Run(context.local()) + .ToLocalChecked(); + v8::Local<Value> value = CompileRun( "Object.getPrototypeOf(o).x = function(x) { return x + 1; };" "var result = 0;" "for (var i = 0; i < 1000; i++) {" " result = o.x(42);" "}"); - CHECK_EQ(41, value->Int32Value()); + CHECK_EQ(41, value->Int32Value(context.local()).FromJust()); } @@ -2132,11 +2464,14 @@ THREADED_TEST(InterceptorCallICCacheableNotNeeded) { THREADED_TEST(InterceptorCallICInvalidatedCacheable) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); - v8::Handle<Value> value = CompileRun( + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + v8::Local<Value> value = CompileRun( "proto1 = new Object();" "proto2 = new Object();" "o.__proto__ = proto1;" @@ -2151,7 +2486,7 @@ THREADED_TEST(InterceptorCallICInvalidatedCacheable) { "for (var i = 0; i < 7; i++) {" " result += o.y(42);" "}"); - CHECK_EQ(41 * 7, value->Int32Value()); + CHECK_EQ(41 * 7, value->Int32Value(context.local()).FromJust()); } @@ -2160,11 +2495,14 @@ THREADED_TEST(InterceptorCallICInvalidatedCacheable) { THREADED_TEST(InterceptorCallICConstantFunctionUsed) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); - v8::Handle<Value> value = CompileRun( + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + v8::Local<Value> value = CompileRun( "function inc(x) { return x + 1; };" "inc(1);" "o.x = inc;" @@ -2172,15 +2510,18 @@ THREADED_TEST(InterceptorCallICConstantFunctionUsed) { "for (var i = 0; i < 1000; i++) {" " result = o.x(42);" "}"); - CHECK_EQ(43, value->Int32Value()); + CHECK_EQ(43, value->Int32Value(context.local()).FromJust()); } -static v8::Handle<Value> call_ic_function5; +static v8::Local<Value> call_ic_function5; static void InterceptorCallICGetter5( Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - if (v8_str("x")->Equals(name)) info.GetReturnValue().Set(call_ic_function5); + if (v8_str("x") + ->Equals(info.GetIsolate()->GetCurrentContext(), name) + .FromJust()) + info.GetReturnValue().Set(call_ic_function5); } @@ -2190,13 +2531,18 @@ static void InterceptorCallICGetter5( THREADED_TEST(InterceptorCallICConstantFunctionNotNeeded) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter5)); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); - call_ic_function5 = v8_compile("function f(x) { return x - 1; }; f")->Run(); - v8::Handle<Value> value = CompileRun( + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + call_ic_function5 = v8_compile("function f(x) { return x - 1; }; f") + ->Run(context.local()) + .ToLocalChecked(); + v8::Local<Value> value = CompileRun( "function inc(x) { return x + 1; };" "inc(1);" "o.x = inc;" @@ -2204,15 +2550,18 @@ THREADED_TEST(InterceptorCallICConstantFunctionNotNeeded) { "for (var i = 0; i < 1000; i++) {" " result = o.x(42);" "}"); - CHECK_EQ(41, value->Int32Value()); + CHECK_EQ(41, value->Int32Value(context.local()).FromJust()); } -static v8::Handle<Value> call_ic_function6; +static v8::Local<Value> call_ic_function6; static void InterceptorCallICGetter6( Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - if (v8_str("x")->Equals(name)) info.GetReturnValue().Set(call_ic_function6); + if (v8_str("x") + ->Equals(info.GetIsolate()->GetCurrentContext(), name) + .FromJust()) + info.GetReturnValue().Set(call_ic_function6); } @@ -2222,13 +2571,18 @@ THREADED_TEST(InterceptorCallICConstantFunctionNotNeededWrapped) { i::FLAG_allow_natives_syntax = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter6)); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); - call_ic_function6 = v8_compile("function f(x) { return x - 1; }; f")->Run(); - v8::Handle<Value> value = CompileRun( + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + call_ic_function6 = v8_compile("function f(x) { return x - 1; }; f") + ->Run(context.local()) + .ToLocalChecked(); + v8::Local<Value> value = CompileRun( "function inc(x) { return x + 1; };" "inc(1);" "o.x = inc;" @@ -2244,7 +2598,7 @@ THREADED_TEST(InterceptorCallICConstantFunctionNotNeededWrapped) { "test();" "%OptimizeFunctionOnNextCall(test);" "test()"); - CHECK_EQ(41, value->Int32Value()); + CHECK_EQ(41, value->Int32Value(context.local()).FromJust()); } @@ -2253,11 +2607,14 @@ THREADED_TEST(InterceptorCallICConstantFunctionNotNeededWrapped) { THREADED_TEST(InterceptorCallICInvalidatedConstantFunction) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); - v8::Handle<Value> value = CompileRun( + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + v8::Local<Value> value = CompileRun( "function inc(x) { return x + 1; };" "inc(1);" "proto1 = new Object();" @@ -2274,7 +2631,7 @@ THREADED_TEST(InterceptorCallICInvalidatedConstantFunction) { "for (var i = 0; i < 7; i++) {" " result += o.y(42);" "}"); - CHECK_EQ(41 * 7, value->Int32Value()); + CHECK_EQ(41 * 7, value->Int32Value(context.local()).FromJust()); } @@ -2284,11 +2641,14 @@ THREADED_TEST(InterceptorCallICInvalidatedConstantFunction) { THREADED_TEST(InterceptorCallICInvalidatedConstantFunctionViaGlobal) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); - v8::Handle<Value> value = CompileRun( + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + v8::Local<Value> value = CompileRun( "function inc(x) { return x + 1; };" "inc(1);" "o.__proto__ = this;" @@ -2302,7 +2662,7 @@ THREADED_TEST(InterceptorCallICInvalidatedConstantFunctionViaGlobal) { "for (var i = 0; i < 7; i++) {" " result += o.y(42);" "}"); - CHECK_EQ(41 * 7, value->Int32Value()); + CHECK_EQ(41 * 7, value->Int32Value(context.local()).FromJust()); } @@ -2310,13 +2670,16 @@ THREADED_TEST(InterceptorCallICInvalidatedConstantFunctionViaGlobal) { THREADED_TEST(InterceptorCallICCachedFromGlobal) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); LocalContext context; - context->Global()->Set(v8_str("o"), templ_o->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("o"), + templ_o->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); - v8::Handle<Value> value = CompileRun( + v8::Local<Value> value = CompileRun( "try {" " o.__proto__ = this;" " for (var i = 0; i < 10; i++) {" @@ -2332,16 +2695,18 @@ THREADED_TEST(InterceptorCallICCachedFromGlobal) { "} catch(e) {" " e" "};"); - CHECK_EQ(239 * 10, value->Int32Value()); + CHECK_EQ(239 * 10, value->Int32Value(context.local()).FromJust()); } -v8::Handle<Value> keyed_call_ic_function; +v8::Local<Value> keyed_call_ic_function; static void InterceptorKeyedCallICGetter( Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - if (v8_str("x")->Equals(name)) { + if (v8_str("x") + ->Equals(info.GetIsolate()->GetCurrentContext(), name) + .FromJust()) { info.GetReturnValue().Set(keyed_call_ic_function); } } @@ -2352,10 +2717,13 @@ static void InterceptorKeyedCallICGetter( THREADED_TEST(InterceptorKeyedCallICKeyChange1) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); CompileRun( "proto = new Object();" "proto.y = function(x) { return x + 1; };" @@ -2367,8 +2735,11 @@ THREADED_TEST(InterceptorKeyedCallICKeyChange1) { " if (i == 5) { method = 'z'; };" " result += o[method](41);" "}"); - CHECK_EQ(42 * 5 + 40 * 5, - context->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(42 * 5 + 40 * 5, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } @@ -2378,13 +2749,17 @@ THREADED_TEST(InterceptorKeyedCallICKeyChange1) { THREADED_TEST(InterceptorKeyedCallICKeyChange2) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorKeyedCallICGetter)); LocalContext context; - context->Global()->Set(v8_str("proto1"), templ->NewInstance()); - keyed_call_ic_function = - v8_compile("function f(x) { return x - 1; }; f")->Run(); + context->Global() + ->Set(context.local(), v8_str("proto1"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + keyed_call_ic_function = v8_compile("function f(x) { return x - 1; }; f") + ->Run(context.local()) + .ToLocalChecked(); CompileRun( "o = new Object();" "proto2 = new Object();" @@ -2398,8 +2773,11 @@ THREADED_TEST(InterceptorKeyedCallICKeyChange2) { " if (i == 5) { method = 'y'; };" " result += o[method](41);" "}"); - CHECK_EQ(42 * 5 + 40 * 5, - context->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(42 * 5 + 40 * 5, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } @@ -2408,10 +2786,13 @@ THREADED_TEST(InterceptorKeyedCallICKeyChange2) { THREADED_TEST(InterceptorKeyedCallICKeyChangeOnGlobal) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); CompileRun( "function inc(x) { return x + 1; };" "inc(1);" @@ -2426,8 +2807,11 @@ THREADED_TEST(InterceptorKeyedCallICKeyChangeOnGlobal) { " if (i == 5) { method = 'y'; };" " result += o[method](41);" "}"); - CHECK_EQ(42 * 5 + 40 * 5, - context->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(42 * 5 + 40 * 5, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } @@ -2435,10 +2819,13 @@ THREADED_TEST(InterceptorKeyedCallICKeyChangeOnGlobal) { THREADED_TEST(InterceptorKeyedCallICFromGlobal) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); LocalContext context; - context->Global()->Set(v8_str("o"), templ_o->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("o"), + templ_o->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); CompileRun( "function len(x) { return x.length; };" @@ -2452,8 +2839,16 @@ THREADED_TEST(InterceptorKeyedCallICFromGlobal) { " };" " result = o[m]('239');" "}"); - CHECK_EQ(3, context->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(239, context->Global()->Get(v8_str("saved_result"))->Int32Value()); + CHECK_EQ(3, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(239, context->Global() + ->Get(context.local(), v8_str("saved_result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } @@ -2461,10 +2856,13 @@ THREADED_TEST(InterceptorKeyedCallICFromGlobal) { THREADED_TEST(InterceptorKeyedCallICMapChangeBefore) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); LocalContext context; - context->Global()->Set(v8_str("proto"), templ_o->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("proto"), + templ_o->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var o = new Object();" @@ -2476,8 +2874,11 @@ THREADED_TEST(InterceptorKeyedCallICMapChangeBefore) { " if (i == 5) { o.method = function(x) { return x - 1; }; };" " result += o[m](41);" "}"); - CHECK_EQ(42 * 5 + 40 * 5, - context->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(42 * 5 + 40 * 5, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } @@ -2485,10 +2886,13 @@ THREADED_TEST(InterceptorKeyedCallICMapChangeBefore) { THREADED_TEST(InterceptorKeyedCallICMapChangeAfter) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); LocalContext context; - context->Global()->Set(v8_str("o"), templ_o->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("o"), + templ_o->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var proto = new Object();" @@ -2500,8 +2904,11 @@ THREADED_TEST(InterceptorKeyedCallICMapChangeAfter) { " if (i == 5) { proto.method = function(x) { return x - 1; }; };" " result += o[m](41);" "}"); - CHECK_EQ(42 * 5 + 40 * 5, - context->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(42 * 5 + 40 * 5, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } @@ -2510,7 +2917,10 @@ static int interceptor_call_count = 0; static void InterceptorICRefErrorGetter( Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - if (!is_bootstrapping && v8_str("x")->Equals(name) && + if (!is_bootstrapping && + v8_str("x") + ->Equals(info.GetIsolate()->GetCurrentContext(), name) + .FromJust() && interceptor_call_count++ < 20) { info.GetReturnValue().Set(call_ic_function2); } @@ -2523,14 +2933,16 @@ static void InterceptorICRefErrorGetter( THREADED_TEST(InterceptorICReferenceErrors) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorICRefErrorGetter)); is_bootstrapping = true; - LocalContext context(0, templ, v8::Handle<Value>()); + LocalContext context(0, templ, v8::Local<Value>()); is_bootstrapping = false; - call_ic_function2 = v8_compile("function h(x) { return x; }; h")->Run(); - v8::Handle<Value> value = CompileRun( + call_ic_function2 = v8_compile("function h(x) { return x; }; h") + ->Run(context.local()) + .ToLocalChecked(); + v8::Local<Value> value = CompileRun( "function f() {" " for (var i = 0; i < 1000; i++) {" " try { x; } catch(e) { return true; }" @@ -2538,7 +2950,7 @@ THREADED_TEST(InterceptorICReferenceErrors) { " return false;" "};" "f();"); - CHECK_EQ(true, value->BooleanValue()); + CHECK_EQ(true, value->BooleanValue(context.local()).FromJust()); interceptor_call_count = 0; value = CompileRun( "function g() {" @@ -2548,7 +2960,7 @@ THREADED_TEST(InterceptorICReferenceErrors) { " return false;" "};" "g();"); - CHECK_EQ(true, value->BooleanValue()); + CHECK_EQ(true, value->BooleanValue(context.local()).FromJust()); } @@ -2558,7 +2970,10 @@ static void InterceptorICExceptionGetter( Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); if (is_bootstrapping) return; - if (v8_str("x")->Equals(name) && ++interceptor_ic_exception_get_count < 20) { + if (v8_str("x") + ->Equals(info.GetIsolate()->GetCurrentContext(), name) + .FromJust() && + ++interceptor_ic_exception_get_count < 20) { info.GetReturnValue().Set(call_ic_function3); } if (interceptor_ic_exception_get_count == 20) { @@ -2574,14 +2989,16 @@ THREADED_TEST(InterceptorICGetterExceptions) { interceptor_ic_exception_get_count = 0; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorICExceptionGetter)); is_bootstrapping = true; - LocalContext context(0, templ, v8::Handle<Value>()); + LocalContext context(0, templ, v8::Local<Value>()); is_bootstrapping = false; - call_ic_function3 = v8_compile("function h(x) { return x; }; h")->Run(); - v8::Handle<Value> value = CompileRun( + call_ic_function3 = v8_compile("function h(x) { return x; }; h") + ->Run(context.local()) + .ToLocalChecked(); + v8::Local<Value> value = CompileRun( "function f() {" " for (var i = 0; i < 100; i++) {" " try { x; } catch(e) { return true; }" @@ -2589,7 +3006,7 @@ THREADED_TEST(InterceptorICGetterExceptions) { " return false;" "};" "f();"); - CHECK_EQ(true, value->BooleanValue()); + CHECK_EQ(true, value->BooleanValue(context.local()).FromJust()); interceptor_ic_exception_get_count = 0; value = CompileRun( "function f() {" @@ -2599,7 +3016,7 @@ THREADED_TEST(InterceptorICGetterExceptions) { " return false;" "};" "f();"); - CHECK_EQ(true, value->BooleanValue()); + CHECK_EQ(true, value->BooleanValue(context.local()).FromJust()); } @@ -2621,11 +3038,11 @@ THREADED_TEST(InterceptorICSetterExceptions) { interceptor_ic_exception_set_count = 0; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler( v8::NamedPropertyHandlerConfiguration(0, InterceptorICExceptionSetter)); - LocalContext context(0, templ, v8::Handle<Value>()); - v8::Handle<Value> value = CompileRun( + LocalContext context(0, templ, v8::Local<Value>()); + v8::Local<Value> value = CompileRun( "function f() {" " for (var i = 0; i < 100; i++) {" " try { x = 42; } catch(e) { return true; }" @@ -2633,7 +3050,7 @@ THREADED_TEST(InterceptorICSetterExceptions) { " return false;" "};" "f();"); - CHECK_EQ(true, value->BooleanValue()); + CHECK_EQ(true, value->BooleanValue(context.local()).FromJust()); } @@ -2641,16 +3058,17 @@ THREADED_TEST(InterceptorICSetterExceptions) { THREADED_TEST(NullNamedInterceptor) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration( static_cast<v8::GenericNamedPropertyGetterCallback>(0))); LocalContext context; templ->Set(CcTest::isolate(), "x", v8_num(42)); - v8::Handle<v8::Object> obj = templ->NewInstance(); - context->Global()->Set(v8_str("obj"), obj); - v8::Handle<Value> value = CompileRun("obj.x"); + v8::Local<v8::Object> obj = + templ->NewInstance(context.local()).ToLocalChecked(); + context->Global()->Set(context.local(), v8_str("obj"), obj).FromJust(); + v8::Local<Value> value = CompileRun("obj.x"); CHECK(value->IsInt32()); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(context.local()).FromJust()); } @@ -2658,27 +3076,33 @@ THREADED_TEST(NullNamedInterceptor) { THREADED_TEST(NullIndexedInterceptor) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::IndexedPropertyHandlerConfiguration( static_cast<v8::IndexedPropertyGetterCallback>(0))); LocalContext context; templ->Set(CcTest::isolate(), "42", v8_num(42)); - v8::Handle<v8::Object> obj = templ->NewInstance(); - context->Global()->Set(v8_str("obj"), obj); - v8::Handle<Value> value = CompileRun("obj[42]"); + v8::Local<v8::Object> obj = + templ->NewInstance(context.local()).ToLocalChecked(); + context->Global()->Set(context.local(), v8_str("obj"), obj).FromJust(); + v8::Local<Value> value = CompileRun("obj[42]"); CHECK(value->IsInt32()); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(context.local()).FromJust()); } THREADED_TEST(NamedPropertyHandlerGetterAttributes) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); + v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); templ->InstanceTemplate()->SetHandler( v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); LocalContext env; - env->Global()->Set(v8_str("obj"), templ->GetFunction()->NewInstance()); + env->Global() + ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked()) + .FromJust(); ExpectTrue("obj.x === 42"); ExpectTrue("!obj.propertyIsEnumerable('x')"); } @@ -2688,9 +3112,12 @@ THREADED_TEST(Regress256330) { i::FLAG_allow_natives_syntax = true; LocalContext context; v8::HandleScope scope(context->GetIsolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); + Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); - context->Global()->Set(v8_str("Bug"), templ->GetFunction()); + context->Global() + ->Set(context.local(), v8_str("Bug"), + templ->GetFunction(context.local()).ToLocalChecked()) + .FromJust(); CompileRun( "\"use strict\"; var o = new Bug;" "function f(o) { o.x = 10; };" @@ -2704,10 +3131,13 @@ THREADED_TEST(Regress256330) { THREADED_TEST(CrankshaftInterceptorSetter) { i::FLAG_allow_natives_syntax = true; v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Obj"), templ->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Obj"), + templ->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var obj = new Obj;" // Initialize fields to avoid transitions later. @@ -2731,10 +3161,13 @@ THREADED_TEST(CrankshaftInterceptorSetter) { THREADED_TEST(CrankshaftInterceptorGetter) { i::FLAG_allow_natives_syntax = true; v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Obj"), templ->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Obj"), + templ->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var obj = new Obj;" // Initialize fields to avoid transitions later. @@ -2755,10 +3188,13 @@ THREADED_TEST(CrankshaftInterceptorGetter) { THREADED_TEST(CrankshaftInterceptorFieldRead) { i::FLAG_allow_natives_syntax = true; v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Obj"), templ->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Obj"), + templ->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var obj = new Obj;" "obj.__proto__.interceptor_age = 42;" @@ -2776,10 +3212,13 @@ THREADED_TEST(CrankshaftInterceptorFieldRead) { THREADED_TEST(CrankshaftInterceptorFieldWrite) { i::FLAG_allow_natives_syntax = true; v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(templ, InterceptorGetter, InterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Obj"), templ->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Obj"), + templ->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var obj = new Obj;" "obj.age = 100000;" @@ -2797,19 +3236,25 @@ THREADED_TEST(CrankshaftInterceptorFieldWrite) { THREADED_TEST(Regress149912) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - Handle<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); + Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); - context->Global()->Set(v8_str("Bug"), templ->GetFunction()); + context->Global() + ->Set(context.local(), v8_str("Bug"), + templ->GetFunction(context.local()).ToLocalChecked()) + .FromJust(); CompileRun("Number.prototype.__proto__ = new Bug; var x = 0; x.foo();"); } THREADED_TEST(Regress125988) { v8::HandleScope scope(CcTest::isolate()); - Handle<FunctionTemplate> intercept = FunctionTemplate::New(CcTest::isolate()); + Local<FunctionTemplate> intercept = FunctionTemplate::New(CcTest::isolate()); AddInterceptor(intercept, EmptyInterceptorGetter, EmptyInterceptorSetter); LocalContext env; - env->Global()->Set(v8_str("Intercept"), intercept->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("Intercept"), + intercept->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); CompileRun( "var a = new Object();" "var b = new Intercept();" @@ -2832,17 +3277,21 @@ THREADED_TEST(Regress125988) { static void IndexedPropertyEnumerator( const v8::PropertyCallbackInfo<v8::Array>& info) { - v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 1); - result->Set(0, v8::Integer::New(info.GetIsolate(), 7)); + v8::Local<v8::Array> result = v8::Array::New(info.GetIsolate(), 1); + result->Set(info.GetIsolate()->GetCurrentContext(), 0, + v8::Integer::New(info.GetIsolate(), 7)) + .FromJust(); info.GetReturnValue().Set(result); } static void NamedPropertyEnumerator( const v8::PropertyCallbackInfo<v8::Array>& info) { - v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2); - result->Set(0, v8_str("x")); - result->Set(1, v8::Symbol::GetIterator(info.GetIsolate())); + v8::Local<v8::Array> result = v8::Array::New(info.GetIsolate(), 2); + v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); + result->Set(context, 0, v8_str("x")).FromJust(); + result->Set(context, 1, v8::Symbol::GetIterator(info.GetIsolate())) + .FromJust(); info.GetReturnValue().Set(result); } @@ -2850,8 +3299,7 @@ static void NamedPropertyEnumerator( THREADED_TEST(GetOwnPropertyNamesWithInterceptor) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> obj_template = - v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(isolate); obj_template->Set(v8_str("7"), v8::Integer::New(CcTest::isolate(), 7)); obj_template->Set(v8_str("x"), v8::Integer::New(CcTest::isolate(), 42)); @@ -2861,33 +3309,50 @@ THREADED_TEST(GetOwnPropertyNamesWithInterceptor) { NULL, NULL, NULL, NULL, NamedPropertyEnumerator)); LocalContext context; - v8::Handle<v8::Object> global = context->Global(); - global->Set(v8_str("object"), obj_template->NewInstance()); + v8::Local<v8::Object> global = context->Global(); + global->Set(context.local(), v8_str("object"), + obj_template->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); - v8::Handle<v8::Value> result = + v8::Local<v8::Value> result = CompileRun("Object.getOwnPropertyNames(object)"); CHECK(result->IsArray()); - v8::Handle<v8::Array> result_array = v8::Handle<v8::Array>::Cast(result); + v8::Local<v8::Array> result_array = v8::Local<v8::Array>::Cast(result); CHECK_EQ(2u, result_array->Length()); - CHECK(result_array->Get(0)->IsString()); - CHECK(result_array->Get(1)->IsString()); - CHECK(v8_str("7")->Equals(result_array->Get(0))); - CHECK(v8_str("x")->Equals(result_array->Get(1))); + CHECK(result_array->Get(context.local(), 0).ToLocalChecked()->IsString()); + CHECK(result_array->Get(context.local(), 1).ToLocalChecked()->IsString()); + CHECK(v8_str("7") + ->Equals(context.local(), + result_array->Get(context.local(), 0).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("x") + ->Equals(context.local(), + result_array->Get(context.local(), 1).ToLocalChecked()) + .FromJust()); result = CompileRun("var ret = []; for (var k in object) ret.push(k); ret"); CHECK(result->IsArray()); - result_array = v8::Handle<v8::Array>::Cast(result); + result_array = v8::Local<v8::Array>::Cast(result); CHECK_EQ(2u, result_array->Length()); - CHECK(result_array->Get(0)->IsString()); - CHECK(result_array->Get(1)->IsString()); - CHECK(v8_str("7")->Equals(result_array->Get(0))); - CHECK(v8_str("x")->Equals(result_array->Get(1))); + CHECK(result_array->Get(context.local(), 0).ToLocalChecked()->IsString()); + CHECK(result_array->Get(context.local(), 1).ToLocalChecked()->IsString()); + CHECK(v8_str("7") + ->Equals(context.local(), + result_array->Get(context.local(), 0).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("x") + ->Equals(context.local(), + result_array->Get(context.local(), 1).ToLocalChecked()) + .FromJust()); result = CompileRun("Object.getOwnPropertySymbols(object)"); CHECK(result->IsArray()); - result_array = v8::Handle<v8::Array>::Cast(result); + result_array = v8::Local<v8::Array>::Cast(result); CHECK_EQ(1u, result_array->Length()); - CHECK(result_array->Get(0)->Equals(v8::Symbol::GetIterator(isolate))); + CHECK(result_array->Get(context.local(), 0) + .ToLocalChecked() + ->Equals(context.local(), v8::Symbol::GetIterator(isolate)) + .FromJust()); } @@ -2900,8 +3365,7 @@ static void IndexedPropertyEnumeratorException( THREADED_TEST(GetOwnPropertyNamesWithIndexedInterceptorExceptions_regress4026) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> obj_template = - v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(isolate); obj_template->Set(v8_str("7"), v8::Integer::New(CcTest::isolate(), 7)); obj_template->Set(v8_str("x"), v8::Integer::New(CcTest::isolate(), 42)); @@ -2910,9 +3374,11 @@ THREADED_TEST(GetOwnPropertyNamesWithIndexedInterceptorExceptions_regress4026) { NULL, NULL, NULL, NULL, IndexedPropertyEnumeratorException)); LocalContext context; - v8::Handle<v8::Object> global = context->Global(); - global->Set(v8_str("object"), obj_template->NewInstance()); - v8::Handle<v8::Value> result = CompileRun( + v8::Local<v8::Object> global = context->Global(); + global->Set(context.local(), v8_str("object"), + obj_template->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + v8::Local<v8::Value> result = CompileRun( "var result = []; " "try { " " for (var k in object) result .push(k);" @@ -2921,7 +3387,7 @@ THREADED_TEST(GetOwnPropertyNamesWithIndexedInterceptorExceptions_regress4026) { "}" "result "); CHECK(!result->IsArray()); - CHECK(v8_num(42)->Equals(result)); + CHECK(v8_num(42)->Equals(context.local(), result).FromJust()); result = CompileRun( "var result = [];" @@ -2932,7 +3398,7 @@ THREADED_TEST(GetOwnPropertyNamesWithIndexedInterceptorExceptions_regress4026) { "}" "result"); CHECK(!result->IsArray()); - CHECK(v8_num(42)->Equals(result)); + CHECK(v8_num(42)->Equals(context.local(), result).FromJust()); } @@ -2945,8 +3411,7 @@ static void NamedPropertyEnumeratorException( THREADED_TEST(GetOwnPropertyNamesWithNamedInterceptorExceptions_regress4026) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> obj_template = - v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(isolate); obj_template->Set(v8_str("7"), v8::Integer::New(CcTest::isolate(), 7)); obj_template->Set(v8_str("x"), v8::Integer::New(CcTest::isolate(), 42)); @@ -2955,10 +3420,12 @@ THREADED_TEST(GetOwnPropertyNamesWithNamedInterceptorExceptions_regress4026) { NULL, NULL, NULL, NULL, NamedPropertyEnumeratorException)); LocalContext context; - v8::Handle<v8::Object> global = context->Global(); - global->Set(v8_str("object"), obj_template->NewInstance()); + v8::Local<v8::Object> global = context->Global(); + global->Set(context.local(), v8_str("object"), + obj_template->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); - v8::Handle<v8::Value> result = CompileRun( + v8::Local<v8::Value> result = CompileRun( "var result = []; " "try { " " for (var k in object) result.push(k);" @@ -2967,7 +3434,7 @@ THREADED_TEST(GetOwnPropertyNamesWithNamedInterceptorExceptions_regress4026) { "}" "result"); CHECK(!result->IsArray()); - CHECK(v8_num(43)->Equals(result)); + CHECK(v8_num(43)->Equals(context.local(), result).FromJust()); result = CompileRun( "var result = [];" @@ -2978,7 +3445,7 @@ THREADED_TEST(GetOwnPropertyNamesWithNamedInterceptorExceptions_regress4026) { "}" "result"); CHECK(!result->IsArray()); - CHECK(v8_num(43)->Equals(result)); + CHECK(v8_num(43)->Equals(context.local(), result).FromJust()); } namespace { @@ -2987,7 +3454,8 @@ template <typename T> Local<Object> BuildWrappedObject(v8::Isolate* isolate, T* data) { auto templ = v8::ObjectTemplate::New(isolate); templ->SetInternalFieldCount(1); - auto instance = templ->NewInstance(); + auto instance = + templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); instance->SetAlignedPointerInInternalField(0, data); return instance; } @@ -3083,11 +3551,21 @@ TEST(NamedAllCanReadInterceptor) { auto checked = v8::ObjectTemplate::New(isolate); checked->SetAccessCheckCallback(SimpleAccessChecker); - context->Global()->Set(v8_str("intercepted_0"), intercepted_0->NewInstance()); - context->Global()->Set(v8_str("intercepted_1"), intercepted_1->NewInstance()); - auto checked_instance = checked->NewInstance(); - checked_instance->Set(v8_str("whatever"), v8_num(17)); - context->Global()->Set(v8_str("checked"), checked_instance); + context->Global() + ->Set(context.local(), v8_str("intercepted_0"), + intercepted_0->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + context->Global() + ->Set(context.local(), v8_str("intercepted_1"), + intercepted_1->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + auto checked_instance = + checked->NewInstance(context.local()).ToLocalChecked(); + checked_instance->Set(context.local(), v8_str("whatever"), v8_num(17)) + .FromJust(); + context->Global() + ->Set(context.local(), v8_str("checked"), checked_instance) + .FromJust(); CompileRun( "checked.__proto__ = intercepted_1;" "intercepted_1.__proto__ = intercepted_0;"); @@ -3160,11 +3638,20 @@ TEST(IndexedAllCanReadInterceptor) { auto checked = v8::ObjectTemplate::New(isolate); checked->SetAccessCheckCallback(SimpleAccessChecker); - context->Global()->Set(v8_str("intercepted_0"), intercepted_0->NewInstance()); - context->Global()->Set(v8_str("intercepted_1"), intercepted_1->NewInstance()); - auto checked_instance = checked->NewInstance(); - context->Global()->Set(v8_str("checked"), checked_instance); - checked_instance->Set(15, v8_num(17)); + context->Global() + ->Set(context.local(), v8_str("intercepted_0"), + intercepted_0->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + context->Global() + ->Set(context.local(), v8_str("intercepted_1"), + intercepted_1->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + auto checked_instance = + checked->NewInstance(context.local()).ToLocalChecked(); + context->Global() + ->Set(context.local(), v8_str("checked"), checked_instance) + .FromJust(); + checked_instance->Set(context.local(), 15, v8_num(17)).FromJust(); CompileRun( "checked.__proto__ = intercepted_1;" "intercepted_1.__proto__ = intercepted_0;"); @@ -3214,8 +3701,11 @@ THREADED_TEST(NonMaskingInterceptorOwnProperty) { conf.data = BuildWrappedObject<ShouldInterceptData>(isolate, &intercept_data); interceptor_templ->SetHandler(conf); - auto interceptor = interceptor_templ->NewInstance(); - context->Global()->Set(v8_str("obj"), interceptor); + auto interceptor = + interceptor_templ->NewInstance(context.local()).ToLocalChecked(); + context->Global() + ->Set(context.local(), v8_str("obj"), interceptor) + .FromJust(); ExpectInt32("obj.whatever", 239); @@ -3242,8 +3732,11 @@ THREADED_TEST(NonMaskingInterceptorPrototypeProperty) { conf.data = BuildWrappedObject<ShouldInterceptData>(isolate, &intercept_data); interceptor_templ->SetHandler(conf); - auto interceptor = interceptor_templ->NewInstance(); - context->Global()->Set(v8_str("obj"), interceptor); + auto interceptor = + interceptor_templ->NewInstance(context.local()).ToLocalChecked(); + context->Global() + ->Set(context.local(), v8_str("obj"), interceptor) + .FromJust(); ExpectInt32("obj.whatever", 239); @@ -3270,8 +3763,11 @@ THREADED_TEST(NonMaskingInterceptorPrototypePropertyIC) { conf.data = BuildWrappedObject<ShouldInterceptData>(isolate, &intercept_data); interceptor_templ->SetHandler(conf); - auto interceptor = interceptor_templ->NewInstance(); - context->Global()->Set(v8_str("obj"), interceptor); + auto interceptor = + interceptor_templ->NewInstance(context.local()).ToLocalChecked(); + context->Global() + ->Set(context.local(), v8_str("obj"), interceptor) + .FromJust(); CompileRun( "outer = {};" @@ -3345,7 +3841,7 @@ void DatabaseSetter(Local<Name> name, Local<Value> value, const v8::PropertyCallbackInfo<Value>& info) { ApiTestFuzzer::Fuzz(); auto context = info.GetIsolate()->GetCurrentContext(); - if (name->Equals(v8_str("db"))) return; + if (name->Equals(context, v8_str("db")).FromJust()) return; Local<v8::Object> db = info.Holder() ->GetRealNamedProperty(context, v8_str("db")) .ToLocalChecked() @@ -3367,10 +3863,14 @@ THREADED_TEST(NonMaskingInterceptorGlobalEvalRegression) { conf.flags = v8::PropertyHandlerFlags::kNonMasking; interceptor_templ->SetHandler(conf); - context->Global()->Set(v8_str("intercepted_1"), - interceptor_templ->NewInstance()); - context->Global()->Set(v8_str("intercepted_2"), - interceptor_templ->NewInstance()); + context->Global() + ->Set(context.local(), v8_str("intercepted_1"), + interceptor_templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); + context->Global() + ->Set(context.local(), v8_str("intercepted_2"), + interceptor_templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust(); // Init dbs. CompileRun( diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index aa2863638c..ca3f446a41 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -46,11 +46,12 @@ #include "src/execution.h" #include "src/futex-emulation.h" #include "src/objects.h" -#include "src/parser.h" +#include "src/parsing/parser.h" #include "src/unicode-inl.h" #include "src/utils.h" #include "src/vm-state.h" -#include "test/cctest/heap-tester.h" +#include "test/cctest/heap/heap-tester.h" +#include "test/cctest/heap/utils-inl.h" static const bool kLogThreading = false; @@ -60,7 +61,6 @@ using ::v8::Context; using ::v8::Extension; using ::v8::Function; using ::v8::FunctionTemplate; -using ::v8::Handle; using ::v8::HandleScope; using ::v8::Local; using ::v8::Maybe; @@ -94,8 +94,7 @@ using ::v8::Value; void RunWithProfiler(void (*test)()) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Local<v8::String> profile_name = - v8::String::NewFromUtf8(env->GetIsolate(), "my_profile1"); + v8::Local<v8::String> profile_name = v8_str("my_profile1"); v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); cpu_profiler->StartProfiling(profile_name); @@ -110,12 +109,21 @@ static void IncrementingSignatureCallback( const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); signature_callback_count++; - CHECK(signature_expected_receiver->Equals(args.Holder())); - CHECK(signature_expected_receiver->Equals(args.This())); - v8::Handle<v8::Array> result = + CHECK(signature_expected_receiver->Equals( + args.GetIsolate()->GetCurrentContext(), + args.Holder()) + .FromJust()); + CHECK(signature_expected_receiver->Equals( + args.GetIsolate()->GetCurrentContext(), + args.This()) + .FromJust()); + v8::Local<v8::Array> result = v8::Array::New(args.GetIsolate(), args.Length()); - for (int i = 0; i < args.Length(); i++) - result->Set(v8::Integer::New(args.GetIsolate(), i), args[i]); + for (int i = 0; i < args.Length(); i++) { + CHECK(result->Set(args.GetIsolate()->GetCurrentContext(), + v8::Integer::New(args.GetIsolate(), i), args[i]) + .FromJust()); + } args.GetReturnValue().Set(result); } @@ -154,13 +162,13 @@ THREADED_TEST(Handles) { CHECK(!local_env.IsEmpty()); local_env->Enter(); - v8::Handle<v8::Primitive> undef = v8::Undefined(CcTest::isolate()); + v8::Local<v8::Primitive> undef = v8::Undefined(CcTest::isolate()); CHECK(!undef.IsEmpty()); CHECK(undef->IsUndefined()); const char* source = "1 + 2 + 3"; Local<Script> script = v8_compile(source); - CHECK_EQ(6, script->Run()->Int32Value()); + CHECK_EQ(6, v8_run_int32value(script)); local_env->Exit(); } @@ -168,7 +176,7 @@ THREADED_TEST(Handles) { THREADED_TEST(IsolateOfContext) { v8::HandleScope scope(CcTest::isolate()); - v8::Handle<Context> env = Context::New(CcTest::isolate()); + v8::Local<Context> env = Context::New(CcTest::isolate()); CHECK(!env->GetIsolate()->InContext()); CHECK(env->GetIsolate() == CcTest::isolate()); @@ -199,7 +207,11 @@ static void TestSignature(const char* loop_js, Local<Value> receiver, CHECK_EQ(10, signature_callback_count); } else { CHECK(v8_str("TypeError: Illegal invocation") - ->Equals(try_catch.Exception()->ToString(isolate))); + ->Equals(isolate->GetCurrentContext(), + try_catch.Exception() + ->ToString(isolate->GetCurrentContext()) + .ToLocalChecked()) + .FromJust()); } } @@ -209,32 +221,43 @@ THREADED_TEST(ReceiverSignature) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); // Setup templates. - v8::Handle<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::Signature> sig = v8::Signature::New(isolate, fun); - v8::Handle<v8::FunctionTemplate> callback_sig = - v8::FunctionTemplate::New( - isolate, IncrementingSignatureCallback, Local<Value>(), sig); - v8::Handle<v8::FunctionTemplate> callback = + v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate); + v8::Local<v8::Signature> sig = v8::Signature::New(isolate, fun); + v8::Local<v8::FunctionTemplate> callback_sig = v8::FunctionTemplate::New( + isolate, IncrementingSignatureCallback, Local<Value>(), sig); + v8::Local<v8::FunctionTemplate> callback = v8::FunctionTemplate::New(isolate, IncrementingSignatureCallback); - v8::Handle<v8::FunctionTemplate> sub_fun = v8::FunctionTemplate::New(isolate); + v8::Local<v8::FunctionTemplate> sub_fun = v8::FunctionTemplate::New(isolate); sub_fun->Inherit(fun); - v8::Handle<v8::FunctionTemplate> unrel_fun = + v8::Local<v8::FunctionTemplate> unrel_fun = v8::FunctionTemplate::New(isolate); // Install properties. - v8::Handle<v8::ObjectTemplate> fun_proto = fun->PrototypeTemplate(); + v8::Local<v8::ObjectTemplate> fun_proto = fun->PrototypeTemplate(); fun_proto->Set(v8_str("prop_sig"), callback_sig); fun_proto->Set(v8_str("prop"), callback); fun_proto->SetAccessorProperty( v8_str("accessor_sig"), callback_sig, callback_sig); fun_proto->SetAccessorProperty(v8_str("accessor"), callback, callback); // Instantiate templates. - Local<Value> fun_instance = fun->InstanceTemplate()->NewInstance(); - Local<Value> sub_fun_instance = sub_fun->InstanceTemplate()->NewInstance(); + Local<Value> fun_instance = + fun->InstanceTemplate()->NewInstance(env.local()).ToLocalChecked(); + Local<Value> sub_fun_instance = + sub_fun->InstanceTemplate()->NewInstance(env.local()).ToLocalChecked(); // Setup global variables. - env->Global()->Set(v8_str("Fun"), fun->GetFunction()); - env->Global()->Set(v8_str("UnrelFun"), unrel_fun->GetFunction()); - env->Global()->Set(v8_str("fun_instance"), fun_instance); - env->Global()->Set(v8_str("sub_fun_instance"), sub_fun_instance); + CHECK(env->Global() + ->Set(env.local(), v8_str("Fun"), + fun->GetFunction(env.local()).ToLocalChecked()) + .FromJust()); + CHECK(env->Global() + ->Set(env.local(), v8_str("UnrelFun"), + unrel_fun->GetFunction(env.local()).ToLocalChecked()) + .FromJust()); + CHECK(env->Global() + ->Set(env.local(), v8_str("fun_instance"), fun_instance) + .FromJust()); + CHECK(env->Global() + ->Set(env.local(), v8_str("sub_fun_instance"), sub_fun_instance) + .FromJust()); CompileRun( "var accessor_sig_key = 'accessor_sig';" "var accessor_key = 'accessor';" @@ -283,8 +306,8 @@ THREADED_TEST(HulIgennem) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::Primitive> undef = v8::Undefined(isolate); - Local<String> undef_str = undef->ToString(isolate); + v8::Local<v8::Primitive> undef = v8::Undefined(isolate); + Local<String> undef_str = undef->ToString(env.local()).ToLocalChecked(); char* value = i::NewArray<char>(undef_str->Utf8Length() + 1); undef_str->WriteUtf8(value); CHECK_EQ(0, strcmp(value, "undefined")); @@ -297,14 +320,16 @@ THREADED_TEST(Access) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); Local<v8::Object> obj = v8::Object::New(isolate); - Local<Value> foo_before = obj->Get(v8_str("foo")); + Local<Value> foo_before = + obj->Get(env.local(), v8_str("foo")).ToLocalChecked(); CHECK(foo_before->IsUndefined()); Local<String> bar_str = v8_str("bar"); - obj->Set(v8_str("foo"), bar_str); - Local<Value> foo_after = obj->Get(v8_str("foo")); + CHECK(obj->Set(env.local(), v8_str("foo"), bar_str).FromJust()); + Local<Value> foo_after = + obj->Get(env.local(), v8_str("foo")).ToLocalChecked(); CHECK(!foo_after->IsUndefined()); CHECK(foo_after->IsString()); - CHECK(bar_str->Equals(foo_after)); + CHECK(bar_str->Equals(env.local(), foo_after).FromJust()); } @@ -312,18 +337,22 @@ THREADED_TEST(AccessElement) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); Local<v8::Object> obj = v8::Object::New(env->GetIsolate()); - Local<Value> before = obj->Get(1); + Local<Value> before = obj->Get(env.local(), 1).ToLocalChecked(); CHECK(before->IsUndefined()); Local<String> bar_str = v8_str("bar"); - obj->Set(1, bar_str); - Local<Value> after = obj->Get(1); + CHECK(obj->Set(env.local(), 1, bar_str).FromJust()); + Local<Value> after = obj->Get(env.local(), 1).ToLocalChecked(); CHECK(!after->IsUndefined()); CHECK(after->IsString()); - CHECK(bar_str->Equals(after)); + CHECK(bar_str->Equals(env.local(), after).FromJust()); Local<v8::Array> value = CompileRun("[\"a\", \"b\"]").As<v8::Array>(); - CHECK(v8_str("a")->Equals(value->Get(0))); - CHECK(v8_str("b")->Equals(value->Get(1))); + CHECK(v8_str("a") + ->Equals(env.local(), value->Get(env.local(), 0).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("b") + ->Equals(env.local(), value->Get(env.local(), 1).ToLocalChecked()) + .FromJust()); } @@ -332,7 +361,7 @@ THREADED_TEST(Script) { v8::HandleScope scope(env->GetIsolate()); const char* source = "1 + 2 + 3"; Local<Script> script = v8_compile(source); - CHECK_EQ(6, script->Run()->Int32Value()); + CHECK_EQ(6, v8_run_int32value(script)); } @@ -403,11 +432,13 @@ THREADED_TEST(ScriptUsingStringResource) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); TestResource* resource = new TestResource(two_byte_source, &dispose_count); - Local<String> source = String::NewExternal(env->GetIsolate(), resource); + Local<String> source = + String::NewExternalTwoByte(env->GetIsolate(), resource) + .ToLocalChecked(); Local<Script> script = v8_compile(source); - Local<Value> value = script->Run(); + Local<Value> value = script->Run(env.local()).ToLocalChecked(); CHECK(value->IsNumber()); - CHECK_EQ(7, value->Int32Value()); + CHECK_EQ(7, value->Int32Value(env.local()).FromJust()); CHECK(source->IsExternal()); CHECK_EQ(resource, static_cast<TestResource*>(source->GetExternalStringResource())); @@ -432,7 +463,9 @@ THREADED_TEST(ScriptUsingOneByteStringResource) { v8::HandleScope scope(env->GetIsolate()); TestOneByteResource* resource = new TestOneByteResource(i::StrDup(c_source), &dispose_count); - Local<String> source = String::NewExternal(env->GetIsolate(), resource); + Local<String> source = + String::NewExternalOneByte(env->GetIsolate(), resource) + .ToLocalChecked(); CHECK(source->IsExternalOneByte()); CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource), source->GetExternalOneByteStringResource()); @@ -441,9 +474,9 @@ THREADED_TEST(ScriptUsingOneByteStringResource) { source->GetExternalStringResourceBase(&encoding)); CHECK_EQ(String::ONE_BYTE_ENCODING, encoding); Local<Script> script = v8_compile(source); - Local<Value> value = script->Run(); + Local<Value> value = script->Run(env.local()).ToLocalChecked(); CHECK(value->IsNumber()); - CHECK_EQ(7, value->Int32Value()); + CHECK_EQ(7, value->Int32Value(env.local()).FromJust()); CcTest::heap()->CollectAllGarbage(); CHECK_EQ(0, dispose_count); } @@ -460,7 +493,9 @@ THREADED_TEST(ScriptMakingExternalString) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); Local<String> source = - String::NewFromTwoByte(env->GetIsolate(), two_byte_source); + String::NewFromTwoByte(env->GetIsolate(), two_byte_source, + v8::NewStringType::kNormal) + .ToLocalChecked(); // Trigger GCs so that the newly allocated string moves to old gen. CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now @@ -473,9 +508,9 @@ THREADED_TEST(ScriptMakingExternalString) { &dispose_count)); CHECK(success); Local<Script> script = v8_compile(source); - Local<Value> value = script->Run(); + Local<Value> value = script->Run(env.local()).ToLocalChecked(); CHECK(value->IsNumber()); - CHECK_EQ(7, value->Int32Value()); + CHECK_EQ(7, value->Int32Value(env.local()).FromJust()); CcTest::heap()->CollectAllGarbage(); CHECK_EQ(0, dispose_count); } @@ -499,9 +534,9 @@ THREADED_TEST(ScriptMakingExternalOneByteString) { new TestOneByteResource(i::StrDup(c_source), &dispose_count)); CHECK(success); Local<Script> script = v8_compile(source); - Local<Value> value = script->Run(); + Local<Value> value = script->Run(env.local()).ToLocalChecked(); CHECK(value->IsNumber()); - CHECK_EQ(7, value->Int32Value()); + CHECK_EQ(7, value->Int32Value(env.local()).FromJust()); CcTest::heap()->CollectAllGarbage(); CHECK_EQ(0, dispose_count); } @@ -521,7 +556,9 @@ TEST(MakingExternalStringConditions) { uint16_t* two_byte_string = AsciiToTwoByteString("s1"); Local<String> small_string = - String::NewFromTwoByte(env->GetIsolate(), two_byte_string); + String::NewFromTwoByte(env->GetIsolate(), two_byte_string, + v8::NewStringType::kNormal) + .ToLocalChecked(); i::DeleteArray(two_byte_string); // We should refuse to externalize small strings. @@ -533,7 +570,9 @@ TEST(MakingExternalStringConditions) { CHECK(small_string->CanMakeExternal()); two_byte_string = AsciiToTwoByteString("small string 2"); - small_string = String::NewFromTwoByte(env->GetIsolate(), two_byte_string); + small_string = String::NewFromTwoByte(env->GetIsolate(), two_byte_string, + v8::NewStringType::kNormal) + .ToLocalChecked(); i::DeleteArray(two_byte_string); const int buf_size = 10 * 1024; @@ -543,7 +582,9 @@ TEST(MakingExternalStringConditions) { two_byte_string = AsciiToTwoByteString(buf); Local<String> large_string = - String::NewFromTwoByte(env->GetIsolate(), two_byte_string); + String::NewFromTwoByte(env->GetIsolate(), two_byte_string, + v8::NewStringType::kNormal) + .ToLocalChecked(); i::DeleteArray(buf); i::DeleteArray(two_byte_string); // Large strings should be immediately accepted. @@ -559,7 +600,7 @@ TEST(MakingExternalOneByteStringConditions) { CcTest::heap()->CollectGarbage(i::NEW_SPACE); CcTest::heap()->CollectGarbage(i::NEW_SPACE); - Local<String> small_string = String::NewFromUtf8(env->GetIsolate(), "s1"); + Local<String> small_string = v8_str("s1"); // We should refuse to externalize small strings. CHECK(!small_string->CanMakeExternal()); // Trigger GCs so that the newly allocated string moves to old gen. @@ -572,7 +613,7 @@ TEST(MakingExternalOneByteStringConditions) { char* buf = i::NewArray<char>(buf_size); memset(buf, 'a', buf_size); buf[buf_size - 1] = '\0'; - Local<String> large_string = String::NewFromUtf8(env->GetIsolate(), buf); + Local<String> large_string = v8_str(buf); i::DeleteArray(buf); // Large strings should be immediately accepted. CHECK(large_string->CanMakeExternal()); @@ -618,8 +659,10 @@ THREADED_TEST(UsingExternalString) { { v8::HandleScope scope(CcTest::isolate()); uint16_t* two_byte_string = AsciiToTwoByteString("test string"); - Local<String> string = String::NewExternal( - CcTest::isolate(), new TestResource(two_byte_string)); + Local<String> string = + String::NewExternalTwoByte(CcTest::isolate(), + new TestResource(two_byte_string)) + .ToLocalChecked(); i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); // Trigger GCs so that the newly allocated string moves to old gen. CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now @@ -638,8 +681,11 @@ THREADED_TEST(UsingExternalOneByteString) { { v8::HandleScope scope(CcTest::isolate()); const char* one_byte_string = "test string"; - Local<String> string = String::NewExternal( - CcTest::isolate(), new TestOneByteResource(i::StrDup(one_byte_string))); + Local<String> string = + String::NewExternalOneByte( + CcTest::isolate(), + new TestOneByteResource(i::StrDup(one_byte_string))) + .ToLocalChecked(); i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); // Trigger GCs so that the newly allocated string moves to old gen. CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now @@ -684,8 +730,9 @@ THREADED_TEST(NewExternalForVeryLongString) { v8::HandleScope scope(isolate); v8::TryCatch try_catch(isolate); RandomLengthOneByteResource r(1 << 30); - v8::Local<v8::String> str = v8::String::NewExternal(isolate, &r); - CHECK(str.IsEmpty()); + v8::MaybeLocal<v8::String> maybe_str = + v8::String::NewExternalOneByte(isolate, &r); + CHECK(maybe_str.IsEmpty()); CHECK(!try_catch.HasCaught()); } @@ -693,8 +740,9 @@ THREADED_TEST(NewExternalForVeryLongString) { v8::HandleScope scope(isolate); v8::TryCatch try_catch(isolate); RandomLengthResource r(1 << 30); - v8::Local<v8::String> str = v8::String::NewExternal(isolate, &r); - CHECK(str.IsEmpty()); + v8::MaybeLocal<v8::String> maybe_str = + v8::String::NewExternalTwoByte(isolate, &r); + CHECK(maybe_str.IsEmpty()); CHECK(!try_catch.HasCaught()); } } @@ -708,8 +756,11 @@ THREADED_TEST(ScavengeExternalString) { { v8::HandleScope scope(CcTest::isolate()); uint16_t* two_byte_string = AsciiToTwoByteString("test string"); - Local<String> string = String::NewExternal( - CcTest::isolate(), new TestResource(two_byte_string, &dispose_count)); + Local<String> string = + String::NewExternalTwoByte( + CcTest::isolate(), + new TestResource(two_byte_string, &dispose_count)) + .ToLocalChecked(); i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); CcTest::heap()->CollectGarbage(i::NEW_SPACE); in_new_space = CcTest::heap()->InNewSpace(*istring); @@ -729,9 +780,11 @@ THREADED_TEST(ScavengeExternalOneByteString) { { v8::HandleScope scope(CcTest::isolate()); const char* one_byte_string = "test string"; - Local<String> string = String::NewExternal( - CcTest::isolate(), - new TestOneByteResource(i::StrDup(one_byte_string), &dispose_count)); + Local<String> string = + String::NewExternalOneByte( + CcTest::isolate(), + new TestOneByteResource(i::StrDup(one_byte_string), &dispose_count)) + .ToLocalChecked(); i::Handle<i::String> istring = v8::Utils::OpenHandle(*string); CcTest::heap()->CollectGarbage(i::NEW_SPACE); in_new_space = CcTest::heap()->InNewSpace(*istring); @@ -775,11 +828,13 @@ TEST(ExternalStringWithDisposeHandling) { { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - Local<String> source = String::NewExternal(env->GetIsolate(), &res_stack); + Local<String> source = + String::NewExternalOneByte(env->GetIsolate(), &res_stack) + .ToLocalChecked(); Local<Script> script = v8_compile(source); - Local<Value> value = script->Run(); + Local<Value> value = script->Run(env.local()).ToLocalChecked(); CHECK(value->IsNumber()); - CHECK_EQ(7, value->Int32Value()); + CHECK_EQ(7, value->Int32Value(env.local()).FromJust()); CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, TestOneByteResourceWithDisposeControl::dispose_count); } @@ -796,11 +851,13 @@ TEST(ExternalStringWithDisposeHandling) { { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - Local<String> source = String::NewExternal(env->GetIsolate(), res_heap); + Local<String> source = + String::NewExternalOneByte(env->GetIsolate(), res_heap) + .ToLocalChecked(); Local<Script> script = v8_compile(source); - Local<Value> value = script->Run(); + Local<Value> value = script->Run(env.local()).ToLocalChecked(); CHECK(value->IsNumber()); - CHECK_EQ(7, value->Int32Value()); + CHECK_EQ(7, value->Int32Value(env.local()).FromJust()); CcTest::heap()->CollectAllAvailableGarbage(); CHECK_EQ(0, TestOneByteResourceWithDisposeControl::dispose_count); } @@ -826,34 +883,41 @@ THREADED_TEST(StringConcat) { uint16_t* two_byte_source = AsciiToTwoByteString(two_byte_string_1); Local<String> right = - String::NewFromTwoByte(env->GetIsolate(), two_byte_source); + String::NewFromTwoByte(env->GetIsolate(), two_byte_source, + v8::NewStringType::kNormal) + .ToLocalChecked(); i::DeleteArray(two_byte_source); Local<String> source = String::Concat(left, right); - right = String::NewExternal( - env->GetIsolate(), - new TestOneByteResource(i::StrDup(one_byte_extern_1))); + right = String::NewExternalOneByte( + env->GetIsolate(), + new TestOneByteResource(i::StrDup(one_byte_extern_1))) + .ToLocalChecked(); source = String::Concat(source, right); - right = String::NewExternal( - env->GetIsolate(), - new TestResource(AsciiToTwoByteString(two_byte_extern_1))); + right = String::NewExternalTwoByte( + env->GetIsolate(), + new TestResource(AsciiToTwoByteString(two_byte_extern_1))) + .ToLocalChecked(); source = String::Concat(source, right); right = v8_str(one_byte_string_2); source = String::Concat(source, right); two_byte_source = AsciiToTwoByteString(two_byte_string_2); - right = String::NewFromTwoByte(env->GetIsolate(), two_byte_source); + right = String::NewFromTwoByte(env->GetIsolate(), two_byte_source, + v8::NewStringType::kNormal) + .ToLocalChecked(); i::DeleteArray(two_byte_source); source = String::Concat(source, right); - right = String::NewExternal( - env->GetIsolate(), - new TestResource(AsciiToTwoByteString(two_byte_extern_2))); + right = String::NewExternalTwoByte( + env->GetIsolate(), + new TestResource(AsciiToTwoByteString(two_byte_extern_2))) + .ToLocalChecked(); source = String::Concat(source, right); Local<Script> script = v8_compile(source); - Local<Value> value = script->Run(); + Local<Value> value = script->Run(env.local()).ToLocalChecked(); CHECK(value->IsNumber()); - CHECK_EQ(68, value->Int32Value()); + CHECK_EQ(68, value->Int32Value(env.local()).FromJust()); } CcTest::i_isolate()->compilation_cache()->Clear(); CcTest::heap()->CollectAllGarbage(); @@ -864,10 +928,10 @@ THREADED_TEST(StringConcat) { THREADED_TEST(GlobalProperties) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Handle<v8::Object> global = env->Global(); - global->Set(v8_str("pi"), v8_num(3.1415926)); - Local<Value> pi = global->Get(v8_str("pi")); - CHECK_EQ(3.1415926, pi->NumberValue()); + v8::Local<v8::Object> global = env->Global(); + CHECK(global->Set(env.local(), v8_str("pi"), v8_num(3.1415926)).FromJust()); + Local<Value> pi = global->Get(env.local(), v8_str("pi")).ToLocalChecked(); + CHECK_EQ(3.1415926, pi->NumberValue(env.local()).FromJust()); } @@ -893,8 +957,14 @@ static void construct_callback( const v8::FunctionCallbackInfo<Value>& info) { ApiTestFuzzer::Fuzz(); CheckReturnValue(info, FUNCTION_ADDR(construct_callback)); - info.This()->Set(v8_str("x"), v8_num(1)); - info.This()->Set(v8_str("y"), v8_num(2)); + CHECK( + info.This() + ->Set(info.GetIsolate()->GetCurrentContext(), v8_str("x"), v8_num(1)) + .FromJust()); + CHECK( + info.This() + ->Set(info.GetIsolate()->GetCurrentContext(), v8_str("y"), v8_num(2)) + .FromJust()); info.GetReturnValue().Set(v8_str("bad value")); info.GetReturnValue().Set(info.This()); } @@ -920,11 +990,11 @@ static void TestFunctionTemplateInitializer(Handler handler, Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate, handler); - Local<Function> fun = fun_templ->GetFunction(); - env->Global()->Set(v8_str("obj"), fun); + Local<Function> fun = fun_templ->GetFunction(env.local()).ToLocalChecked(); + CHECK(env->Global()->Set(env.local(), v8_str("obj"), fun).FromJust()); Local<Script> script = v8_compile("obj()"); for (int i = 0; i < 30; i++) { - CHECK_EQ(102, script->Run()->Int32Value()); + CHECK_EQ(102, v8_run_int32value(script)); } } // Use SetCallHandler to initialize a function template, should work like @@ -936,11 +1006,11 @@ static void TestFunctionTemplateInitializer(Handler handler, Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); fun_templ->SetCallHandler(handler_2); - Local<Function> fun = fun_templ->GetFunction(); - env->Global()->Set(v8_str("obj"), fun); + Local<Function> fun = fun_templ->GetFunction(env.local()).ToLocalChecked(); + CHECK(env->Global()->Set(env.local(), v8_str("obj"), fun).FromJust()); Local<Script> script = v8_compile("obj()"); for (int i = 0; i < 30; i++) { - CHECK_EQ(102, script->Run()->Int32Value()); + CHECK_EQ(102, v8_run_int32value(script)); } } } @@ -956,19 +1026,20 @@ static void TestFunctionTemplateAccessor(Constructor constructor, v8::FunctionTemplate::New(env->GetIsolate(), constructor); fun_templ->SetClassName(v8_str("funky")); fun_templ->InstanceTemplate()->SetAccessor(v8_str("m"), accessor); - Local<Function> fun = fun_templ->GetFunction(); - env->Global()->Set(v8_str("obj"), fun); - Local<Value> result = v8_compile("(new obj()).toString()")->Run(); - CHECK(v8_str("[object funky]")->Equals(result)); + Local<Function> fun = fun_templ->GetFunction(env.local()).ToLocalChecked(); + CHECK(env->Global()->Set(env.local(), v8_str("obj"), fun).FromJust()); + Local<Value> result = + v8_compile("(new obj()).toString()")->Run(env.local()).ToLocalChecked(); + CHECK(v8_str("[object funky]")->Equals(env.local(), result).FromJust()); CompileRun("var obj_instance = new obj();"); Local<Script> script; script = v8_compile("obj_instance.x"); for (int i = 0; i < 30; i++) { - CHECK_EQ(1, script->Run()->Int32Value()); + CHECK_EQ(1, v8_run_int32value(script)); } script = v8_compile("obj_instance.m"); for (int i = 0; i < 30; i++) { - CHECK_EQ(239, script->Run()->Int32Value()); + CHECK_EQ(239, v8_run_int32value(script)); } } @@ -992,20 +1063,24 @@ static void TestSimpleCallback(Callback callback) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> object_template = + v8::Local<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(isolate); object_template->Set(isolate, "callback", v8::FunctionTemplate::New(isolate, callback)); - v8::Local<v8::Object> object = object_template->NewInstance(); - (*env)->Global()->Set(v8_str("callback_object"), object); - v8::Handle<v8::Script> script; + v8::Local<v8::Object> object = + object_template->NewInstance(env.local()).ToLocalChecked(); + CHECK((*env) + ->Global() + ->Set(env.local(), v8_str("callback_object"), object) + .FromJust()); + v8::Local<v8::Script> script; script = v8_compile("callback_object.callback(17)"); for (int i = 0; i < 30; i++) { - CHECK_EQ(51424, script->Run()->Int32Value()); + CHECK_EQ(51424, v8_run_int32value(script)); } script = v8_compile("callback_object.callback(17, 24)"); for (int i = 0; i < 30; i++) { - CHECK_EQ(51425, script->Run()->Int32Value()); + CHECK_EQ(51425, v8_run_int32value(script)); } } @@ -1086,25 +1161,29 @@ void FastReturnValueCallback<void>( template<> void FastReturnValueCallback<Object>( const v8::FunctionCallbackInfo<v8::Value>& info) { - v8::Handle<v8::Object> object; + v8::Local<v8::Object> object; if (!fast_return_value_object_is_empty) { object = Object::New(info.GetIsolate()); } info.GetReturnValue().Set(object); } -template<typename T> -Handle<Value> TestFastReturnValues() { +template <typename T> +Local<Value> TestFastReturnValues() { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::EscapableHandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> object_template = + v8::Local<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(isolate); v8::FunctionCallback callback = &FastReturnValueCallback<T>; object_template->Set(isolate, "callback", v8::FunctionTemplate::New(isolate, callback)); - v8::Local<v8::Object> object = object_template->NewInstance(); - (*env)->Global()->Set(v8_str("callback_object"), object); + v8::Local<v8::Object> object = + object_template->NewInstance(env.local()).ToLocalChecked(); + CHECK((*env) + ->Global() + ->Set(env.local(), v8_str("callback_object"), object) + .FromJust()); return scope.Escape(CompileRun("callback_object.callback()")); } @@ -1113,7 +1192,7 @@ THREADED_PROFILED_TEST(FastReturnValues) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::Value> value; + v8::Local<v8::Value> value; // check int32_t and uint32_t int32_t int_values[] = { 0, 234, -723, @@ -1126,24 +1205,28 @@ THREADED_PROFILED_TEST(FastReturnValues) { fast_return_value_int32 = int_value; value = TestFastReturnValues<int32_t>(); CHECK(value->IsInt32()); - CHECK(fast_return_value_int32 == value->Int32Value()); + CHECK_EQ(fast_return_value_int32, + value->Int32Value(env.local()).FromJust()); // check uint32_t fast_return_value_uint32 = static_cast<uint32_t>(int_value); value = TestFastReturnValues<uint32_t>(); CHECK(value->IsUint32()); - CHECK(fast_return_value_uint32 == value->Uint32Value()); + CHECK_EQ(fast_return_value_uint32, + value->Uint32Value(env.local()).FromJust()); } } // check double value = TestFastReturnValues<double>(); CHECK(value->IsNumber()); - CHECK_EQ(kFastReturnValueDouble, value->ToNumber(isolate)->Value()); + CHECK_EQ(kFastReturnValueDouble, + value->ToNumber(env.local()).ToLocalChecked()->Value()); // check bool values for (int i = 0; i < 2; i++) { fast_return_value_bool = i == 0; value = TestFastReturnValues<bool>(); CHECK(value->IsBoolean()); - CHECK_EQ(fast_return_value_bool, value->ToBoolean(isolate)->Value()); + CHECK_EQ(fast_return_value_bool, + value->ToBoolean(env.local()).ToLocalChecked()->Value()); } // check oddballs ReturnValueOddball oddballs[] = { @@ -1183,33 +1266,30 @@ THREADED_TEST(FunctionTemplateSetLength) { v8::HandleScope scope(isolate); { Local<v8::FunctionTemplate> fun_templ = - v8::FunctionTemplate::New(isolate, - handle_callback, - Handle<v8::Value>(), - Handle<v8::Signature>(), - 23); - Local<Function> fun = fun_templ->GetFunction(); - env->Global()->Set(v8_str("obj"), fun); + v8::FunctionTemplate::New(isolate, handle_callback, Local<v8::Value>(), + Local<v8::Signature>(), 23); + Local<Function> fun = fun_templ->GetFunction(env.local()).ToLocalChecked(); + CHECK(env->Global()->Set(env.local(), v8_str("obj"), fun).FromJust()); Local<Script> script = v8_compile("obj.length"); - CHECK_EQ(23, script->Run()->Int32Value()); + CHECK_EQ(23, v8_run_int32value(script)); } { Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate, handle_callback); fun_templ->SetLength(22); - Local<Function> fun = fun_templ->GetFunction(); - env->Global()->Set(v8_str("obj"), fun); + Local<Function> fun = fun_templ->GetFunction(env.local()).ToLocalChecked(); + CHECK(env->Global()->Set(env.local(), v8_str("obj"), fun).FromJust()); Local<Script> script = v8_compile("obj.length"); - CHECK_EQ(22, script->Run()->Int32Value()); + CHECK_EQ(22, v8_run_int32value(script)); } { // Without setting length it defaults to 0. Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate, handle_callback); - Local<Function> fun = fun_templ->GetFunction(); - env->Global()->Set(v8_str("obj"), fun); + Local<Function> fun = fun_templ->GetFunction(env.local()).ToLocalChecked(); + CHECK(env->Global()->Set(env.local(), v8_str("obj"), fun).FromJust()); Local<Script> script = v8_compile("obj.length"); - CHECK_EQ(0, script->Run()->Int32Value()); + CHECK_EQ(0, v8_run_int32value(script)); } } @@ -1227,19 +1307,22 @@ static void TestExternalPointerWrapping() { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::Value> data = - v8::External::New(isolate, expected_ptr); + v8::Local<v8::Value> data = v8::External::New(isolate, expected_ptr); - v8::Handle<v8::Object> obj = v8::Object::New(isolate); - obj->Set(v8_str("func"), - v8::FunctionTemplate::New(isolate, callback, data)->GetFunction()); - env->Global()->Set(v8_str("obj"), obj); + v8::Local<v8::Object> obj = v8::Object::New(isolate); + CHECK(obj->Set(env.local(), v8_str("func"), + v8::FunctionTemplate::New(isolate, callback, data) + ->GetFunction(env.local()) + .ToLocalChecked()) + .FromJust()); + CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); - CHECK(CompileRun( - "function foo() {\n" - " for (var i = 0; i < 13; i++) obj.func();\n" - "}\n" - "foo(), true")->BooleanValue()); + CHECK(CompileRun("function foo() {\n" + " for (var i = 0; i < 13; i++) obj.func();\n" + "}\n" + "foo(), true") + ->BooleanValue(env.local()) + .FromJust()); } @@ -1299,28 +1382,43 @@ THREADED_TEST(FindInstanceInPrototypeChain) { Local<v8::FunctionTemplate> other = v8::FunctionTemplate::New(isolate); derived->Inherit(base); - Local<v8::Function> base_function = base->GetFunction(); - Local<v8::Function> derived_function = derived->GetFunction(); - Local<v8::Function> other_function = other->GetFunction(); - - Local<v8::Object> base_instance = base_function->NewInstance(); - Local<v8::Object> derived_instance = derived_function->NewInstance(); - Local<v8::Object> derived_instance2 = derived_function->NewInstance(); - Local<v8::Object> other_instance = other_function->NewInstance(); - derived_instance2->Set(v8_str("__proto__"), derived_instance); - other_instance->Set(v8_str("__proto__"), derived_instance2); + Local<v8::Function> base_function = + base->GetFunction(env.local()).ToLocalChecked(); + Local<v8::Function> derived_function = + derived->GetFunction(env.local()).ToLocalChecked(); + Local<v8::Function> other_function = + other->GetFunction(env.local()).ToLocalChecked(); + + Local<v8::Object> base_instance = + base_function->NewInstance(env.local()).ToLocalChecked(); + Local<v8::Object> derived_instance = + derived_function->NewInstance(env.local()).ToLocalChecked(); + Local<v8::Object> derived_instance2 = + derived_function->NewInstance(env.local()).ToLocalChecked(); + Local<v8::Object> other_instance = + other_function->NewInstance(env.local()).ToLocalChecked(); + CHECK( + derived_instance2->Set(env.local(), v8_str("__proto__"), derived_instance) + .FromJust()); + CHECK(other_instance->Set(env.local(), v8_str("__proto__"), derived_instance2) + .FromJust()); // base_instance is only an instance of base. - CHECK( - base_instance->Equals(base_instance->FindInstanceInPrototypeChain(base))); + CHECK(base_instance->Equals(env.local(), + base_instance->FindInstanceInPrototypeChain(base)) + .FromJust()); CHECK(base_instance->FindInstanceInPrototypeChain(derived).IsEmpty()); CHECK(base_instance->FindInstanceInPrototypeChain(other).IsEmpty()); // derived_instance is an instance of base and derived. - CHECK(derived_instance->Equals( - derived_instance->FindInstanceInPrototypeChain(base))); - CHECK(derived_instance->Equals( - derived_instance->FindInstanceInPrototypeChain(derived))); + CHECK(derived_instance->Equals(env.local(), + derived_instance->FindInstanceInPrototypeChain( + base)) + .FromJust()); + CHECK(derived_instance->Equals(env.local(), + derived_instance->FindInstanceInPrototypeChain( + derived)) + .FromJust()); CHECK(derived_instance->FindInstanceInPrototypeChain(other).IsEmpty()); // other_instance is an instance of other and its immediate @@ -1329,11 +1427,17 @@ THREADED_TEST(FindInstanceInPrototypeChain) { // but it comes after derived_instance2 in the prototype chain of // other_instance. CHECK(derived_instance2->Equals( - other_instance->FindInstanceInPrototypeChain(base))); - CHECK(derived_instance2->Equals( - other_instance->FindInstanceInPrototypeChain(derived))); + env.local(), + other_instance->FindInstanceInPrototypeChain(base)) + .FromJust()); + CHECK(derived_instance2->Equals(env.local(), + other_instance->FindInstanceInPrototypeChain( + derived)) + .FromJust()); CHECK(other_instance->Equals( - other_instance->FindInstanceInPrototypeChain(other))); + env.local(), + other_instance->FindInstanceInPrototypeChain(other)) + .FromJust()); } @@ -1463,12 +1567,12 @@ THREADED_TEST(OutOfSignedRangeUnsignedInteger) { THREADED_TEST(IsNativeError) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Handle<Value> syntax_error = CompileRun( + v8::Local<Value> syntax_error = CompileRun( "var out = 0; try { eval(\"#\"); } catch(x) { out = x; } out; "); CHECK(syntax_error->IsNativeError()); - v8::Handle<Value> not_error = CompileRun("{a:42}"); + v8::Local<Value> not_error = CompileRun("{a:42}"); CHECK(!not_error->IsNativeError()); - v8::Handle<Value> not_object = CompileRun("42"); + v8::Local<Value> not_object = CompileRun("42"); CHECK(!not_object->IsNativeError()); } @@ -1478,10 +1582,10 @@ THREADED_TEST(IsGeneratorFunctionOrObject) { v8::HandleScope scope(env->GetIsolate()); CompileRun("function *gen() { yield 1; }\nfunction func() {}"); - v8::Handle<Value> gen = CompileRun("gen"); - v8::Handle<Value> genObj = CompileRun("gen()"); - v8::Handle<Value> object = CompileRun("{a:42}"); - v8::Handle<Value> func = CompileRun("func"); + v8::Local<Value> gen = CompileRun("gen"); + v8::Local<Value> genObj = CompileRun("gen()"); + v8::Local<Value> object = CompileRun("{a:42}"); + v8::Local<Value> func = CompileRun("func"); CHECK(gen->IsGeneratorFunction()); CHECK(gen->IsFunction()); @@ -1504,12 +1608,12 @@ THREADED_TEST(IsGeneratorFunctionOrObject) { THREADED_TEST(ArgumentsObject) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Handle<Value> arguments_object = + v8::Local<Value> arguments_object = CompileRun("var out = 0; (function(){ out = arguments; })(1,2,3); out;"); CHECK(arguments_object->IsArgumentsObject()); - v8::Handle<Value> array = CompileRun("[1,2,3]"); + v8::Local<Value> array = CompileRun("[1,2,3]"); CHECK(!array->IsArgumentsObject()); - v8::Handle<Value> object = CompileRun("{a:42}"); + v8::Local<Value> object = CompileRun("{a:42}"); CHECK(!object->IsArgumentsObject()); } @@ -1517,10 +1621,10 @@ THREADED_TEST(ArgumentsObject) { THREADED_TEST(IsMapOrSet) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Handle<Value> map = CompileRun("new Map()"); - v8::Handle<Value> set = CompileRun("new Set()"); - v8::Handle<Value> weak_map = CompileRun("new WeakMap()"); - v8::Handle<Value> weak_set = CompileRun("new WeakSet()"); + v8::Local<Value> map = CompileRun("new Map()"); + v8::Local<Value> set = CompileRun("new Set()"); + v8::Local<Value> weak_map = CompileRun("new WeakMap()"); + v8::Local<Value> weak_set = CompileRun("new WeakSet()"); CHECK(map->IsMap()); CHECK(set->IsSet()); CHECK(weak_map->IsWeakMap()); @@ -1542,7 +1646,7 @@ THREADED_TEST(IsMapOrSet) { CHECK(!weak_set->IsSet()); CHECK(!weak_set->IsWeakMap()); - v8::Handle<Value> object = CompileRun("{a:42}"); + v8::Local<Value> object = CompileRun("{a:42}"); CHECK(!object->IsMap()); CHECK(!object->IsSet()); CHECK(!object->IsWeakMap()); @@ -1553,20 +1657,20 @@ THREADED_TEST(IsMapOrSet) { THREADED_TEST(StringObject) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Handle<Value> boxed_string = CompileRun("new String(\"test\")"); + v8::Local<Value> boxed_string = CompileRun("new String(\"test\")"); CHECK(boxed_string->IsStringObject()); - v8::Handle<Value> unboxed_string = CompileRun("\"test\""); + v8::Local<Value> unboxed_string = CompileRun("\"test\""); CHECK(!unboxed_string->IsStringObject()); - v8::Handle<Value> boxed_not_string = CompileRun("new Number(42)"); + v8::Local<Value> boxed_not_string = CompileRun("new Number(42)"); CHECK(!boxed_not_string->IsStringObject()); - v8::Handle<Value> not_object = CompileRun("0"); + v8::Local<Value> not_object = CompileRun("0"); CHECK(!not_object->IsStringObject()); - v8::Handle<v8::StringObject> as_boxed = boxed_string.As<v8::StringObject>(); + v8::Local<v8::StringObject> as_boxed = boxed_string.As<v8::StringObject>(); CHECK(!as_boxed.IsEmpty()); Local<v8::String> the_string = as_boxed->ValueOf(); CHECK(!the_string.IsEmpty()); ExpectObject("\"test\"", the_string); - v8::Handle<v8::Value> new_boxed_string = v8::StringObject::New(the_string); + v8::Local<v8::Value> new_boxed_string = v8::StringObject::New(the_string); CHECK(new_boxed_string->IsStringObject()); as_boxed = new_boxed_string.As<v8::StringObject>(); the_string = as_boxed->ValueOf(); @@ -1578,28 +1682,28 @@ THREADED_TEST(StringObject) { TEST(StringObjectDelete) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::Handle<Value> boxed_string = CompileRun("new String(\"test\")"); + v8::Local<Value> boxed_string = CompileRun("new String(\"test\")"); CHECK(boxed_string->IsStringObject()); - v8::Handle<v8::Object> str_obj = boxed_string.As<v8::Object>(); - CHECK(!str_obj->Delete(2)); - CHECK(!str_obj->Delete(v8_num(2))); + v8::Local<v8::Object> str_obj = boxed_string.As<v8::Object>(); + CHECK(!str_obj->Delete(context.local(), 2).FromJust()); + CHECK(!str_obj->Delete(context.local(), v8_num(2)).FromJust()); } THREADED_TEST(NumberObject) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Handle<Value> boxed_number = CompileRun("new Number(42)"); + v8::Local<Value> boxed_number = CompileRun("new Number(42)"); CHECK(boxed_number->IsNumberObject()); - v8::Handle<Value> unboxed_number = CompileRun("42"); + v8::Local<Value> unboxed_number = CompileRun("42"); CHECK(!unboxed_number->IsNumberObject()); - v8::Handle<Value> boxed_not_number = CompileRun("new Boolean(false)"); + v8::Local<Value> boxed_not_number = CompileRun("new Boolean(false)"); CHECK(!boxed_not_number->IsNumberObject()); - v8::Handle<v8::NumberObject> as_boxed = boxed_number.As<v8::NumberObject>(); + v8::Local<v8::NumberObject> as_boxed = boxed_number.As<v8::NumberObject>(); CHECK(!as_boxed.IsEmpty()); double the_number = as_boxed->ValueOf(); CHECK_EQ(42.0, the_number); - v8::Handle<v8::Value> new_boxed_number = + v8::Local<v8::Value> new_boxed_number = v8::NumberObject::New(env->GetIsolate(), 43); CHECK(new_boxed_number->IsNumberObject()); as_boxed = new_boxed_number.As<v8::NumberObject>(); @@ -1611,19 +1715,20 @@ THREADED_TEST(NumberObject) { THREADED_TEST(BooleanObject) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Handle<Value> boxed_boolean = CompileRun("new Boolean(true)"); + v8::Local<Value> boxed_boolean = CompileRun("new Boolean(true)"); CHECK(boxed_boolean->IsBooleanObject()); - v8::Handle<Value> unboxed_boolean = CompileRun("true"); + v8::Local<Value> unboxed_boolean = CompileRun("true"); CHECK(!unboxed_boolean->IsBooleanObject()); - v8::Handle<Value> boxed_not_boolean = CompileRun("new Number(42)"); + v8::Local<Value> boxed_not_boolean = CompileRun("new Number(42)"); CHECK(!boxed_not_boolean->IsBooleanObject()); - v8::Handle<v8::BooleanObject> as_boxed = - boxed_boolean.As<v8::BooleanObject>(); + v8::Local<v8::BooleanObject> as_boxed = boxed_boolean.As<v8::BooleanObject>(); CHECK(!as_boxed.IsEmpty()); bool the_boolean = as_boxed->ValueOf(); CHECK_EQ(true, the_boolean); - v8::Handle<v8::Value> boxed_true = v8::BooleanObject::New(true); - v8::Handle<v8::Value> boxed_false = v8::BooleanObject::New(false); + v8::Local<v8::Value> boxed_true = + v8::BooleanObject::New(env->GetIsolate(), true); + v8::Local<v8::Value> boxed_false = + v8::BooleanObject::New(env->GetIsolate(), false); CHECK(boxed_true->IsBooleanObject()); CHECK(boxed_false->IsBooleanObject()); as_boxed = boxed_true.As<v8::BooleanObject>(); @@ -1640,22 +1745,21 @@ THREADED_TEST(PrimitiveAndWrappedBooleans) { Local<Value> primitive_false = Boolean::New(env->GetIsolate(), false); CHECK(primitive_false->IsBoolean()); CHECK(!primitive_false->IsBooleanObject()); - CHECK(!primitive_false->BooleanValue()); + CHECK(!primitive_false->BooleanValue(env.local()).FromJust()); CHECK(!primitive_false->IsTrue()); CHECK(primitive_false->IsFalse()); - Local<Value> false_value = BooleanObject::New(false); + Local<Value> false_value = BooleanObject::New(env->GetIsolate(), false); CHECK(!false_value->IsBoolean()); CHECK(false_value->IsBooleanObject()); - CHECK(false_value->BooleanValue()); + CHECK(false_value->BooleanValue(env.local()).FromJust()); CHECK(!false_value->IsTrue()); CHECK(!false_value->IsFalse()); Local<BooleanObject> false_boolean_object = false_value.As<BooleanObject>(); CHECK(!false_boolean_object->IsBoolean()); CHECK(false_boolean_object->IsBooleanObject()); - // TODO(svenpanne) Uncomment when BooleanObject::BooleanValue() is deleted. - // CHECK(false_boolean_object->BooleanValue()); + CHECK(false_boolean_object->BooleanValue(env.local()).FromJust()); CHECK(!false_boolean_object->ValueOf()); CHECK(!false_boolean_object->IsTrue()); CHECK(!false_boolean_object->IsFalse()); @@ -1663,22 +1767,21 @@ THREADED_TEST(PrimitiveAndWrappedBooleans) { Local<Value> primitive_true = Boolean::New(env->GetIsolate(), true); CHECK(primitive_true->IsBoolean()); CHECK(!primitive_true->IsBooleanObject()); - CHECK(primitive_true->BooleanValue()); + CHECK(primitive_true->BooleanValue(env.local()).FromJust()); CHECK(primitive_true->IsTrue()); CHECK(!primitive_true->IsFalse()); - Local<Value> true_value = BooleanObject::New(true); + Local<Value> true_value = BooleanObject::New(env->GetIsolate(), true); CHECK(!true_value->IsBoolean()); CHECK(true_value->IsBooleanObject()); - CHECK(true_value->BooleanValue()); + CHECK(true_value->BooleanValue(env.local()).FromJust()); CHECK(!true_value->IsTrue()); CHECK(!true_value->IsFalse()); Local<BooleanObject> true_boolean_object = true_value.As<BooleanObject>(); CHECK(!true_boolean_object->IsBoolean()); CHECK(true_boolean_object->IsBooleanObject()); - // TODO(svenpanne) Uncomment when BooleanObject::BooleanValue() is deleted. - // CHECK(true_boolean_object->BooleanValue()); + CHECK(true_boolean_object->BooleanValue(env.local()).FromJust()); CHECK(true_boolean_object->ValueOf()); CHECK(!true_boolean_object->IsTrue()); CHECK(!true_boolean_object->IsFalse()); @@ -1690,7 +1793,7 @@ THREADED_TEST(Number) { v8::HandleScope scope(env->GetIsolate()); double PI = 3.1415926; Local<v8::Number> pi_obj = v8::Number::New(env->GetIsolate(), PI); - CHECK_EQ(PI, pi_obj->NumberValue()); + CHECK_EQ(PI, pi_obj->NumberValue(env.local()).FromJust()); } @@ -1699,11 +1802,11 @@ THREADED_TEST(ToNumber) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); Local<String> str = v8_str("3.1415926"); - CHECK_EQ(3.1415926, str->NumberValue()); - v8::Handle<v8::Boolean> t = v8::True(isolate); - CHECK_EQ(1.0, t->NumberValue()); - v8::Handle<v8::Boolean> f = v8::False(isolate); - CHECK_EQ(0.0, f->NumberValue()); + CHECK_EQ(3.1415926, str->NumberValue(env.local()).FromJust()); + v8::Local<v8::Boolean> t = v8::True(isolate); + CHECK_EQ(1.0, t->NumberValue(env.local()).FromJust()); + v8::Local<v8::Boolean> f = v8::False(isolate); + CHECK_EQ(0.0, f->NumberValue(env.local()).FromJust()); } @@ -1711,11 +1814,17 @@ THREADED_TEST(Date) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); double PI = 3.1415926; - Local<Value> date = v8::Date::New(env->GetIsolate(), PI); - CHECK_EQ(3.0, date->NumberValue()); - date.As<v8::Date>()->Set(v8_str("property"), - v8::Integer::New(env->GetIsolate(), 42)); - CHECK_EQ(42, date.As<v8::Date>()->Get(v8_str("property"))->Int32Value()); + Local<Value> date = v8::Date::New(env.local(), PI).ToLocalChecked(); + CHECK_EQ(3.0, date->NumberValue(env.local()).FromJust()); + CHECK(date.As<v8::Date>() + ->Set(env.local(), v8_str("property"), + v8::Integer::New(env->GetIsolate(), 42)) + .FromJust()); + CHECK_EQ(42, date.As<v8::Date>() + ->Get(env.local(), v8_str("property")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); } @@ -1723,23 +1832,27 @@ THREADED_TEST(Boolean) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::Boolean> t = v8::True(isolate); + v8::Local<v8::Boolean> t = v8::True(isolate); CHECK(t->Value()); - v8::Handle<v8::Boolean> f = v8::False(isolate); + v8::Local<v8::Boolean> f = v8::False(isolate); CHECK(!f->Value()); - v8::Handle<v8::Primitive> u = v8::Undefined(isolate); - CHECK(!u->BooleanValue()); - v8::Handle<v8::Primitive> n = v8::Null(isolate); - CHECK(!n->BooleanValue()); - v8::Handle<String> str1 = v8_str(""); - CHECK(!str1->BooleanValue()); - v8::Handle<String> str2 = v8_str("x"); - CHECK(str2->BooleanValue()); - CHECK(!v8::Number::New(isolate, 0)->BooleanValue()); - CHECK(v8::Number::New(isolate, -1)->BooleanValue()); - CHECK(v8::Number::New(isolate, 1)->BooleanValue()); - CHECK(v8::Number::New(isolate, 42)->BooleanValue()); - CHECK(!v8_compile("NaN")->Run()->BooleanValue()); + v8::Local<v8::Primitive> u = v8::Undefined(isolate); + CHECK(!u->BooleanValue(env.local()).FromJust()); + v8::Local<v8::Primitive> n = v8::Null(isolate); + CHECK(!n->BooleanValue(env.local()).FromJust()); + v8::Local<String> str1 = v8_str(""); + CHECK(!str1->BooleanValue(env.local()).FromJust()); + v8::Local<String> str2 = v8_str("x"); + CHECK(str2->BooleanValue(env.local()).FromJust()); + CHECK(!v8::Number::New(isolate, 0)->BooleanValue(env.local()).FromJust()); + CHECK(v8::Number::New(isolate, -1)->BooleanValue(env.local()).FromJust()); + CHECK(v8::Number::New(isolate, 1)->BooleanValue(env.local()).FromJust()); + CHECK(v8::Number::New(isolate, 42)->BooleanValue(env.local()).FromJust()); + CHECK(!v8_compile("NaN") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); } @@ -1759,19 +1872,19 @@ static void GetM(Local<String> name, THREADED_TEST(GlobalPrototype) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> func_templ = + v8::Local<v8::FunctionTemplate> func_templ = v8::FunctionTemplate::New(isolate); func_templ->PrototypeTemplate()->Set( isolate, "dummy", v8::FunctionTemplate::New(isolate, DummyCallHandler)); - v8::Handle<ObjectTemplate> templ = func_templ->InstanceTemplate(); + v8::Local<ObjectTemplate> templ = func_templ->InstanceTemplate(); templ->Set(isolate, "x", v8_num(200)); templ->SetAccessor(v8_str("m"), GetM); LocalContext env(0, templ); - v8::Handle<Script> script(v8_compile("dummy()")); - v8::Handle<Value> result(script->Run()); - CHECK_EQ(13.4, result->NumberValue()); - CHECK_EQ(200, v8_compile("x")->Run()->Int32Value()); - CHECK_EQ(876, v8_compile("m")->Run()->Int32Value()); + v8::Local<Script> script(v8_compile("dummy()")); + v8::Local<Value> result(script->Run(env.local()).ToLocalChecked()); + CHECK_EQ(13.4, result->NumberValue(env.local()).FromJust()); + CHECK_EQ(200, v8_run_int32value(v8_compile("x"))); + CHECK_EQ(876, v8_run_int32value(v8_compile("m"))); } @@ -1779,29 +1892,54 @@ THREADED_TEST(ObjectTemplate) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate); - v8::Local<v8::String> class_name = - v8::String::NewFromUtf8(isolate, "the_class_name"); + v8::Local<v8::String> class_name = v8_str("the_class_name"); fun->SetClassName(class_name); Local<ObjectTemplate> templ1 = ObjectTemplate::New(isolate, fun); templ1->Set(isolate, "x", v8_num(10)); templ1->Set(isolate, "y", v8_num(13)); LocalContext env; - Local<v8::Object> instance1 = templ1->NewInstance(); + Local<v8::Object> instance1 = + templ1->NewInstance(env.local()).ToLocalChecked(); CHECK(class_name->StrictEquals(instance1->GetConstructorName())); - env->Global()->Set(v8_str("p"), instance1); - CHECK(v8_compile("(p.x == 10)")->Run()->BooleanValue()); - CHECK(v8_compile("(p.y == 13)")->Run()->BooleanValue()); + CHECK(env->Global()->Set(env.local(), v8_str("p"), instance1).FromJust()); + CHECK(v8_compile("(p.x == 10)") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); + CHECK(v8_compile("(p.y == 13)") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); Local<v8::FunctionTemplate> fun2 = v8::FunctionTemplate::New(isolate); fun2->PrototypeTemplate()->Set(isolate, "nirk", v8_num(123)); Local<ObjectTemplate> templ2 = fun2->InstanceTemplate(); templ2->Set(isolate, "a", v8_num(12)); templ2->Set(isolate, "b", templ1); - Local<v8::Object> instance2 = templ2->NewInstance(); - env->Global()->Set(v8_str("q"), instance2); - CHECK(v8_compile("(q.nirk == 123)")->Run()->BooleanValue()); - CHECK(v8_compile("(q.a == 12)")->Run()->BooleanValue()); - CHECK(v8_compile("(q.b.x == 10)")->Run()->BooleanValue()); - CHECK(v8_compile("(q.b.y == 13)")->Run()->BooleanValue()); + Local<v8::Object> instance2 = + templ2->NewInstance(env.local()).ToLocalChecked(); + CHECK(env->Global()->Set(env.local(), v8_str("q"), instance2).FromJust()); + CHECK(v8_compile("(q.nirk == 123)") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); + CHECK(v8_compile("(q.a == 12)") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); + CHECK(v8_compile("(q.b.x == 10)") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); + CHECK(v8_compile("(q.b.y == 13)") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); } @@ -1821,7 +1959,7 @@ static void GetKnurd(Local<String> property, THREADED_TEST(DescriptorInheritance) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> super = v8::FunctionTemplate::New(isolate); + v8::Local<v8::FunctionTemplate> super = v8::FunctionTemplate::New(isolate); super->PrototypeTemplate()->Set(isolate, "flabby", v8::FunctionTemplate::New(isolate, GetFlabby)); @@ -1829,50 +1967,121 @@ THREADED_TEST(DescriptorInheritance) { super->InstanceTemplate()->SetAccessor(v8_str("knurd"), GetKnurd); - v8::Handle<v8::FunctionTemplate> base1 = v8::FunctionTemplate::New(isolate); + v8::Local<v8::FunctionTemplate> base1 = v8::FunctionTemplate::New(isolate); base1->Inherit(super); base1->PrototypeTemplate()->Set(isolate, "v1", v8_num(20.1)); - v8::Handle<v8::FunctionTemplate> base2 = v8::FunctionTemplate::New(isolate); + v8::Local<v8::FunctionTemplate> base2 = v8::FunctionTemplate::New(isolate); base2->Inherit(super); base2->PrototypeTemplate()->Set(isolate, "v2", v8_num(10.1)); LocalContext env; - env->Global()->Set(v8_str("s"), super->GetFunction()); - env->Global()->Set(v8_str("base1"), base1->GetFunction()); - env->Global()->Set(v8_str("base2"), base2->GetFunction()); + CHECK(env->Global() + ->Set(env.local(), v8_str("s"), + super->GetFunction(env.local()).ToLocalChecked()) + .FromJust()); + CHECK(env->Global() + ->Set(env.local(), v8_str("base1"), + base1->GetFunction(env.local()).ToLocalChecked()) + .FromJust()); + CHECK(env->Global() + ->Set(env.local(), v8_str("base2"), + base2->GetFunction(env.local()).ToLocalChecked()) + .FromJust()); // Checks right __proto__ chain. - CHECK(CompileRun("base1.prototype.__proto__ == s.prototype")->BooleanValue()); - CHECK(CompileRun("base2.prototype.__proto__ == s.prototype")->BooleanValue()); + CHECK(CompileRun("base1.prototype.__proto__ == s.prototype") + ->BooleanValue(env.local()) + .FromJust()); + CHECK(CompileRun("base2.prototype.__proto__ == s.prototype") + ->BooleanValue(env.local()) + .FromJust()); - CHECK(v8_compile("s.prototype.PI == 3.14")->Run()->BooleanValue()); + CHECK(v8_compile("s.prototype.PI == 3.14") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); // Instance accessor should not be visible on function object or its prototype - CHECK(CompileRun("s.knurd == undefined")->BooleanValue()); - CHECK(CompileRun("s.prototype.knurd == undefined")->BooleanValue()); - CHECK(CompileRun("base1.prototype.knurd == undefined")->BooleanValue()); - - env->Global()->Set(v8_str("obj"), - base1->GetFunction()->NewInstance()); - CHECK_EQ(17.2, v8_compile("obj.flabby()")->Run()->NumberValue()); - CHECK(v8_compile("'flabby' in obj")->Run()->BooleanValue()); - CHECK_EQ(15.2, v8_compile("obj.knurd")->Run()->NumberValue()); - CHECK(v8_compile("'knurd' in obj")->Run()->BooleanValue()); - CHECK_EQ(20.1, v8_compile("obj.v1")->Run()->NumberValue()); - - env->Global()->Set(v8_str("obj2"), - base2->GetFunction()->NewInstance()); - CHECK_EQ(17.2, v8_compile("obj2.flabby()")->Run()->NumberValue()); - CHECK(v8_compile("'flabby' in obj2")->Run()->BooleanValue()); - CHECK_EQ(15.2, v8_compile("obj2.knurd")->Run()->NumberValue()); - CHECK(v8_compile("'knurd' in obj2")->Run()->BooleanValue()); - CHECK_EQ(10.1, v8_compile("obj2.v2")->Run()->NumberValue()); + CHECK( + CompileRun("s.knurd == undefined")->BooleanValue(env.local()).FromJust()); + CHECK(CompileRun("s.prototype.knurd == undefined") + ->BooleanValue(env.local()) + .FromJust()); + CHECK(CompileRun("base1.prototype.knurd == undefined") + ->BooleanValue(env.local()) + .FromJust()); + + CHECK(env->Global() + ->Set(env.local(), v8_str("obj"), base1->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked()) + .FromJust()); + CHECK_EQ(17.2, v8_compile("obj.flabby()") + ->Run(env.local()) + .ToLocalChecked() + ->NumberValue(env.local()) + .FromJust()); + CHECK(v8_compile("'flabby' in obj") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); + CHECK_EQ(15.2, v8_compile("obj.knurd") + ->Run(env.local()) + .ToLocalChecked() + ->NumberValue(env.local()) + .FromJust()); + CHECK(v8_compile("'knurd' in obj") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); + CHECK_EQ(20.1, v8_compile("obj.v1") + ->Run(env.local()) + .ToLocalChecked() + ->NumberValue(env.local()) + .FromJust()); + + CHECK(env->Global() + ->Set(env.local(), v8_str("obj2"), base2->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked()) + .FromJust()); + CHECK_EQ(17.2, v8_compile("obj2.flabby()") + ->Run(env.local()) + .ToLocalChecked() + ->NumberValue(env.local()) + .FromJust()); + CHECK(v8_compile("'flabby' in obj2") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); + CHECK_EQ(15.2, v8_compile("obj2.knurd") + ->Run(env.local()) + .ToLocalChecked() + ->NumberValue(env.local()) + .FromJust()); + CHECK(v8_compile("'knurd' in obj2") + ->Run(env.local()) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); + CHECK_EQ(10.1, v8_compile("obj2.v2") + ->Run(env.local()) + .ToLocalChecked() + ->NumberValue(env.local()) + .FromJust()); // base1 and base2 cannot cross reference to each's prototype - CHECK(v8_compile("obj.v2")->Run()->IsUndefined()); - CHECK(v8_compile("obj2.v1")->Run()->IsUndefined()); + CHECK(v8_compile("obj.v2")->Run(env.local()).ToLocalChecked()->IsUndefined()); + CHECK( + v8_compile("obj2.v1")->Run(env.local()).ToLocalChecked()->IsUndefined()); } @@ -1880,15 +2089,18 @@ THREADED_TEST(DescriptorInheritance) { void SimpleAccessorGetter(Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { - Handle<Object> self = Handle<Object>::Cast(info.This()); - info.GetReturnValue().Set( - self->Get(String::Concat(v8_str("accessor_"), name))); + Local<Object> self = Local<Object>::Cast(info.This()); + info.GetReturnValue().Set(self->Get(info.GetIsolate()->GetCurrentContext(), + String::Concat(v8_str("accessor_"), name)) + .ToLocalChecked()); } void SimpleAccessorSetter(Local<String> name, Local<Value> value, const v8::PropertyCallbackInfo<void>& info) { - Handle<Object> self = Handle<Object>::Cast(info.This()); - self->Set(String::Concat(v8_str("accessor_"), name), value); + Local<Object> self = Local<Object>::Cast(info.This()); + CHECK(self->Set(info.GetIsolate()->GetCurrentContext(), + String::Concat(v8_str("accessor_"), name), value) + .FromJust()); } void SymbolAccessorGetter(Local<Name> name, @@ -1928,7 +2140,7 @@ THREADED_TEST(ExecutableAccessorIsPreservedOnAttributeChange) { v8::HandleScope scope(isolate); LocalContext env; v8::Local<v8::Value> res = CompileRun("var a = []; a;"); - i::Handle<i::JSObject> a(v8::Utils::OpenHandle(v8::Object::Cast(*res))); + i::Handle<i::JSReceiver> a(v8::Utils::OpenHandle(v8::Object::Cast(*res))); CHECK(a->map()->instance_descriptors()->IsFixedArray()); CHECK_GT(i::FixedArray::cast(a->map()->instance_descriptors())->length(), 0); CompileRun("Object.defineProperty(a, 'length', { writable: false });"); @@ -1944,59 +2156,81 @@ THREADED_TEST(ExecutableAccessorIsPreservedOnAttributeChange) { THREADED_TEST(UndefinedIsNotEnumerable) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Handle<Value> result = CompileRun("this.propertyIsEnumerable(undefined)"); + v8::Local<Value> result = CompileRun("this.propertyIsEnumerable(undefined)"); CHECK(result->IsFalse()); } -v8::Handle<Script> call_recursively_script; +v8::Local<Script> call_recursively_script; static const int kTargetRecursionDepth = 150; // near maximum static void CallScriptRecursivelyCall( const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); - int depth = args.This()->Get(v8_str("depth"))->Int32Value(); + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); + int depth = args.This() + ->Get(context, v8_str("depth")) + .ToLocalChecked() + ->Int32Value(context) + .FromJust(); if (depth == kTargetRecursionDepth) return; - args.This()->Set(v8_str("depth"), - v8::Integer::New(args.GetIsolate(), depth + 1)); - args.GetReturnValue().Set(call_recursively_script->Run()); + CHECK(args.This() + ->Set(context, v8_str("depth"), + v8::Integer::New(args.GetIsolate(), depth + 1)) + .FromJust()); + args.GetReturnValue().Set( + call_recursively_script->Run(context).ToLocalChecked()); } static void CallFunctionRecursivelyCall( const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); - int depth = args.This()->Get(v8_str("depth"))->Int32Value(); + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); + int depth = args.This() + ->Get(context, v8_str("depth")) + .ToLocalChecked() + ->Int32Value(context) + .FromJust(); if (depth == kTargetRecursionDepth) { printf("[depth = %d]\n", depth); return; } - args.This()->Set(v8_str("depth"), - v8::Integer::New(args.GetIsolate(), depth + 1)); - v8::Handle<Value> function = - args.This()->Get(v8_str("callFunctionRecursively")); - args.GetReturnValue().Set( - function.As<Function>()->Call(args.This(), 0, NULL)); + CHECK(args.This() + ->Set(context, v8_str("depth"), + v8::Integer::New(args.GetIsolate(), depth + 1)) + .FromJust()); + v8::Local<Value> function = + args.This() + ->Get(context, v8_str("callFunctionRecursively")) + .ToLocalChecked(); + args.GetReturnValue().Set(function.As<Function>() + ->Call(context, args.This(), 0, NULL) + .ToLocalChecked()); } THREADED_TEST(DeepCrossLanguageRecursion) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> global = ObjectTemplate::New(isolate); global->Set(v8_str("callScriptRecursively"), v8::FunctionTemplate::New(isolate, CallScriptRecursivelyCall)); global->Set(v8_str("callFunctionRecursively"), v8::FunctionTemplate::New(isolate, CallFunctionRecursivelyCall)); LocalContext env(NULL, global); - env->Global()->Set(v8_str("depth"), v8::Integer::New(isolate, 0)); + CHECK(env->Global() + ->Set(env.local(), v8_str("depth"), v8::Integer::New(isolate, 0)) + .FromJust()); call_recursively_script = v8_compile("callScriptRecursively()"); - call_recursively_script->Run(); - call_recursively_script = v8::Handle<Script>(); + call_recursively_script->Run(env.local()).ToLocalChecked(); + call_recursively_script = v8::Local<Script>(); - env->Global()->Set(v8_str("depth"), v8::Integer::New(isolate, 0)); + CHECK(env->Global() + ->Set(env.local(), v8_str("depth"), v8::Integer::New(isolate, 0)) + .FromJust()); CompileRun("callFunctionRecursively()"); } @@ -2022,17 +2256,20 @@ static void ThrowingPropertyHandlerSet( THREADED_TEST(CallbackExceptionRegression) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetHandler(v8::NamedPropertyHandlerConfiguration( ThrowingPropertyHandlerGet, ThrowingPropertyHandlerSet)); LocalContext env; - env->Global()->Set(v8_str("obj"), obj->NewInstance()); - v8::Handle<Value> otto = + CHECK(env->Global() + ->Set(env.local(), v8_str("obj"), + obj->NewInstance(env.local()).ToLocalChecked()) + .FromJust()); + v8::Local<Value> otto = CompileRun("try { with (obj) { otto; } } catch (e) { e; }"); - CHECK(v8_str("otto")->Equals(otto)); - v8::Handle<Value> netto = + CHECK(v8_str("otto")->Equals(env.local(), otto).FromJust()); + v8::Local<Value> netto = CompileRun("try { with (obj) { netto = 4; } } catch (e) { e; }"); - CHECK(v8_str("netto")->Equals(netto)); + CHECK(v8_str("netto")->Equals(env.local(), netto).FromJust()); } @@ -2042,9 +2279,12 @@ THREADED_TEST(FunctionPrototype) { Local<v8::FunctionTemplate> Foo = v8::FunctionTemplate::New(isolate); Foo->PrototypeTemplate()->Set(v8_str("plak"), v8_num(321)); LocalContext env; - env->Global()->Set(v8_str("Foo"), Foo->GetFunction()); + CHECK(env->Global() + ->Set(env.local(), v8_str("Foo"), + Foo->GetFunction(env.local()).ToLocalChecked()) + .FromJust()); Local<Script> script = v8_compile("Foo.prototype.plak"); - CHECK_EQ(script->Run()->Int32Value(), 321); + CHECK_EQ(v8_run_int32value(script), 321); } @@ -2056,11 +2296,14 @@ THREADED_TEST(InternalFields) { Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate(); instance_templ->SetInternalFieldCount(1); - Local<v8::Object> obj = templ->GetFunction()->NewInstance(); + Local<v8::Object> obj = templ->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked(); CHECK_EQ(1, obj->InternalFieldCount()); CHECK(obj->GetInternalField(0)->IsUndefined()); obj->SetInternalField(0, v8_num(17)); - CHECK_EQ(17, obj->GetInternalField(0)->Int32Value()); + CHECK_EQ(17, obj->GetInternalField(0)->Int32Value(env.local()).FromJust()); } @@ -2070,12 +2313,12 @@ THREADED_TEST(GlobalObjectInternalFields) { Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate); global_template->SetInternalFieldCount(1); LocalContext env(NULL, global_template); - v8::Handle<v8::Object> global_proxy = env->Global(); - v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); + v8::Local<v8::Object> global_proxy = env->Global(); + v8::Local<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); CHECK_EQ(1, global->InternalFieldCount()); CHECK(global->GetInternalField(0)->IsUndefined()); global->SetInternalField(0, v8_num(17)); - CHECK_EQ(17, global->GetInternalField(0)->Int32Value()); + CHECK_EQ(17, global->GetInternalField(0)->Int32Value(env.local()).FromJust()); } @@ -2084,12 +2327,12 @@ THREADED_TEST(GlobalObjectHasRealIndexedProperty) { v8::HandleScope scope(CcTest::isolate()); v8::Local<v8::Object> global = env->Global(); - global->Set(0, v8::String::NewFromUtf8(CcTest::isolate(), "value")); - CHECK(global->HasRealIndexedProperty(0)); + CHECK(global->Set(env.local(), 0, v8_str("value")).FromJust()); + CHECK(global->HasRealIndexedProperty(env.local(), 0).FromJust()); } -static void CheckAlignedPointerInInternalField(Handle<v8::Object> obj, +static void CheckAlignedPointerInInternalField(Local<v8::Object> obj, void* value) { CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1)); obj->SetAlignedPointerInInternalField(0, value); @@ -2106,7 +2349,10 @@ THREADED_TEST(InternalFieldsAlignedPointers) { Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate(); instance_templ->SetInternalFieldCount(1); - Local<v8::Object> obj = templ->GetFunction()->NewInstance(); + Local<v8::Object> obj = templ->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked(); CHECK_EQ(1, obj->InternalFieldCount()); CheckAlignedPointerInInternalField(obj, NULL); @@ -2169,7 +2415,7 @@ THREADED_TEST(EmbedderDataAlignedPointers) { static void CheckEmbedderData(LocalContext* env, int index, - v8::Handle<Value> data) { + v8::Local<Value> data) { (*env)->SetEmbedderData(index, data); CHECK((*env)->GetEmbedderData(index)->StrictEquals(data)); } @@ -2180,25 +2426,13 @@ THREADED_TEST(EmbedderData) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - CheckEmbedderData( - &env, 3, v8::String::NewFromUtf8(isolate, "The quick brown fox jumps")); - CheckEmbedderData(&env, 2, - v8::String::NewFromUtf8(isolate, "over the lazy dog.")); + CheckEmbedderData(&env, 3, v8_str("The quick brown fox jumps")); + CheckEmbedderData(&env, 2, v8_str("over the lazy dog.")); CheckEmbedderData(&env, 1, v8::Number::New(isolate, 1.2345)); CheckEmbedderData(&env, 0, v8::Boolean::New(isolate, true)); } -THREADED_TEST(GetIsolate) { - LocalContext env; - v8::Isolate* isolate = env->GetIsolate(); - v8::HandleScope scope(isolate); - Local<v8::Object> obj = v8::Object::New(isolate); - CHECK_EQ(isolate, obj->GetIsolate()); - CHECK_EQ(isolate, CcTest::global()->GetIsolate()); -} - - THREADED_TEST(IdentityHash) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); @@ -2249,9 +2483,11 @@ void GlobalProxyIdentityHash(bool set_in_js) { v8::Isolate* isolate = env->GetIsolate(); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); v8::HandleScope scope(isolate); - Handle<Object> global_proxy = env->Global(); + Local<Object> global_proxy = env->Global(); i::Handle<i::Object> i_global_proxy = v8::Utils::OpenHandle(*global_proxy); - env->Global()->Set(v8_str("global"), global_proxy); + CHECK(env->Global() + ->Set(env.local(), v8_str("global"), global_proxy) + .FromJust()); i::Handle<i::Object> original_hash; if (set_in_js) { CompileRun("var m = new Set(); m.add(global);"); @@ -2268,7 +2504,7 @@ void GlobalProxyIdentityHash(bool set_in_js) { CHECK_EQ(hash1, hash2); { // Re-attach global proxy to a new context, hash should stay the same. - LocalContext env2(NULL, Handle<ObjectTemplate>(), global_proxy); + LocalContext env2(NULL, Local<ObjectTemplate>(), global_proxy); int hash3 = global_proxy->GetIdentityHash(); CHECK_EQ(hash1, hash3); } @@ -2297,7 +2533,7 @@ TEST(SymbolIdentityHash) { } { - v8::Handle<v8::Symbol> js_symbol = + v8::Local<v8::Symbol> js_symbol = CompileRun("Symbol('foo')").As<v8::Symbol>(); int hash = js_symbol->GetIdentityHash(); int hash1 = js_symbol->GetIdentityHash(); @@ -2314,7 +2550,7 @@ TEST(StringIdentityHash) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - Local<v8::String> str = v8::String::NewFromUtf8(isolate, "str1"); + Local<v8::String> str = v8_str("str1"); int hash = str->GetIdentityHash(); int hash1 = str->GetIdentityHash(); CHECK_EQ(hash, hash1); @@ -2322,7 +2558,7 @@ TEST(StringIdentityHash) { int hash3 = str->GetIdentityHash(); CHECK_EQ(hash, hash3); - Local<v8::String> str2 = v8::String::NewFromUtf8(isolate, "str1"); + Local<v8::String> str2 = v8_str("str1"); int hash4 = str2->GetIdentityHash(); CHECK_EQ(hash, hash4); } @@ -2345,92 +2581,145 @@ THREADED_TEST(SymbolProperties) { CHECK(sym2->IsSymbol()); CHECK(!obj->IsSymbol()); - CHECK(sym1->Equals(sym1)); - CHECK(sym2->Equals(sym2)); - CHECK(!sym1->Equals(sym2)); - CHECK(!sym2->Equals(sym1)); + CHECK(sym1->Equals(env.local(), sym1).FromJust()); + CHECK(sym2->Equals(env.local(), sym2).FromJust()); + CHECK(!sym1->Equals(env.local(), sym2).FromJust()); + CHECK(!sym2->Equals(env.local(), sym1).FromJust()); CHECK(sym1->StrictEquals(sym1)); CHECK(sym2->StrictEquals(sym2)); CHECK(!sym1->StrictEquals(sym2)); CHECK(!sym2->StrictEquals(sym1)); - CHECK(sym2->Name()->Equals(v8_str("my-symbol"))); + CHECK(sym2->Name()->Equals(env.local(), v8_str("my-symbol")).FromJust()); v8::Local<v8::Value> sym_val = sym2; CHECK(sym_val->IsSymbol()); - CHECK(sym_val->Equals(sym2)); + CHECK(sym_val->Equals(env.local(), sym2).FromJust()); CHECK(sym_val->StrictEquals(sym2)); - CHECK(v8::Symbol::Cast(*sym_val)->Equals(sym2)); + CHECK(v8::Symbol::Cast(*sym_val)->Equals(env.local(), sym2).FromJust()); v8::Local<v8::Value> sym_obj = v8::SymbolObject::New(isolate, sym2); CHECK(sym_obj->IsSymbolObject()); CHECK(!sym2->IsSymbolObject()); CHECK(!obj->IsSymbolObject()); - CHECK(sym_obj->Equals(sym2)); + CHECK(sym_obj->Equals(env.local(), sym2).FromJust()); CHECK(!sym_obj->StrictEquals(sym2)); - CHECK(v8::SymbolObject::Cast(*sym_obj)->Equals(sym_obj)); - CHECK(v8::SymbolObject::Cast(*sym_obj)->ValueOf()->Equals(sym2)); + CHECK(v8::SymbolObject::Cast(*sym_obj) + ->Equals(env.local(), sym_obj) + .FromJust()); + CHECK(v8::SymbolObject::Cast(*sym_obj) + ->ValueOf() + ->Equals(env.local(), sym2) + .FromJust()); // Make sure delete of a non-existent symbol property works. - CHECK(obj->Delete(sym1)); - CHECK(!obj->Has(sym1)); - - CHECK(obj->Set(sym1, v8::Integer::New(isolate, 1503))); - CHECK(obj->Has(sym1)); - CHECK_EQ(1503, obj->Get(sym1)->Int32Value()); - CHECK(obj->Set(sym1, v8::Integer::New(isolate, 2002))); - CHECK(obj->Has(sym1)); - CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); - CHECK_EQ(v8::None, obj->GetPropertyAttributes(sym1)); - - CHECK_EQ(0u, obj->GetOwnPropertyNames()->Length()); - unsigned num_props = obj->GetPropertyNames()->Length(); - CHECK(obj->Set(v8::String::NewFromUtf8(isolate, "bla"), - v8::Integer::New(isolate, 20))); - CHECK_EQ(1u, obj->GetOwnPropertyNames()->Length()); - CHECK_EQ(num_props + 1, obj->GetPropertyNames()->Length()); + CHECK(obj->Delete(env.local(), sym1).FromJust()); + CHECK(!obj->Has(env.local(), sym1).FromJust()); + + CHECK( + obj->Set(env.local(), sym1, v8::Integer::New(isolate, 1503)).FromJust()); + CHECK(obj->Has(env.local(), sym1).FromJust()); + CHECK_EQ(1503, obj->Get(env.local(), sym1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK( + obj->Set(env.local(), sym1, v8::Integer::New(isolate, 2002)).FromJust()); + CHECK(obj->Has(env.local(), sym1).FromJust()); + CHECK_EQ(2002, obj->Get(env.local(), sym1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(v8::None, obj->GetPropertyAttributes(env.local(), sym1).FromJust()); + + CHECK_EQ(0u, + obj->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); + unsigned num_props = + obj->GetPropertyNames(env.local()).ToLocalChecked()->Length(); + CHECK(obj->Set(env.local(), v8_str("bla"), v8::Integer::New(isolate, 20)) + .FromJust()); + CHECK_EQ(1u, + obj->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); + CHECK_EQ(num_props + 1, + obj->GetPropertyNames(env.local()).ToLocalChecked()->Length()); CcTest::heap()->CollectAllGarbage(); - CHECK(obj->SetAccessor(sym3, SymbolAccessorGetter, SymbolAccessorSetter)); - CHECK(obj->Get(sym3)->IsUndefined()); - CHECK(obj->Set(sym3, v8::Integer::New(isolate, 42))); - CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42))); - CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3")) - ->Equals(v8::Integer::New(isolate, 42))); + CHECK(obj->SetAccessor(env.local(), sym3, SymbolAccessorGetter, + SymbolAccessorSetter) + .FromJust()); + CHECK(obj->Get(env.local(), sym3).ToLocalChecked()->IsUndefined()); + CHECK(obj->Set(env.local(), sym3, v8::Integer::New(isolate, 42)).FromJust()); + CHECK(obj->Get(env.local(), sym3) + .ToLocalChecked() + ->Equals(env.local(), v8::Integer::New(isolate, 42)) + .FromJust()); + CHECK(obj->Get(env.local(), v8_str("accessor_sym3")) + .ToLocalChecked() + ->Equals(env.local(), v8::Integer::New(isolate, 42)) + .FromJust()); // Add another property and delete it afterwards to force the object in // slow case. - CHECK(obj->Set(sym2, v8::Integer::New(isolate, 2008))); - CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); - CHECK_EQ(2008, obj->Get(sym2)->Int32Value()); - CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); - CHECK_EQ(2u, obj->GetOwnPropertyNames()->Length()); - - CHECK(obj->Has(sym1)); - CHECK(obj->Has(sym2)); - CHECK(obj->Has(sym3)); - CHECK(obj->Has(v8::String::NewFromUtf8(isolate, "accessor_sym3"))); - CHECK(obj->Delete(sym2)); - CHECK(obj->Has(sym1)); - CHECK(!obj->Has(sym2)); - CHECK(obj->Has(sym3)); - CHECK(obj->Has(v8::String::NewFromUtf8(isolate, "accessor_sym3"))); - CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); - CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42))); - CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3")) - ->Equals(v8::Integer::New(isolate, 42))); - CHECK_EQ(2u, obj->GetOwnPropertyNames()->Length()); + CHECK( + obj->Set(env.local(), sym2, v8::Integer::New(isolate, 2008)).FromJust()); + CHECK_EQ(2002, obj->Get(env.local(), sym1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(2008, obj->Get(env.local(), sym2) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(2002, obj->Get(env.local(), sym1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(2u, + obj->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); + + CHECK(obj->Has(env.local(), sym1).FromJust()); + CHECK(obj->Has(env.local(), sym2).FromJust()); + CHECK(obj->Has(env.local(), sym3).FromJust()); + CHECK(obj->Has(env.local(), v8_str("accessor_sym3")).FromJust()); + CHECK(obj->Delete(env.local(), sym2).FromJust()); + CHECK(obj->Has(env.local(), sym1).FromJust()); + CHECK(!obj->Has(env.local(), sym2).FromJust()); + CHECK(obj->Has(env.local(), sym3).FromJust()); + CHECK(obj->Has(env.local(), v8_str("accessor_sym3")).FromJust()); + CHECK_EQ(2002, obj->Get(env.local(), sym1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK(obj->Get(env.local(), sym3) + .ToLocalChecked() + ->Equals(env.local(), v8::Integer::New(isolate, 42)) + .FromJust()); + CHECK(obj->Get(env.local(), v8_str("accessor_sym3")) + .ToLocalChecked() + ->Equals(env.local(), v8::Integer::New(isolate, 42)) + .FromJust()); + CHECK_EQ(2u, + obj->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); // Symbol properties are inherited. v8::Local<v8::Object> child = v8::Object::New(isolate); - child->SetPrototype(obj); - CHECK(child->Has(sym1)); - CHECK_EQ(2002, child->Get(sym1)->Int32Value()); - CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42))); - CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3")) - ->Equals(v8::Integer::New(isolate, 42))); - CHECK_EQ(0u, child->GetOwnPropertyNames()->Length()); + CHECK(child->SetPrototype(env.local(), obj).FromJust()); + CHECK(child->Has(env.local(), sym1).FromJust()); + CHECK_EQ(2002, child->Get(env.local(), sym1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK(obj->Get(env.local(), sym3) + .ToLocalChecked() + ->Equals(env.local(), v8::Integer::New(isolate, 42)) + .FromJust()); + CHECK(obj->Get(env.local(), v8_str("accessor_sym3")) + .ToLocalChecked() + ->Equals(env.local(), v8::Integer::New(isolate, 42)) + .FromJust()); + CHECK_EQ(0u, + child->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); } @@ -2442,9 +2731,110 @@ THREADED_TEST(SymbolTemplateProperties) { v8::Local<v8::Name> name = v8::Symbol::New(isolate); CHECK(!name.IsEmpty()); foo->PrototypeTemplate()->Set(name, v8::FunctionTemplate::New(isolate)); - v8::Local<v8::Object> new_instance = foo->InstanceTemplate()->NewInstance(); + v8::Local<v8::Object> new_instance = + foo->InstanceTemplate()->NewInstance(env.local()).ToLocalChecked(); CHECK(!new_instance.IsEmpty()); - CHECK(new_instance->Has(name)); + CHECK(new_instance->Has(env.local(), name).FromJust()); +} + + +THREADED_TEST(PrivatePropertiesOnProxies) { + i::FLAG_harmony_proxies = true; + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + + v8::Local<v8::Object> target = CompileRun("({})").As<v8::Object>(); + v8::Local<v8::Object> handler = CompileRun("({})").As<v8::Object>(); + + v8::Local<v8::Proxy> proxy = + v8::Proxy::New(env.local(), target, handler).ToLocalChecked(); + + v8::Local<v8::Private> priv1 = v8::Private::New(isolate); + v8::Local<v8::Private> priv2 = + v8::Private::New(isolate, v8_str("my-private")); + + CcTest::heap()->CollectAllGarbage(); + + CHECK(priv2->Name() + ->Equals(env.local(), + v8::String::NewFromUtf8(isolate, "my-private", + v8::NewStringType::kNormal) + .ToLocalChecked()) + .FromJust()); + + // Make sure delete of a non-existent private symbol property works. + proxy->DeletePrivate(env.local(), priv1).FromJust(); + CHECK(!proxy->HasPrivate(env.local(), priv1).FromJust()); + + CHECK(proxy->SetPrivate(env.local(), priv1, v8::Integer::New(isolate, 1503)) + .FromJust()); + CHECK(proxy->HasPrivate(env.local(), priv1).FromJust()); + CHECK_EQ(1503, proxy->GetPrivate(env.local(), priv1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK(proxy->SetPrivate(env.local(), priv1, v8::Integer::New(isolate, 2002)) + .FromJust()); + CHECK(proxy->HasPrivate(env.local(), priv1).FromJust()); + CHECK_EQ(2002, proxy->GetPrivate(env.local(), priv1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + + CHECK_EQ(0u, + proxy->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); + unsigned num_props = + proxy->GetPropertyNames(env.local()).ToLocalChecked()->Length(); + CHECK(proxy->Set(env.local(), v8::String::NewFromUtf8( + isolate, "bla", v8::NewStringType::kNormal) + .ToLocalChecked(), + v8::Integer::New(isolate, 20)) + .FromJust()); + CHECK_EQ(1u, + proxy->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); + CHECK_EQ(num_props + 1, + proxy->GetPropertyNames(env.local()).ToLocalChecked()->Length()); + + CcTest::heap()->CollectAllGarbage(); + + // Add another property and delete it afterwards to force the object in + // slow case. + CHECK(proxy->SetPrivate(env.local(), priv2, v8::Integer::New(isolate, 2008)) + .FromJust()); + CHECK_EQ(2002, proxy->GetPrivate(env.local(), priv1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(2008, proxy->GetPrivate(env.local(), priv2) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(2002, proxy->GetPrivate(env.local(), priv1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(1u, + proxy->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); + + CHECK(proxy->HasPrivate(env.local(), priv1).FromJust()); + CHECK(proxy->HasPrivate(env.local(), priv2).FromJust()); + CHECK(proxy->DeletePrivate(env.local(), priv2).FromJust()); + CHECK(proxy->HasPrivate(env.local(), priv1).FromJust()); + CHECK(!proxy->HasPrivate(env.local(), priv2).FromJust()); + CHECK_EQ(2002, proxy->GetPrivate(env.local(), priv1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(1u, + proxy->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); + + // Private properties are not inherited (for the time being). + v8::Local<v8::Object> child = v8::Object::New(isolate); + CHECK(child->SetPrototype(env.local(), proxy).FromJust()); + CHECK(!child->HasPrivate(env.local(), priv1).FromJust()); + CHECK_EQ(0u, + child->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); } @@ -2460,7 +2850,12 @@ THREADED_TEST(PrivateProperties) { CcTest::heap()->CollectAllGarbage(); - CHECK(priv2->Name()->Equals(v8::String::NewFromUtf8(isolate, "my-private"))); + CHECK(priv2->Name() + ->Equals(env.local(), + v8::String::NewFromUtf8(isolate, "my-private", + v8::NewStringType::kNormal) + .ToLocalChecked()) + .FromJust()); // Make sure delete of a non-existent private symbol property works. obj->DeletePrivate(env.local(), priv1).FromJust(); @@ -2469,20 +2864,31 @@ THREADED_TEST(PrivateProperties) { CHECK(obj->SetPrivate(env.local(), priv1, v8::Integer::New(isolate, 1503)) .FromJust()); CHECK(obj->HasPrivate(env.local(), priv1).FromJust()); - CHECK_EQ(1503, - obj->GetPrivate(env.local(), priv1).ToLocalChecked()->Int32Value()); + CHECK_EQ(1503, obj->GetPrivate(env.local(), priv1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CHECK(obj->SetPrivate(env.local(), priv1, v8::Integer::New(isolate, 2002)) .FromJust()); CHECK(obj->HasPrivate(env.local(), priv1).FromJust()); - CHECK_EQ(2002, - obj->GetPrivate(env.local(), priv1).ToLocalChecked()->Int32Value()); - - CHECK_EQ(0u, obj->GetOwnPropertyNames()->Length()); - unsigned num_props = obj->GetPropertyNames()->Length(); - CHECK(obj->Set(v8::String::NewFromUtf8(isolate, "bla"), - v8::Integer::New(isolate, 20))); - CHECK_EQ(1u, obj->GetOwnPropertyNames()->Length()); - CHECK_EQ(num_props + 1, obj->GetPropertyNames()->Length()); + CHECK_EQ(2002, obj->GetPrivate(env.local(), priv1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + + CHECK_EQ(0u, + obj->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); + unsigned num_props = + obj->GetPropertyNames(env.local()).ToLocalChecked()->Length(); + CHECK(obj->Set(env.local(), v8::String::NewFromUtf8( + isolate, "bla", v8::NewStringType::kNormal) + .ToLocalChecked(), + v8::Integer::New(isolate, 20)) + .FromJust()); + CHECK_EQ(1u, + obj->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); + CHECK_EQ(num_props + 1, + obj->GetPropertyNames(env.local()).ToLocalChecked()->Length()); CcTest::heap()->CollectAllGarbage(); @@ -2490,28 +2896,39 @@ THREADED_TEST(PrivateProperties) { // slow case. CHECK(obj->SetPrivate(env.local(), priv2, v8::Integer::New(isolate, 2008)) .FromJust()); - CHECK_EQ(2002, - obj->GetPrivate(env.local(), priv1).ToLocalChecked()->Int32Value()); - CHECK_EQ(2008, - obj->GetPrivate(env.local(), priv2).ToLocalChecked()->Int32Value()); - CHECK_EQ(2002, - obj->GetPrivate(env.local(), priv1).ToLocalChecked()->Int32Value()); - CHECK_EQ(1u, obj->GetOwnPropertyNames()->Length()); + CHECK_EQ(2002, obj->GetPrivate(env.local(), priv1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(2008, obj->GetPrivate(env.local(), priv2) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(2002, obj->GetPrivate(env.local(), priv1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(1u, + obj->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); CHECK(obj->HasPrivate(env.local(), priv1).FromJust()); CHECK(obj->HasPrivate(env.local(), priv2).FromJust()); CHECK(obj->DeletePrivate(env.local(), priv2).FromJust()); CHECK(obj->HasPrivate(env.local(), priv1).FromJust()); CHECK(!obj->HasPrivate(env.local(), priv2).FromJust()); - CHECK_EQ(2002, - obj->GetPrivate(env.local(), priv1).ToLocalChecked()->Int32Value()); - CHECK_EQ(1u, obj->GetOwnPropertyNames()->Length()); + CHECK_EQ(2002, obj->GetPrivate(env.local(), priv1) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(1u, + obj->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); // Private properties are not inherited (for the time being). v8::Local<v8::Object> child = v8::Object::New(isolate); - child->SetPrototype(obj); + CHECK(child->SetPrototype(env.local(), obj).FromJust()); CHECK(!child->HasPrivate(env.local(), priv1).FromJust()); - CHECK_EQ(0u, child->GetOwnPropertyNames()->Length()); + CHECK_EQ(0u, + child->GetOwnPropertyNames(env.local()).ToLocalChecked()->Length()); } @@ -2534,7 +2951,8 @@ THREADED_TEST(GlobalSymbols) { CHECK(!sym->SameValue(glob)); CompileRun("var sym2 = Symbol.for('my-symbol')"); - v8::Local<Value> sym2 = env->Global()->Get(v8_str("sym2")); + v8::Local<Value> sym2 = + env->Global()->Get(env.local(), v8_str("sym2")).ToLocalChecked(); CHECK(sym2->SameValue(glob)); CHECK(!sym2->SameValue(glob_api)); } @@ -2549,7 +2967,8 @@ static void CheckWellKnownSymbol(v8::Local<v8::Symbol>(*getter)(v8::Isolate*), v8::Local<v8::Symbol> symbol = getter(isolate); std::string script = std::string("var sym = ") + name; CompileRun(script.c_str()); - v8::Local<Value> value = env->Global()->Get(v8_str("sym")); + v8::Local<Value> value = + env->Global()->Get(env.local(), v8_str("sym")).ToLocalChecked(); CHECK(!value.IsEmpty()); CHECK(!symbol.IsEmpty()); @@ -2582,8 +3001,9 @@ THREADED_TEST(GlobalPrivates) { CHECK(!obj->HasPrivate(env.local(), priv).FromJust()); CompileRun("var intern = %CreatePrivateSymbol('my-private')"); - v8::Local<Value> intern = env->Global()->Get(v8_str("intern")); - CHECK(!obj->Has(intern)); + v8::Local<Value> intern = + env->Global()->Get(env.local(), v8_str("intern")).ToLocalChecked(); + CHECK(!obj->Has(env.local(), intern).FromJust()); } @@ -2600,10 +3020,12 @@ class ScopedArrayBufferContents { }; template <typename T> -static void CheckInternalFieldsAreZero(v8::Handle<T> value) { +static void CheckInternalFieldsAreZero(v8::Local<T> value) { CHECK_EQ(T::kInternalFieldCount, value->InternalFieldCount()); for (int i = 0; i < value->InternalFieldCount(); i++) { - CHECK_EQ(0, value->GetInternalField(i)->Int32Value()); + CHECK_EQ(0, value->GetInternalField(i) + ->Int32Value(CcTest::isolate()->GetCurrentContext()) + .FromJust()); } } @@ -2624,24 +3046,24 @@ THREADED_TEST(ArrayBuffer_ApiInternalToExternal) { CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); uint8_t* data = static_cast<uint8_t*>(ab_contents.Data()); - DCHECK(data != NULL); - env->Global()->Set(v8_str("ab"), ab); + CHECK(data != NULL); + CHECK(env->Global()->Set(env.local(), v8_str("ab"), ab).FromJust()); - v8::Handle<v8::Value> result = CompileRun("ab.byteLength"); - CHECK_EQ(1024, result->Int32Value()); + v8::Local<v8::Value> result = CompileRun("ab.byteLength"); + CHECK_EQ(1024, result->Int32Value(env.local()).FromJust()); result = CompileRun( "var u8 = new Uint8Array(ab);" "u8[0] = 0xFF;" "u8[1] = 0xAA;" "u8.length"); - CHECK_EQ(1024, result->Int32Value()); + CHECK_EQ(1024, result->Int32Value(env.local()).FromJust()); CHECK_EQ(0xFF, data[0]); CHECK_EQ(0xAA, data[1]); data[0] = 0xCC; data[1] = 0x11; result = CompileRun("u8[0] + u8[1]"); - CHECK_EQ(0xDD, result->Int32Value()); + CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust()); } @@ -2664,18 +3086,18 @@ THREADED_TEST(ArrayBuffer_JSInternalToExternal) { CHECK(ab1->IsExternal()); result = CompileRun("ab1.byteLength"); - CHECK_EQ(2, result->Int32Value()); + CHECK_EQ(2, result->Int32Value(env.local()).FromJust()); result = CompileRun("u8_a[0]"); - CHECK_EQ(0xAA, result->Int32Value()); + CHECK_EQ(0xAA, result->Int32Value(env.local()).FromJust()); result = CompileRun("u8_a[1]"); - CHECK_EQ(0xFF, result->Int32Value()); + CHECK_EQ(0xFF, result->Int32Value(env.local()).FromJust()); result = CompileRun( "var u8_b = new Uint8Array(ab1);" "u8_b[0] = 0xBB;" "u8_a[0]"); - CHECK_EQ(0xBB, result->Int32Value()); + CHECK_EQ(0xBB, result->Int32Value(env.local()).FromJust()); result = CompileRun("u8_b[1]"); - CHECK_EQ(0xFF, result->Int32Value()); + CHECK_EQ(0xFF, result->Int32Value(env.local()).FromJust()); CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength())); uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data()); @@ -2684,7 +3106,7 @@ THREADED_TEST(ArrayBuffer_JSInternalToExternal) { ab1_data[0] = 0xCC; ab1_data[1] = 0x11; result = CompileRun("u8_a[0] + u8_a[1]"); - CHECK_EQ(0xDD, result->Int32Value()); + CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust()); } @@ -2701,23 +3123,23 @@ THREADED_TEST(ArrayBuffer_External) { CHECK_EQ(100, static_cast<int>(ab3->ByteLength())); CHECK(ab3->IsExternal()); - env->Global()->Set(v8_str("ab3"), ab3); + CHECK(env->Global()->Set(env.local(), v8_str("ab3"), ab3).FromJust()); - v8::Handle<v8::Value> result = CompileRun("ab3.byteLength"); - CHECK_EQ(100, result->Int32Value()); + v8::Local<v8::Value> result = CompileRun("ab3.byteLength"); + CHECK_EQ(100, result->Int32Value(env.local()).FromJust()); result = CompileRun( "var u8_b = new Uint8Array(ab3);" "u8_b[0] = 0xBB;" "u8_b[1] = 0xCC;" "u8_b.length"); - CHECK_EQ(100, result->Int32Value()); + CHECK_EQ(100, result->Int32Value(env.local()).FromJust()); CHECK_EQ(0xBB, my_data[0]); CHECK_EQ(0xCC, my_data[1]); my_data[0] = 0xCC; my_data[1] = 0x11; result = CompileRun("u8_b[0] + u8_b[1]"); - CHECK_EQ(0xDD, result->Int32Value()); + CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust()); } @@ -2739,13 +3161,13 @@ THREADED_TEST(ArrayBuffer_DisableNeuter) { } -static void CheckDataViewIsNeutered(v8::Handle<v8::DataView> dv) { +static void CheckDataViewIsNeutered(v8::Local<v8::DataView> dv) { CHECK_EQ(0, static_cast<int>(dv->ByteLength())); CHECK_EQ(0, static_cast<int>(dv->ByteOffset())); } -static void CheckIsNeutered(v8::Handle<v8::TypedArray> ta) { +static void CheckIsNeutered(v8::Local<v8::TypedArray> ta) { CHECK_EQ(0, static_cast<int>(ta->ByteLength())); CHECK_EQ(0, static_cast<int>(ta->Length())); CHECK_EQ(0, static_cast<int>(ta->ByteOffset())); @@ -2758,16 +3180,16 @@ static void CheckIsTypedArrayVarNeutered(const char* name) { "%s.byteLength == 0 && %s.byteOffset == 0 && %s.length == 0", name, name, name); CHECK(CompileRun(source.start())->IsTrue()); - v8::Handle<v8::TypedArray> ta = - v8::Handle<v8::TypedArray>::Cast(CompileRun(name)); + v8::Local<v8::TypedArray> ta = + v8::Local<v8::TypedArray>::Cast(CompileRun(name)); CheckIsNeutered(ta); } template <typename TypedArray, int kElementSize> -static Handle<TypedArray> CreateAndCheck(Handle<v8::ArrayBuffer> ab, - int byteOffset, int length) { - v8::Handle<TypedArray> ta = TypedArray::New(ab, byteOffset, length); +static Local<TypedArray> CreateAndCheck(Local<v8::ArrayBuffer> ab, + int byteOffset, int length) { + v8::Local<TypedArray> ta = TypedArray::New(ab, byteOffset, length); CheckInternalFieldsAreZero<v8::ArrayBufferView>(ta); CHECK_EQ(byteOffset, static_cast<int>(ta->ByteOffset())); CHECK_EQ(length, static_cast<int>(ta->Length())); @@ -2781,31 +3203,31 @@ THREADED_TEST(ArrayBuffer_NeuteringApi) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, 1024); + v8::Local<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, 1024); - v8::Handle<v8::Uint8Array> u8a = + v8::Local<v8::Uint8Array> u8a = CreateAndCheck<v8::Uint8Array, 1>(buffer, 1, 1023); - v8::Handle<v8::Uint8ClampedArray> u8c = + v8::Local<v8::Uint8ClampedArray> u8c = CreateAndCheck<v8::Uint8ClampedArray, 1>(buffer, 1, 1023); - v8::Handle<v8::Int8Array> i8a = + v8::Local<v8::Int8Array> i8a = CreateAndCheck<v8::Int8Array, 1>(buffer, 1, 1023); - v8::Handle<v8::Uint16Array> u16a = + v8::Local<v8::Uint16Array> u16a = CreateAndCheck<v8::Uint16Array, 2>(buffer, 2, 511); - v8::Handle<v8::Int16Array> i16a = + v8::Local<v8::Int16Array> i16a = CreateAndCheck<v8::Int16Array, 2>(buffer, 2, 511); - v8::Handle<v8::Uint32Array> u32a = + v8::Local<v8::Uint32Array> u32a = CreateAndCheck<v8::Uint32Array, 4>(buffer, 4, 255); - v8::Handle<v8::Int32Array> i32a = + v8::Local<v8::Int32Array> i32a = CreateAndCheck<v8::Int32Array, 4>(buffer, 4, 255); - v8::Handle<v8::Float32Array> f32a = + v8::Local<v8::Float32Array> f32a = CreateAndCheck<v8::Float32Array, 4>(buffer, 4, 255); - v8::Handle<v8::Float64Array> f64a = + v8::Local<v8::Float64Array> f64a = CreateAndCheck<v8::Float64Array, 8>(buffer, 8, 127); - v8::Handle<v8::DataView> dv = v8::DataView::New(buffer, 1, 1023); + v8::Local<v8::DataView> dv = v8::DataView::New(buffer, 1, 1023); CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv); CHECK_EQ(1, static_cast<int>(dv->ByteOffset())); CHECK_EQ(1023, static_cast<int>(dv->ByteLength())); @@ -2844,16 +3266,15 @@ THREADED_TEST(ArrayBuffer_NeuteringScript) { "var f64a = new Float64Array(ab, 8, 127);" "var dv = new DataView(ab, 1, 1023);"); - v8::Handle<v8::ArrayBuffer> ab = + v8::Local<v8::ArrayBuffer> ab = Local<v8::ArrayBuffer>::Cast(CompileRun("ab")); - v8::Handle<v8::DataView> dv = - v8::Handle<v8::DataView>::Cast(CompileRun("dv")); + v8::Local<v8::DataView> dv = v8::Local<v8::DataView>::Cast(CompileRun("dv")); ScopedArrayBufferContents contents(ab->Externalize()); ab->Neuter(); CHECK_EQ(0, static_cast<int>(ab->ByteLength())); - CHECK_EQ(0, CompileRun("ab.byteLength")->Int32Value()); + CHECK_EQ(0, v8_run_int32value(v8_compile("ab.byteLength"))); CheckIsTypedArrayVarNeutered("u8a"); CheckIsTypedArrayVarNeutered("u8c"); @@ -2901,24 +3322,24 @@ THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) { CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); uint8_t* data = static_cast<uint8_t*>(ab_contents.Data()); - DCHECK(data != NULL); - env->Global()->Set(v8_str("ab"), ab); + CHECK(data != NULL); + CHECK(env->Global()->Set(env.local(), v8_str("ab"), ab).FromJust()); - v8::Handle<v8::Value> result = CompileRun("ab.byteLength"); - CHECK_EQ(1024, result->Int32Value()); + v8::Local<v8::Value> result = CompileRun("ab.byteLength"); + CHECK_EQ(1024, result->Int32Value(env.local()).FromJust()); result = CompileRun( "var u8 = new Uint8Array(ab);" "u8[0] = 0xFF;" "u8[1] = 0xAA;" "u8.length"); - CHECK_EQ(1024, result->Int32Value()); + CHECK_EQ(1024, result->Int32Value(env.local()).FromJust()); CHECK_EQ(0xFF, data[0]); CHECK_EQ(0xAA, data[1]); data[0] = 0xCC; data[1] = 0x11; result = CompileRun("u8[0] + u8[1]"); - CHECK_EQ(0xDD, result->Int32Value()); + CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust()); } @@ -2942,18 +3363,18 @@ THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) { CHECK(ab1->IsExternal()); result = CompileRun("ab1.byteLength"); - CHECK_EQ(2, result->Int32Value()); + CHECK_EQ(2, result->Int32Value(env.local()).FromJust()); result = CompileRun("u8_a[0]"); - CHECK_EQ(0xAA, result->Int32Value()); + CHECK_EQ(0xAA, result->Int32Value(env.local()).FromJust()); result = CompileRun("u8_a[1]"); - CHECK_EQ(0xFF, result->Int32Value()); + CHECK_EQ(0xFF, result->Int32Value(env.local()).FromJust()); result = CompileRun( "var u8_b = new Uint8Array(ab1);" "u8_b[0] = 0xBB;" "u8_a[0]"); - CHECK_EQ(0xBB, result->Int32Value()); + CHECK_EQ(0xBB, result->Int32Value(env.local()).FromJust()); result = CompileRun("u8_b[1]"); - CHECK_EQ(0xFF, result->Int32Value()); + CHECK_EQ(0xFF, result->Int32Value(env.local()).FromJust()); CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength())); uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data()); @@ -2962,7 +3383,7 @@ THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) { ab1_data[0] = 0xCC; ab1_data[1] = 0x11; result = CompileRun("u8_a[0] + u8_a[1]"); - CHECK_EQ(0xDD, result->Int32Value()); + CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust()); } @@ -2980,23 +3401,23 @@ THREADED_TEST(SharedArrayBuffer_External) { CHECK_EQ(100, static_cast<int>(ab3->ByteLength())); CHECK(ab3->IsExternal()); - env->Global()->Set(v8_str("ab3"), ab3); + CHECK(env->Global()->Set(env.local(), v8_str("ab3"), ab3).FromJust()); - v8::Handle<v8::Value> result = CompileRun("ab3.byteLength"); - CHECK_EQ(100, result->Int32Value()); + v8::Local<v8::Value> result = CompileRun("ab3.byteLength"); + CHECK_EQ(100, result->Int32Value(env.local()).FromJust()); result = CompileRun( "var u8_b = new Uint8Array(ab3);" "u8_b[0] = 0xBB;" "u8_b[1] = 0xCC;" "u8_b.length"); - CHECK_EQ(100, result->Int32Value()); + CHECK_EQ(100, result->Int32Value(env.local()).FromJust()); CHECK_EQ(0xBB, my_data[0]); CHECK_EQ(0xCC, my_data[1]); my_data[0] = 0xCC; my_data[1] = 0x11; result = CompileRun("u8_b[0] + u8_b[1]"); - CHECK_EQ(0xDD, result->Int32Value()); + CHECK_EQ(0xDD, result->Int32Value(env.local()).FromJust()); } @@ -3018,40 +3439,64 @@ THREADED_TEST(HiddenProperties) { CHECK(obj->SetPrivate(env.local(), key, v8::Integer::New(isolate, 1503)) .FromJust()); - CHECK_EQ(1503, - obj->GetPrivate(env.local(), key).ToLocalChecked()->Int32Value()); + CHECK_EQ(1503, obj->GetPrivate(env.local(), key) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CHECK(obj->SetPrivate(env.local(), key, v8::Integer::New(isolate, 2002)) .FromJust()); - CHECK_EQ(2002, - obj->GetPrivate(env.local(), key).ToLocalChecked()->Int32Value()); + CHECK_EQ(2002, obj->GetPrivate(env.local(), key) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CcTest::heap()->CollectAllGarbage(); // Make sure we do not find the hidden property. - CHECK(!obj->Has(empty)); - CHECK_EQ(2002, - obj->GetPrivate(env.local(), key).ToLocalChecked()->Int32Value()); - CHECK(obj->Get(empty)->IsUndefined()); - CHECK_EQ(2002, - obj->GetPrivate(env.local(), key).ToLocalChecked()->Int32Value()); - CHECK(obj->Set(empty, v8::Integer::New(isolate, 2003))); - CHECK_EQ(2002, - obj->GetPrivate(env.local(), key).ToLocalChecked()->Int32Value()); - CHECK_EQ(2003, obj->Get(empty)->Int32Value()); + CHECK(!obj->Has(env.local(), empty).FromJust()); + CHECK_EQ(2002, obj->GetPrivate(env.local(), key) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK(obj->Get(env.local(), empty).ToLocalChecked()->IsUndefined()); + CHECK_EQ(2002, obj->GetPrivate(env.local(), key) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK( + obj->Set(env.local(), empty, v8::Integer::New(isolate, 2003)).FromJust()); + CHECK_EQ(2002, obj->GetPrivate(env.local(), key) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(2003, obj->Get(env.local(), empty) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CcTest::heap()->CollectAllGarbage(); // Add another property and delete it afterwards to force the object in // slow case. - CHECK(obj->Set(prop_name, v8::Integer::New(isolate, 2008))); - CHECK_EQ(2002, - obj->GetPrivate(env.local(), key).ToLocalChecked()->Int32Value()); - CHECK_EQ(2008, obj->Get(prop_name)->Int32Value()); - CHECK_EQ(2002, - obj->GetPrivate(env.local(), key).ToLocalChecked()->Int32Value()); - CHECK(obj->Delete(prop_name)); - CHECK_EQ(2002, - obj->GetPrivate(env.local(), key).ToLocalChecked()->Int32Value()); + CHECK(obj->Set(env.local(), prop_name, v8::Integer::New(isolate, 2008)) + .FromJust()); + CHECK_EQ(2002, obj->GetPrivate(env.local(), key) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(2008, obj->Get(env.local(), prop_name) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(2002, obj->GetPrivate(env.local(), key) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK(obj->Delete(env.local(), prop_name).FromJust()); + CHECK_EQ(2002, obj->GetPrivate(env.local(), key) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CcTest::heap()->CollectAllGarbage(); @@ -3089,8 +3534,10 @@ THREADED_TEST(Regress97784) { obj->SetPrivate(env.local(), key, v8::Integer::New(env->GetIsolate(), 42)) .FromJust()); ExpectFalse("set_called"); - CHECK_EQ(42, - obj->GetPrivate(env.local(), key).ToLocalChecked()->Int32Value()); + CHECK_EQ(42, obj->GetPrivate(env.local(), key) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); } @@ -3099,9 +3546,9 @@ THREADED_TEST(External) { int x = 3; Local<v8::External> ext = v8::External::New(CcTest::isolate(), &x); LocalContext env; - env->Global()->Set(v8_str("ext"), ext); + CHECK(env->Global()->Set(env.local(), v8_str("ext"), ext).FromJust()); Local<Value> reext_obj = CompileRun("this.ext"); - v8::Handle<v8::External> reext = reext_obj.As<v8::External>(); + v8::Local<v8::External> reext = reext_obj.As<v8::External>(); int* ptr = static_cast<int*>(reext->Value()); CHECK_EQ(x, 3); *ptr = 10; @@ -3397,7 +3844,7 @@ Local<v8::Object> NewObjectForIntKey( v8::Isolate* isolate, const v8::Global<v8::ObjectTemplate>& templ, int key) { auto local = Local<v8::ObjectTemplate>::New(isolate, templ); - auto obj = local->NewInstance(); + auto obj = local->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); obj->SetAlignedPointerInInternalField(0, IntKeyToVoidPointer(key)); return obj; } @@ -3468,10 +3915,10 @@ void TestGlobalValueMap() { map.Set(7, expected); CHECK_EQ(1, static_cast<int>(map.Size())); obj = map.Get(7); - CHECK(expected->Equals(obj)); + CHECK(expected->Equals(env.local(), obj).FromJust()); { typename Map::PersistentValueReference ref = map.GetReference(7); - CHECK(expected->Equals(ref.NewLocal(isolate))); + CHECK(expected->Equals(env.local(), ref.NewLocal(isolate)).FromJust()); } v8::Global<v8::Object> removed = map.Remove(7); CHECK_EQ(0, static_cast<int>(map.Size())); @@ -3488,7 +3935,7 @@ void TestGlobalValueMap() { removed = map.Set(8, v8::Global<v8::Object>(isolate, expected2), &ref); CHECK_EQ(1, static_cast<int>(map.Size())); CHECK(expected == removed); - CHECK(expected2->Equals(ref.NewLocal(isolate))); + CHECK(expected2->Equals(env.local(), ref.NewLocal(isolate)).FromJust()); } } CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count()); @@ -3553,10 +4000,10 @@ TEST(PersistentValueVector) { CHECK(!vector.IsEmpty()); CHECK_EQ(5, static_cast<int>(vector.Size())); CHECK(obj3.IsEmpty()); - CHECK(obj1->Equals(vector.Get(0))); - CHECK(obj1->Equals(vector.Get(2))); - CHECK(obj1->Equals(vector.Get(4))); - CHECK(obj2->Equals(vector.Get(1))); + CHECK(obj1->Equals(env.local(), vector.Get(0)).FromJust()); + CHECK(obj1->Equals(env.local(), vector.Get(2)).FromJust()); + CHECK(obj1->Equals(env.local(), vector.Get(4)).FromJust()); + CHECK(obj2->Equals(env.local(), vector.Get(1)).FromJust()); CHECK_EQ(5 + handle_count, global_handles->global_handles_count()); @@ -3707,9 +4154,11 @@ THREADED_TEST(ApiObjectGroups) { { HandleScope scope(iso); CHECK(Local<Object>::New(iso, g1s2.handle.As<Object>()) - ->Set(0, Local<Value>::New(iso, g2s2.handle))); + ->Set(env.local(), 0, Local<Value>::New(iso, g2s2.handle)) + .FromJust()); CHECK(Local<Object>::New(iso, g2s1.handle.As<Object>()) - ->Set(0, Local<Value>::New(iso, g1s1.handle))); + ->Set(env.local(), 0, Local<Value>::New(iso, g1s1.handle)) + .FromJust()); } { @@ -3783,8 +4232,8 @@ THREADED_TEST(ApiObjectGroupsForSubtypes) { { HandleScope scope(iso); g1s1.handle.Reset(iso, Object::New(iso)); - g1s2.handle.Reset(iso, String::NewFromUtf8(iso, "foo1")); - g1c1.handle.Reset(iso, String::NewFromUtf8(iso, "foo2")); + g1s2.handle.Reset(iso, v8_str("foo1")); + g1c1.handle.Reset(iso, v8_str("foo2")); g1s1.handle.SetWeak(&g1s1, &WeakPointerCallback, v8::WeakCallbackType::kParameter); g1s2.handle.SetWeak(&g1s2, &WeakPointerCallback, @@ -3793,8 +4242,8 @@ THREADED_TEST(ApiObjectGroupsForSubtypes) { v8::WeakCallbackType::kParameter); g2s1.handle.Reset(iso, Object::New(iso)); - g2s2.handle.Reset(iso, String::NewFromUtf8(iso, "foo3")); - g2c1.handle.Reset(iso, String::NewFromUtf8(iso, "foo4")); + g2s2.handle.Reset(iso, v8_str("foo3")); + g2c1.handle.Reset(iso, v8_str("foo4")); g2s1.handle.SetWeak(&g2s1, &WeakPointerCallback, v8::WeakCallbackType::kParameter); g2s2.handle.SetWeak(&g2s2, &WeakPointerCallback, @@ -3810,9 +4259,11 @@ THREADED_TEST(ApiObjectGroupsForSubtypes) { { HandleScope scope(iso); CHECK(Local<Object>::New(iso, g1s1.handle) - ->Set(0, Local<Object>::New(iso, g2s1.handle))); + ->Set(env.local(), 0, Local<Object>::New(iso, g2s1.handle)) + .FromJust()); CHECK(Local<Object>::New(iso, g2s1.handle) - ->Set(0, Local<Object>::New(iso, g1s1.handle))); + ->Set(env.local(), 0, Local<Object>::New(iso, g1s1.handle)) + .FromJust()); } { @@ -4048,15 +4499,18 @@ TEST(ApiObjectGroupsCycleForScavenger) { iso->SetObjectGroupId(g1s1.handle, UniqueId(1)); iso->SetObjectGroupId(g1s2.handle, UniqueId(1)); Local<Object>::New(iso, g1s1.handle.As<Object>()) - ->Set(v8_str("x"), Local<Value>::New(iso, g2s1.handle)); + ->Set(env.local(), v8_str("x"), Local<Value>::New(iso, g2s1.handle)) + .FromJust(); iso->SetObjectGroupId(g2s1.handle, UniqueId(2)); iso->SetObjectGroupId(g2s2.handle, UniqueId(2)); Local<Object>::New(iso, g2s1.handle.As<Object>()) - ->Set(v8_str("x"), Local<Value>::New(iso, g3s1.handle)); + ->Set(env.local(), v8_str("x"), Local<Value>::New(iso, g3s1.handle)) + .FromJust(); iso->SetObjectGroupId(g3s1.handle, UniqueId(3)); iso->SetObjectGroupId(g3s2.handle, UniqueId(3)); Local<Object>::New(iso, g3s1.handle.As<Object>()) - ->Set(v8_str("x"), Local<Value>::New(iso, g1s1.handle)); + ->Set(env.local(), v8_str("x"), Local<Value>::New(iso, g1s1.handle)) + .FromJust(); } v8::internal::Heap* heap = @@ -4083,15 +4537,18 @@ TEST(ApiObjectGroupsCycleForScavenger) { iso->SetObjectGroupId(g1s1.handle, UniqueId(1)); iso->SetObjectGroupId(g1s2.handle, UniqueId(1)); Local<Object>::New(iso, g1s1.handle.As<Object>()) - ->Set(v8_str("x"), Local<Value>::New(iso, g2s1.handle)); + ->Set(env.local(), v8_str("x"), Local<Value>::New(iso, g2s1.handle)) + .FromJust(); iso->SetObjectGroupId(g2s1.handle, UniqueId(2)); iso->SetObjectGroupId(g2s2.handle, UniqueId(2)); Local<Object>::New(iso, g2s1.handle.As<Object>()) - ->Set(v8_str("x"), Local<Value>::New(iso, g3s1.handle)); + ->Set(env.local(), v8_str("x"), Local<Value>::New(iso, g3s1.handle)) + .FromJust(); iso->SetObjectGroupId(g3s1.handle, UniqueId(3)); iso->SetObjectGroupId(g3s2.handle, UniqueId(3)); Local<Object>::New(iso, g3s1.handle.As<Object>()) - ->Set(v8_str("x"), Local<Value>::New(iso, g1s1.handle)); + ->Set(env.local(), v8_str("x"), Local<Value>::New(iso, g1s1.handle)) + .FromJust(); } heap->CollectAllGarbage(); @@ -4106,7 +4563,7 @@ THREADED_TEST(ScriptException) { v8::HandleScope scope(env->GetIsolate()); Local<Script> script = v8_compile("throw 'panama!';"); v8::TryCatch try_catch(env->GetIsolate()); - Local<Value> result = script->Run(); + v8::MaybeLocal<Value> result = script->Run(env.local()); CHECK(result.IsEmpty()); CHECK(try_catch.HasCaught()); String::Utf8Value exception_value(try_catch.Exception()); @@ -4124,19 +4581,26 @@ TEST(TryCatchCustomException) { "(function f() { throw new CustomError(); })();"); CHECK(try_catch.HasCaught()); CHECK(try_catch.Exception() - ->ToObject(isolate) - ->Get(v8_str("a")) - ->Equals(v8_str("b"))); + ->ToObject(env.local()) + .ToLocalChecked() + ->Get(env.local(), v8_str("a")) + .ToLocalChecked() + ->Equals(env.local(), v8_str("b")) + .FromJust()); } bool message_received; -static void check_message_0(v8::Handle<v8::Message> message, - v8::Handle<Value> data) { - CHECK_EQ(5.76, data->NumberValue()); - CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); +static void check_message_0(v8::Local<v8::Message> message, + v8::Local<Value> data) { + CHECK_EQ(5.76, data->NumberValue(CcTest::isolate()->GetCurrentContext()) + .FromJust()); + CHECK_EQ(6.75, message->GetScriptOrigin() + .ResourceName() + ->NumberValue(CcTest::isolate()->GetCurrentContext()) + .FromJust()); CHECK(!message->IsSharedCrossOrigin()); message_received = true; } @@ -4147,19 +4611,20 @@ THREADED_TEST(MessageHandler0) { v8::HandleScope scope(CcTest::isolate()); CHECK(!message_received); LocalContext context; - v8::V8::AddMessageListener(check_message_0, v8_num(5.76)); - v8::Handle<v8::Script> script = CompileWithOrigin("throw 'error'", "6.75"); - script->Run(); + CcTest::isolate()->AddMessageListener(check_message_0, v8_num(5.76)); + v8::Local<v8::Script> script = CompileWithOrigin("throw 'error'", "6.75"); + CHECK(script->Run(context.local()).IsEmpty()); CHECK(message_received); // clear out the message listener - v8::V8::RemoveMessageListeners(check_message_0); + CcTest::isolate()->RemoveMessageListeners(check_message_0); } -static void check_message_1(v8::Handle<v8::Message> message, - v8::Handle<Value> data) { +static void check_message_1(v8::Local<v8::Message> message, + v8::Local<Value> data) { CHECK(data->IsNumber()); - CHECK_EQ(1337, data->Int32Value()); + CHECK_EQ(1337, + data->Int32Value(CcTest::isolate()->GetCurrentContext()).FromJust()); CHECK(!message->IsSharedCrossOrigin()); message_received = true; } @@ -4169,17 +4634,17 @@ TEST(MessageHandler1) { message_received = false; v8::HandleScope scope(CcTest::isolate()); CHECK(!message_received); - v8::V8::AddMessageListener(check_message_1); + CcTest::isolate()->AddMessageListener(check_message_1); LocalContext context; CompileRun("throw 1337;"); CHECK(message_received); // clear out the message listener - v8::V8::RemoveMessageListeners(check_message_1); + CcTest::isolate()->RemoveMessageListeners(check_message_1); } -static void check_message_2(v8::Handle<v8::Message> message, - v8::Handle<Value> data) { +static void check_message_2(v8::Local<v8::Message> message, + v8::Local<Value> data) { LocalContext context; CHECK(data->IsObject()); v8::Local<v8::Value> hidden_property = @@ -4188,7 +4653,9 @@ static void check_message_2(v8::Handle<v8::Message> message, context.local(), v8::Private::ForApi(CcTest::isolate(), v8_str("hidden key"))) .ToLocalChecked(); - CHECK(v8_str("hidden value")->Equals(hidden_property)); + CHECK(v8_str("hidden value") + ->Equals(context.local(), hidden_property) + .FromJust()); CHECK(!message->IsSharedCrossOrigin()); message_received = true; } @@ -4198,7 +4665,7 @@ TEST(MessageHandler2) { message_received = false; v8::HandleScope scope(CcTest::isolate()); CHECK(!message_received); - v8::V8::AddMessageListener(check_message_2); + CcTest::isolate()->AddMessageListener(check_message_2); LocalContext context; v8::Local<v8::Value> error = v8::Exception::Error(v8_str("custom error")); v8::Object::Cast(*error) @@ -4206,22 +4673,30 @@ TEST(MessageHandler2) { v8::Private::ForApi(CcTest::isolate(), v8_str("hidden key")), v8_str("hidden value")) .FromJust(); - context->Global()->Set(v8_str("error"), error); + CHECK(context->Global() + ->Set(context.local(), v8_str("error"), error) + .FromJust()); CompileRun("throw error;"); CHECK(message_received); // clear out the message listener - v8::V8::RemoveMessageListeners(check_message_2); + CcTest::isolate()->RemoveMessageListeners(check_message_2); } -static void check_message_3(v8::Handle<v8::Message> message, - v8::Handle<Value> data) { +static void check_message_3(v8::Local<v8::Message> message, + v8::Local<Value> data) { CHECK(message->IsSharedCrossOrigin()); CHECK(message->GetScriptOrigin().Options().IsSharedCrossOrigin()); CHECK(message->GetScriptOrigin().Options().IsEmbedderDebugScript()); CHECK(message->GetScriptOrigin().Options().IsOpaque()); - CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); - CHECK_EQ(7.40, message->GetScriptOrigin().SourceMapUrl()->NumberValue()); + CHECK_EQ(6.75, message->GetScriptOrigin() + .ResourceName() + ->NumberValue(CcTest::isolate()->GetCurrentContext()) + .FromJust()); + CHECK_EQ(7.40, message->GetScriptOrigin() + .SourceMapUrl() + ->NumberValue(CcTest::isolate()->GetCurrentContext()) + .FromJust()); message_received = true; } @@ -4231,25 +4706,29 @@ TEST(MessageHandler3) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); CHECK(!message_received); - v8::V8::AddMessageListener(check_message_3); + isolate->AddMessageListener(check_message_3); LocalContext context; v8::ScriptOrigin origin = v8::ScriptOrigin( v8_str("6.75"), v8::Integer::New(isolate, 1), - v8::Integer::New(isolate, 2), v8::True(isolate), Handle<v8::Integer>(), + v8::Integer::New(isolate, 2), v8::True(isolate), Local<v8::Integer>(), v8::True(isolate), v8_str("7.40"), v8::True(isolate)); - v8::Handle<v8::Script> script = - Script::Compile(v8_str("throw 'error'"), &origin); - script->Run(); + v8::Local<v8::Script> script = + Script::Compile(context.local(), v8_str("throw 'error'"), &origin) + .ToLocalChecked(); + CHECK(script->Run(context.local()).IsEmpty()); CHECK(message_received); // clear out the message listener - v8::V8::RemoveMessageListeners(check_message_3); + isolate->RemoveMessageListeners(check_message_3); } -static void check_message_4(v8::Handle<v8::Message> message, - v8::Handle<Value> data) { +static void check_message_4(v8::Local<v8::Message> message, + v8::Local<Value> data) { CHECK(!message->IsSharedCrossOrigin()); - CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); + CHECK_EQ(6.75, message->GetScriptOrigin() + .ResourceName() + ->NumberValue(CcTest::isolate()->GetCurrentContext()) + .FromJust()); message_received = true; } @@ -4259,32 +4738,39 @@ TEST(MessageHandler4) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); CHECK(!message_received); - v8::V8::AddMessageListener(check_message_4); + isolate->AddMessageListener(check_message_4); LocalContext context; v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1), v8::Integer::New(isolate, 2), v8::False(isolate)); - v8::Handle<v8::Script> script = - Script::Compile(v8_str("throw 'error'"), &origin); - script->Run(); + v8::Local<v8::Script> script = + Script::Compile(context.local(), v8_str("throw 'error'"), &origin) + .ToLocalChecked(); + CHECK(script->Run(context.local()).IsEmpty()); CHECK(message_received); // clear out the message listener - v8::V8::RemoveMessageListeners(check_message_4); + isolate->RemoveMessageListeners(check_message_4); } -static void check_message_5a(v8::Handle<v8::Message> message, - v8::Handle<Value> data) { +static void check_message_5a(v8::Local<v8::Message> message, + v8::Local<Value> data) { CHECK(message->IsSharedCrossOrigin()); - CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); + CHECK_EQ(6.75, message->GetScriptOrigin() + .ResourceName() + ->NumberValue(CcTest::isolate()->GetCurrentContext()) + .FromJust()); message_received = true; } -static void check_message_5b(v8::Handle<v8::Message> message, - v8::Handle<Value> data) { +static void check_message_5b(v8::Local<v8::Message> message, + v8::Local<Value> data) { CHECK(!message->IsSharedCrossOrigin()); - CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); + CHECK_EQ(6.75, message->GetScriptOrigin() + .ResourceName() + ->NumberValue(CcTest::isolate()->GetCurrentContext()) + .FromJust()); message_received = true; } @@ -4294,28 +4780,30 @@ TEST(MessageHandler5) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); CHECK(!message_received); - v8::V8::AddMessageListener(check_message_5a); + isolate->AddMessageListener(check_message_5a); LocalContext context; v8::ScriptOrigin origin1 = v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1), v8::Integer::New(isolate, 2), v8::True(isolate)); - v8::Handle<v8::Script> script = - Script::Compile(v8_str("throw 'error'"), &origin1); - script->Run(); + v8::Local<v8::Script> script = + Script::Compile(context.local(), v8_str("throw 'error'"), &origin1) + .ToLocalChecked(); + CHECK(script->Run(context.local()).IsEmpty()); CHECK(message_received); // clear out the message listener - v8::V8::RemoveMessageListeners(check_message_5a); + isolate->RemoveMessageListeners(check_message_5a); message_received = false; - v8::V8::AddMessageListener(check_message_5b); + isolate->AddMessageListener(check_message_5b); v8::ScriptOrigin origin2 = v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1), v8::Integer::New(isolate, 2), v8::False(isolate)); - script = Script::Compile(v8_str("throw 'error'"), &origin2); - script->Run(); + script = Script::Compile(context.local(), v8_str("throw 'error'"), &origin2) + .ToLocalChecked(); + CHECK(script->Run(context.local()).IsEmpty()); CHECK(message_received); // clear out the message listener - v8::V8::RemoveMessageListeners(check_message_5b); + isolate->RemoveMessageListeners(check_message_5b); } @@ -4333,7 +4821,7 @@ TEST(NativeWeakMap) { CHECK(weak_map->Get(local1)->IsUndefined()); weak_map->Set(local1, value); CHECK(weak_map->Has(local1)); - CHECK(value->Equals(weak_map->Get(local1))); + CHECK(value->Equals(env.local(), weak_map->Get(local1)).FromJust()); WeakCallCounter counter(1234); WeakCallCounterAndPersistent<Value> o1(&counter); @@ -4358,18 +4846,24 @@ TEST(NativeWeakMap) { CHECK(weak_map->Has(obj2)); CHECK(weak_map->Has(sym1)); - CHECK(value->Equals(weak_map->Get(local1))); - CHECK(value->Equals(weak_map->Get(obj1))); - CHECK(value->Equals(weak_map->Get(obj2))); - CHECK(value->Equals(weak_map->Get(sym1))); + CHECK(value->Equals(env.local(), weak_map->Get(local1)).FromJust()); + CHECK(value->Equals(env.local(), weak_map->Get(obj1)).FromJust()); + CHECK(value->Equals(env.local(), weak_map->Get(obj2)).FromJust()); + CHECK(value->Equals(env.local(), weak_map->Get(sym1)).FromJust()); } CcTest::heap()->CollectAllGarbage(); { HandleScope scope(isolate); - CHECK(value->Equals(weak_map->Get(local1))); - CHECK(value->Equals(weak_map->Get(Local<Value>::New(isolate, o1.handle)))); - CHECK(value->Equals(weak_map->Get(Local<Value>::New(isolate, o2.handle)))); - CHECK(value->Equals(weak_map->Get(Local<Value>::New(isolate, s1.handle)))); + CHECK(value->Equals(env.local(), weak_map->Get(local1)).FromJust()); + CHECK(value->Equals(env.local(), + weak_map->Get(Local<Value>::New(isolate, o1.handle))) + .FromJust()); + CHECK(value->Equals(env.local(), + weak_map->Get(Local<Value>::New(isolate, o2.handle))) + .FromJust()); + CHECK(value->Equals(env.local(), + weak_map->Get(Local<Value>::New(isolate, s1.handle))) + .FromJust()); } o1.handle.SetWeak(&o1, &WeakPointerCallback, @@ -4386,7 +4880,7 @@ TEST(NativeWeakMap) { CHECK(o2.handle.IsEmpty()); CHECK(s1.handle.IsEmpty()); - CHECK(value->Equals(weak_map->Get(local1))); + CHECK(value->Equals(env.local(), weak_map->Get(local1)).FromJust()); CHECK(weak_map->Delete(local1)); CHECK(!weak_map->Has(local1)); CHECK(weak_map->Get(local1)->IsUndefined()); @@ -4397,30 +4891,71 @@ THREADED_TEST(GetSetProperty) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - context->Global()->Set(v8_str("foo"), v8_num(14)); - context->Global()->Set(v8_str("12"), v8_num(92)); - context->Global()->Set(v8::Integer::New(isolate, 16), v8_num(32)); - context->Global()->Set(v8_num(13), v8_num(56)); + CHECK(context->Global() + ->Set(context.local(), v8_str("foo"), v8_num(14)) + .FromJust()); + CHECK(context->Global() + ->Set(context.local(), v8_str("12"), v8_num(92)) + .FromJust()); + CHECK(context->Global() + ->Set(context.local(), v8::Integer::New(isolate, 16), v8_num(32)) + .FromJust()); + CHECK(context->Global() + ->Set(context.local(), v8_num(13), v8_num(56)) + .FromJust()); Local<Value> foo = CompileRun("this.foo"); - CHECK_EQ(14, foo->Int32Value()); + CHECK_EQ(14, foo->Int32Value(context.local()).FromJust()); Local<Value> twelve = CompileRun("this[12]"); - CHECK_EQ(92, twelve->Int32Value()); + CHECK_EQ(92, twelve->Int32Value(context.local()).FromJust()); Local<Value> sixteen = CompileRun("this[16]"); - CHECK_EQ(32, sixteen->Int32Value()); + CHECK_EQ(32, sixteen->Int32Value(context.local()).FromJust()); Local<Value> thirteen = CompileRun("this[13]"); - CHECK_EQ(56, thirteen->Int32Value()); - CHECK_EQ(92, - context->Global()->Get(v8::Integer::New(isolate, 12))->Int32Value()); - CHECK_EQ(92, context->Global()->Get(v8_str("12"))->Int32Value()); - CHECK_EQ(92, context->Global()->Get(v8_num(12))->Int32Value()); - CHECK_EQ(32, - context->Global()->Get(v8::Integer::New(isolate, 16))->Int32Value()); - CHECK_EQ(32, context->Global()->Get(v8_str("16"))->Int32Value()); - CHECK_EQ(32, context->Global()->Get(v8_num(16))->Int32Value()); - CHECK_EQ(56, - context->Global()->Get(v8::Integer::New(isolate, 13))->Int32Value()); - CHECK_EQ(56, context->Global()->Get(v8_str("13"))->Int32Value()); - CHECK_EQ(56, context->Global()->Get(v8_num(13))->Int32Value()); + CHECK_EQ(56, thirteen->Int32Value(context.local()).FromJust()); + CHECK_EQ(92, context->Global() + ->Get(context.local(), v8::Integer::New(isolate, 12)) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(92, context->Global() + ->Get(context.local(), v8_str("12")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(92, context->Global() + ->Get(context.local(), v8_num(12)) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(32, context->Global() + ->Get(context.local(), v8::Integer::New(isolate, 16)) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(32, context->Global() + ->Get(context.local(), v8_str("16")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(32, context->Global() + ->Get(context.local(), v8_num(16)) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(56, context->Global() + ->Get(context.local(), v8::Integer::New(isolate, 13)) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(56, context->Global() + ->Get(context.local(), v8_str("13")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(56, context->Global() + ->Get(context.local(), v8_num(13)) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } @@ -4429,38 +4964,78 @@ THREADED_TEST(PropertyAttributes) { v8::HandleScope scope(context->GetIsolate()); // none Local<String> prop = v8_str("none"); - context->Global()->Set(prop, v8_num(7)); - CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(prop)); + CHECK(context->Global()->Set(context.local(), prop, v8_num(7)).FromJust()); + CHECK_EQ(v8::None, context->Global() + ->GetPropertyAttributes(context.local(), prop) + .FromJust()); // read-only prop = v8_str("read_only"); - context->Global()->ForceSet(prop, v8_num(7), v8::ReadOnly); - CHECK_EQ(7, context->Global()->Get(prop)->Int32Value()); - CHECK_EQ(v8::ReadOnly, context->Global()->GetPropertyAttributes(prop)); + context->Global() + ->DefineOwnProperty(context.local(), prop, v8_num(7), v8::ReadOnly) + .FromJust(); + CHECK_EQ(7, context->Global() + ->Get(context.local(), prop) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(v8::ReadOnly, context->Global() + ->GetPropertyAttributes(context.local(), prop) + .FromJust()); CompileRun("read_only = 9"); - CHECK_EQ(7, context->Global()->Get(prop)->Int32Value()); - context->Global()->Set(prop, v8_num(10)); - CHECK_EQ(7, context->Global()->Get(prop)->Int32Value()); + CHECK_EQ(7, context->Global() + ->Get(context.local(), prop) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK(context->Global()->Set(context.local(), prop, v8_num(10)).FromJust()); + CHECK_EQ(7, context->Global() + ->Get(context.local(), prop) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); // dont-delete prop = v8_str("dont_delete"); - context->Global()->ForceSet(prop, v8_num(13), v8::DontDelete); - CHECK_EQ(13, context->Global()->Get(prop)->Int32Value()); + context->Global() + ->DefineOwnProperty(context.local(), prop, v8_num(13), v8::DontDelete) + .FromJust(); + CHECK_EQ(13, context->Global() + ->Get(context.local(), prop) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); CompileRun("delete dont_delete"); - CHECK_EQ(13, context->Global()->Get(prop)->Int32Value()); - CHECK_EQ(v8::DontDelete, context->Global()->GetPropertyAttributes(prop)); + CHECK_EQ(13, context->Global() + ->Get(context.local(), prop) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(v8::DontDelete, context->Global() + ->GetPropertyAttributes(context.local(), prop) + .FromJust()); // dont-enum prop = v8_str("dont_enum"); - context->Global()->ForceSet(prop, v8_num(28), v8::DontEnum); - CHECK_EQ(v8::DontEnum, context->Global()->GetPropertyAttributes(prop)); + context->Global() + ->DefineOwnProperty(context.local(), prop, v8_num(28), v8::DontEnum) + .FromJust(); + CHECK_EQ(v8::DontEnum, context->Global() + ->GetPropertyAttributes(context.local(), prop) + .FromJust()); // absent prop = v8_str("absent"); - CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(prop)); + CHECK_EQ(v8::None, context->Global() + ->GetPropertyAttributes(context.local(), prop) + .FromJust()); Local<Value> fake_prop = v8_num(1); - CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(fake_prop)); + CHECK_EQ(v8::None, context->Global() + ->GetPropertyAttributes(context.local(), fake_prop) + .FromJust()); // exception TryCatch try_catch(context->GetIsolate()); Local<Value> exception = CompileRun("({ toString: function() { throw 'exception';} })"); - CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(exception)); + CHECK(context->Global() + ->GetPropertyAttributes(context.local(), exception) + .IsNothing()); CHECK(try_catch.HasCaught()); String::Utf8Value exception_value(try_catch.Exception()); CHECK_EQ(0, strcmp("exception", *exception_value)); @@ -4473,22 +5048,34 @@ THREADED_TEST(Array) { v8::HandleScope scope(context->GetIsolate()); Local<v8::Array> array = v8::Array::New(context->GetIsolate()); CHECK_EQ(0u, array->Length()); - CHECK(array->Get(0)->IsUndefined()); - CHECK(!array->Has(0)); - CHECK(array->Get(100)->IsUndefined()); - CHECK(!array->Has(100)); - array->Set(2, v8_num(7)); + CHECK(array->Get(context.local(), 0).ToLocalChecked()->IsUndefined()); + CHECK(!array->Has(context.local(), 0).FromJust()); + CHECK(array->Get(context.local(), 100).ToLocalChecked()->IsUndefined()); + CHECK(!array->Has(context.local(), 100).FromJust()); + CHECK(array->Set(context.local(), 2, v8_num(7)).FromJust()); CHECK_EQ(3u, array->Length()); - CHECK(!array->Has(0)); - CHECK(!array->Has(1)); - CHECK(array->Has(2)); - CHECK_EQ(7, array->Get(2)->Int32Value()); + CHECK(!array->Has(context.local(), 0).FromJust()); + CHECK(!array->Has(context.local(), 1).FromJust()); + CHECK(array->Has(context.local(), 2).FromJust()); + CHECK_EQ(7, array->Get(context.local(), 2) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); Local<Value> obj = CompileRun("[1, 2, 3]"); Local<v8::Array> arr = obj.As<v8::Array>(); CHECK_EQ(3u, arr->Length()); - CHECK_EQ(1, arr->Get(0)->Int32Value()); - CHECK_EQ(2, arr->Get(1)->Int32Value()); - CHECK_EQ(3, arr->Get(2)->Int32Value()); + CHECK_EQ(1, arr->Get(context.local(), 0) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(2, arr->Get(context.local(), 1) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(3, arr->Get(context.local(), 2) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); array = v8::Array::New(context->GetIsolate(), 27); CHECK_EQ(27u, array->Length()); array = v8::Array::New(context->GetIsolate(), -27); @@ -4500,7 +5087,10 @@ void HandleF(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::EscapableHandleScope scope(args.GetIsolate()); ApiTestFuzzer::Fuzz(); Local<v8::Array> result = v8::Array::New(args.GetIsolate(), args.Length()); - for (int i = 0; i < args.Length(); i++) result->Set(i, args[i]); + for (int i = 0; i < args.Length(); i++) { + CHECK(result->Set(CcTest::isolate()->GetCurrentContext(), i, args[i]) + .FromJust()); + } args.GetReturnValue().Set(scope.Escape(result)); } @@ -4519,28 +5109,58 @@ THREADED_TEST(Vector) { const char* fun2 = "f(11)"; Local<v8::Array> a1 = CompileRun(fun2).As<v8::Array>(); CHECK_EQ(1u, a1->Length()); - CHECK_EQ(11, a1->Get(0)->Int32Value()); + CHECK_EQ(11, a1->Get(context.local(), 0) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); const char* fun3 = "f(12, 13)"; Local<v8::Array> a2 = CompileRun(fun3).As<v8::Array>(); CHECK_EQ(2u, a2->Length()); - CHECK_EQ(12, a2->Get(0)->Int32Value()); - CHECK_EQ(13, a2->Get(1)->Int32Value()); + CHECK_EQ(12, a2->Get(context.local(), 0) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(13, a2->Get(context.local(), 1) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); const char* fun4 = "f(14, 15, 16)"; Local<v8::Array> a3 = CompileRun(fun4).As<v8::Array>(); CHECK_EQ(3u, a3->Length()); - CHECK_EQ(14, a3->Get(0)->Int32Value()); - CHECK_EQ(15, a3->Get(1)->Int32Value()); - CHECK_EQ(16, a3->Get(2)->Int32Value()); + CHECK_EQ(14, a3->Get(context.local(), 0) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(15, a3->Get(context.local(), 1) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(16, a3->Get(context.local(), 2) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); const char* fun5 = "f(17, 18, 19, 20)"; Local<v8::Array> a4 = CompileRun(fun5).As<v8::Array>(); CHECK_EQ(4u, a4->Length()); - CHECK_EQ(17, a4->Get(0)->Int32Value()); - CHECK_EQ(18, a4->Get(1)->Int32Value()); - CHECK_EQ(19, a4->Get(2)->Int32Value()); - CHECK_EQ(20, a4->Get(3)->Int32Value()); + CHECK_EQ(17, a4->Get(context.local(), 0) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(18, a4->Get(context.local(), 1) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(19, a4->Get(context.local(), 2) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(20, a4->Get(context.local(), 3) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } @@ -4563,67 +5183,126 @@ THREADED_TEST(FunctionCall) { " 'use strict';" " return this;" "}"); - Local<Function> Foo = - Local<Function>::Cast(context->Global()->Get(v8_str("Foo"))); - Local<Function> ReturnThisSloppy = - Local<Function>::Cast(context->Global()->Get(v8_str("ReturnThisSloppy"))); - Local<Function> ReturnThisStrict = - Local<Function>::Cast(context->Global()->Get(v8_str("ReturnThisStrict"))); - - v8::Handle<Value>* args0 = NULL; - Local<v8::Array> a0 = Local<v8::Array>::Cast(Foo->Call(Foo, 0, args0)); + Local<Function> Foo = Local<Function>::Cast( + context->Global()->Get(context.local(), v8_str("Foo")).ToLocalChecked()); + Local<Function> ReturnThisSloppy = Local<Function>::Cast( + context->Global() + ->Get(context.local(), v8_str("ReturnThisSloppy")) + .ToLocalChecked()); + Local<Function> ReturnThisStrict = Local<Function>::Cast( + context->Global() + ->Get(context.local(), v8_str("ReturnThisStrict")) + .ToLocalChecked()); + + v8::Local<Value>* args0 = NULL; + Local<v8::Array> a0 = Local<v8::Array>::Cast( + Foo->Call(context.local(), Foo, 0, args0).ToLocalChecked()); CHECK_EQ(0u, a0->Length()); - v8::Handle<Value> args1[] = {v8_num(1.1)}; - Local<v8::Array> a1 = Local<v8::Array>::Cast(Foo->Call(Foo, 1, args1)); + v8::Local<Value> args1[] = {v8_num(1.1)}; + Local<v8::Array> a1 = Local<v8::Array>::Cast( + Foo->Call(context.local(), Foo, 1, args1).ToLocalChecked()); CHECK_EQ(1u, a1->Length()); - CHECK_EQ(1.1, a1->Get(v8::Integer::New(isolate, 0))->NumberValue()); - - v8::Handle<Value> args2[] = {v8_num(2.2), v8_num(3.3)}; - Local<v8::Array> a2 = Local<v8::Array>::Cast(Foo->Call(Foo, 2, args2)); + CHECK_EQ(1.1, a1->Get(context.local(), v8::Integer::New(isolate, 0)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + + v8::Local<Value> args2[] = {v8_num(2.2), v8_num(3.3)}; + Local<v8::Array> a2 = Local<v8::Array>::Cast( + Foo->Call(context.local(), Foo, 2, args2).ToLocalChecked()); CHECK_EQ(2u, a2->Length()); - CHECK_EQ(2.2, a2->Get(v8::Integer::New(isolate, 0))->NumberValue()); - CHECK_EQ(3.3, a2->Get(v8::Integer::New(isolate, 1))->NumberValue()); - - v8::Handle<Value> args3[] = {v8_num(4.4), v8_num(5.5), v8_num(6.6)}; - Local<v8::Array> a3 = Local<v8::Array>::Cast(Foo->Call(Foo, 3, args3)); + CHECK_EQ(2.2, a2->Get(context.local(), v8::Integer::New(isolate, 0)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + CHECK_EQ(3.3, a2->Get(context.local(), v8::Integer::New(isolate, 1)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + + v8::Local<Value> args3[] = {v8_num(4.4), v8_num(5.5), v8_num(6.6)}; + Local<v8::Array> a3 = Local<v8::Array>::Cast( + Foo->Call(context.local(), Foo, 3, args3).ToLocalChecked()); CHECK_EQ(3u, a3->Length()); - CHECK_EQ(4.4, a3->Get(v8::Integer::New(isolate, 0))->NumberValue()); - CHECK_EQ(5.5, a3->Get(v8::Integer::New(isolate, 1))->NumberValue()); - CHECK_EQ(6.6, a3->Get(v8::Integer::New(isolate, 2))->NumberValue()); - - v8::Handle<Value> args4[] = {v8_num(7.7), v8_num(8.8), v8_num(9.9), - v8_num(10.11)}; - Local<v8::Array> a4 = Local<v8::Array>::Cast(Foo->Call(Foo, 4, args4)); + CHECK_EQ(4.4, a3->Get(context.local(), v8::Integer::New(isolate, 0)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + CHECK_EQ(5.5, a3->Get(context.local(), v8::Integer::New(isolate, 1)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + CHECK_EQ(6.6, a3->Get(context.local(), v8::Integer::New(isolate, 2)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + + v8::Local<Value> args4[] = {v8_num(7.7), v8_num(8.8), v8_num(9.9), + v8_num(10.11)}; + Local<v8::Array> a4 = Local<v8::Array>::Cast( + Foo->Call(context.local(), Foo, 4, args4).ToLocalChecked()); CHECK_EQ(4u, a4->Length()); - CHECK_EQ(7.7, a4->Get(v8::Integer::New(isolate, 0))->NumberValue()); - CHECK_EQ(8.8, a4->Get(v8::Integer::New(isolate, 1))->NumberValue()); - CHECK_EQ(9.9, a4->Get(v8::Integer::New(isolate, 2))->NumberValue()); - CHECK_EQ(10.11, a4->Get(v8::Integer::New(isolate, 3))->NumberValue()); - - Local<v8::Value> r1 = ReturnThisSloppy->Call(v8::Undefined(isolate), 0, NULL); + CHECK_EQ(7.7, a4->Get(context.local(), v8::Integer::New(isolate, 0)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + CHECK_EQ(8.8, a4->Get(context.local(), v8::Integer::New(isolate, 1)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + CHECK_EQ(9.9, a4->Get(context.local(), v8::Integer::New(isolate, 2)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + CHECK_EQ(10.11, a4->Get(context.local(), v8::Integer::New(isolate, 3)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + + Local<v8::Value> r1 = + ReturnThisSloppy->Call(context.local(), v8::Undefined(isolate), 0, NULL) + .ToLocalChecked(); CHECK(r1->StrictEquals(context->Global())); - Local<v8::Value> r2 = ReturnThisSloppy->Call(v8::Null(isolate), 0, NULL); + Local<v8::Value> r2 = + ReturnThisSloppy->Call(context.local(), v8::Null(isolate), 0, NULL) + .ToLocalChecked(); CHECK(r2->StrictEquals(context->Global())); - Local<v8::Value> r3 = ReturnThisSloppy->Call(v8_num(42), 0, NULL); + Local<v8::Value> r3 = + ReturnThisSloppy->Call(context.local(), v8_num(42), 0, NULL) + .ToLocalChecked(); CHECK(r3->IsNumberObject()); CHECK_EQ(42.0, r3.As<v8::NumberObject>()->ValueOf()); - Local<v8::Value> r4 = ReturnThisSloppy->Call(v8_str("hello"), 0, NULL); + Local<v8::Value> r4 = + ReturnThisSloppy->Call(context.local(), v8_str("hello"), 0, NULL) + .ToLocalChecked(); CHECK(r4->IsStringObject()); CHECK(r4.As<v8::StringObject>()->ValueOf()->StrictEquals(v8_str("hello"))); - Local<v8::Value> r5 = ReturnThisSloppy->Call(v8::True(isolate), 0, NULL); + Local<v8::Value> r5 = + ReturnThisSloppy->Call(context.local(), v8::True(isolate), 0, NULL) + .ToLocalChecked(); CHECK(r5->IsBooleanObject()); CHECK(r5.As<v8::BooleanObject>()->ValueOf()); - Local<v8::Value> r6 = ReturnThisStrict->Call(v8::Undefined(isolate), 0, NULL); + Local<v8::Value> r6 = + ReturnThisStrict->Call(context.local(), v8::Undefined(isolate), 0, NULL) + .ToLocalChecked(); CHECK(r6->IsUndefined()); - Local<v8::Value> r7 = ReturnThisStrict->Call(v8::Null(isolate), 0, NULL); + Local<v8::Value> r7 = + ReturnThisStrict->Call(context.local(), v8::Null(isolate), 0, NULL) + .ToLocalChecked(); CHECK(r7->IsNull()); - Local<v8::Value> r8 = ReturnThisStrict->Call(v8_num(42), 0, NULL); + Local<v8::Value> r8 = + ReturnThisStrict->Call(context.local(), v8_num(42), 0, NULL) + .ToLocalChecked(); CHECK(r8->StrictEquals(v8_num(42))); - Local<v8::Value> r9 = ReturnThisStrict->Call(v8_str("hello"), 0, NULL); + Local<v8::Value> r9 = + ReturnThisStrict->Call(context.local(), v8_str("hello"), 0, NULL) + .ToLocalChecked(); CHECK(r9->StrictEquals(v8_str("hello"))); - Local<v8::Value> r10 = ReturnThisStrict->Call(v8::True(isolate), 0, NULL); + Local<v8::Value> r10 = + ReturnThisStrict->Call(context.local(), v8::True(isolate), 0, NULL) + .ToLocalChecked(); CHECK(r10->StrictEquals(v8::True(isolate))); } @@ -4640,47 +5319,74 @@ THREADED_TEST(ConstructCall) { " }" " return result;" "}"); - Local<Function> Foo = - Local<Function>::Cast(context->Global()->Get(v8_str("Foo"))); + Local<Function> Foo = Local<Function>::Cast( + context->Global()->Get(context.local(), v8_str("Foo")).ToLocalChecked()); - v8::Handle<Value>* args0 = NULL; - Local<v8::Array> a0 = Local<v8::Array>::Cast(Foo->NewInstance(0, args0)); + v8::Local<Value>* args0 = NULL; + Local<v8::Array> a0 = Local<v8::Array>::Cast( + Foo->NewInstance(context.local(), 0, args0).ToLocalChecked()); CHECK_EQ(0u, a0->Length()); - v8::Handle<Value> args1[] = {v8_num(1.1)}; - Local<v8::Array> a1 = Local<v8::Array>::Cast(Foo->NewInstance(1, args1)); + v8::Local<Value> args1[] = {v8_num(1.1)}; + Local<v8::Array> a1 = Local<v8::Array>::Cast( + Foo->NewInstance(context.local(), 1, args1).ToLocalChecked()); CHECK_EQ(1u, a1->Length()); - CHECK_EQ(1.1, a1->Get(v8::Integer::New(isolate, 0))->NumberValue()); - - v8::Handle<Value> args2[] = {v8_num(2.2), v8_num(3.3)}; - Local<v8::Array> a2 = Local<v8::Array>::Cast(Foo->NewInstance(2, args2)); + CHECK_EQ(1.1, a1->Get(context.local(), v8::Integer::New(isolate, 0)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + + v8::Local<Value> args2[] = {v8_num(2.2), v8_num(3.3)}; + Local<v8::Array> a2 = Local<v8::Array>::Cast( + Foo->NewInstance(context.local(), 2, args2).ToLocalChecked()); CHECK_EQ(2u, a2->Length()); - CHECK_EQ(2.2, a2->Get(v8::Integer::New(isolate, 0))->NumberValue()); - CHECK_EQ(3.3, a2->Get(v8::Integer::New(isolate, 1))->NumberValue()); - - v8::Handle<Value> args3[] = {v8_num(4.4), v8_num(5.5), v8_num(6.6)}; - Local<v8::Array> a3 = Local<v8::Array>::Cast(Foo->NewInstance(3, args3)); + CHECK_EQ(2.2, a2->Get(context.local(), v8::Integer::New(isolate, 0)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + CHECK_EQ(3.3, a2->Get(context.local(), v8::Integer::New(isolate, 1)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + + v8::Local<Value> args3[] = {v8_num(4.4), v8_num(5.5), v8_num(6.6)}; + Local<v8::Array> a3 = Local<v8::Array>::Cast( + Foo->NewInstance(context.local(), 3, args3).ToLocalChecked()); CHECK_EQ(3u, a3->Length()); - CHECK_EQ(4.4, a3->Get(v8::Integer::New(isolate, 0))->NumberValue()); - CHECK_EQ(5.5, a3->Get(v8::Integer::New(isolate, 1))->NumberValue()); - CHECK_EQ(6.6, a3->Get(v8::Integer::New(isolate, 2))->NumberValue()); - - v8::Handle<Value> args4[] = {v8_num(7.7), v8_num(8.8), v8_num(9.9), - v8_num(10.11)}; - Local<v8::Array> a4 = Local<v8::Array>::Cast(Foo->NewInstance(4, args4)); + CHECK_EQ(4.4, a3->Get(context.local(), v8::Integer::New(isolate, 0)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + CHECK_EQ(5.5, a3->Get(context.local(), v8::Integer::New(isolate, 1)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + CHECK_EQ(6.6, a3->Get(context.local(), v8::Integer::New(isolate, 2)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + + v8::Local<Value> args4[] = {v8_num(7.7), v8_num(8.8), v8_num(9.9), + v8_num(10.11)}; + Local<v8::Array> a4 = Local<v8::Array>::Cast( + Foo->NewInstance(context.local(), 4, args4).ToLocalChecked()); CHECK_EQ(4u, a4->Length()); - CHECK_EQ(7.7, a4->Get(v8::Integer::New(isolate, 0))->NumberValue()); - CHECK_EQ(8.8, a4->Get(v8::Integer::New(isolate, 1))->NumberValue()); - CHECK_EQ(9.9, a4->Get(v8::Integer::New(isolate, 2))->NumberValue()); - CHECK_EQ(10.11, a4->Get(v8::Integer::New(isolate, 3))->NumberValue()); -} - - -static void CheckUncle(v8::TryCatch* try_catch) { - CHECK(try_catch->HasCaught()); - String::Utf8Value str_value(try_catch->Exception()); - CHECK_EQ(0, strcmp(*str_value, "uncle?")); - try_catch->Reset(); + CHECK_EQ(7.7, a4->Get(context.local(), v8::Integer::New(isolate, 0)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + CHECK_EQ(8.8, a4->Get(context.local(), v8::Integer::New(isolate, 1)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + CHECK_EQ(9.9, a4->Get(context.local(), v8::Integer::New(isolate, 2)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); + CHECK_EQ(10.11, a4->Get(context.local(), v8::Integer::New(isolate, 3)) + .ToLocalChecked() + ->NumberValue(context.local()) + .FromJust()); } @@ -4690,47 +5396,57 @@ THREADED_TEST(ConversionNumber) { v8::HandleScope scope(isolate); // Very large number. CompileRun("var obj = Math.pow(2,32) * 1237;"); - Local<Value> obj = env->Global()->Get(v8_str("obj")); - CHECK_EQ(5312874545152.0, obj->ToNumber(isolate)->Value()); - CHECK_EQ(0, obj->ToInt32(isolate)->Value()); + Local<Value> obj = + env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); + CHECK_EQ(5312874545152.0, + obj->ToNumber(env.local()).ToLocalChecked()->Value()); + CHECK_EQ(0, obj->ToInt32(env.local()).ToLocalChecked()->Value()); CHECK(0u == - obj->ToUint32(isolate)->Value()); // NOLINT - no CHECK_EQ for unsigned. + obj->ToUint32(env.local()) + .ToLocalChecked() + ->Value()); // NOLINT - no CHECK_EQ for unsigned. // Large number. CompileRun("var obj = -1234567890123;"); - obj = env->Global()->Get(v8_str("obj")); - CHECK_EQ(-1234567890123.0, obj->ToNumber(isolate)->Value()); - CHECK_EQ(-1912276171, obj->ToInt32(isolate)->Value()); - CHECK(2382691125u == obj->ToUint32(isolate)->Value()); // NOLINT + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); + CHECK_EQ(-1234567890123.0, + obj->ToNumber(env.local()).ToLocalChecked()->Value()); + CHECK_EQ(-1912276171, obj->ToInt32(env.local()).ToLocalChecked()->Value()); + CHECK(2382691125u == + obj->ToUint32(env.local()).ToLocalChecked()->Value()); // NOLINT // Small positive integer. CompileRun("var obj = 42;"); - obj = env->Global()->Get(v8_str("obj")); - CHECK_EQ(42.0, obj->ToNumber(isolate)->Value()); - CHECK_EQ(42, obj->ToInt32(isolate)->Value()); - CHECK(42u == obj->ToUint32(isolate)->Value()); // NOLINT + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); + CHECK_EQ(42.0, obj->ToNumber(env.local()).ToLocalChecked()->Value()); + CHECK_EQ(42, obj->ToInt32(env.local()).ToLocalChecked()->Value()); + CHECK(42u == obj->ToUint32(env.local()).ToLocalChecked()->Value()); // NOLINT // Negative integer. CompileRun("var obj = -37;"); - obj = env->Global()->Get(v8_str("obj")); - CHECK_EQ(-37.0, obj->ToNumber(isolate)->Value()); - CHECK_EQ(-37, obj->ToInt32(isolate)->Value()); - CHECK(4294967259u == obj->ToUint32(isolate)->Value()); // NOLINT + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); + CHECK_EQ(-37.0, obj->ToNumber(env.local()).ToLocalChecked()->Value()); + CHECK_EQ(-37, obj->ToInt32(env.local()).ToLocalChecked()->Value()); + CHECK(4294967259u == + obj->ToUint32(env.local()).ToLocalChecked()->Value()); // NOLINT // Positive non-int32 integer. CompileRun("var obj = 0x81234567;"); - obj = env->Global()->Get(v8_str("obj")); - CHECK_EQ(2166572391.0, obj->ToNumber(isolate)->Value()); - CHECK_EQ(-2128394905, obj->ToInt32(isolate)->Value()); - CHECK(2166572391u == obj->ToUint32(isolate)->Value()); // NOLINT + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); + CHECK_EQ(2166572391.0, obj->ToNumber(env.local()).ToLocalChecked()->Value()); + CHECK_EQ(-2128394905, obj->ToInt32(env.local()).ToLocalChecked()->Value()); + CHECK(2166572391u == + obj->ToUint32(env.local()).ToLocalChecked()->Value()); // NOLINT // Fraction. CompileRun("var obj = 42.3;"); - obj = env->Global()->Get(v8_str("obj")); - CHECK_EQ(42.3, obj->ToNumber(isolate)->Value()); - CHECK_EQ(42, obj->ToInt32(isolate)->Value()); - CHECK(42u == obj->ToUint32(isolate)->Value()); // NOLINT + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); + CHECK_EQ(42.3, obj->ToNumber(env.local()).ToLocalChecked()->Value()); + CHECK_EQ(42, obj->ToInt32(env.local()).ToLocalChecked()->Value()); + CHECK(42u == obj->ToUint32(env.local()).ToLocalChecked()->Value()); // NOLINT // Large negative fraction. CompileRun("var obj = -5726623061.75;"); - obj = env->Global()->Get(v8_str("obj")); - CHECK_EQ(-5726623061.75, obj->ToNumber(isolate)->Value()); - CHECK_EQ(-1431655765, obj->ToInt32(isolate)->Value()); - CHECK(2863311531u == obj->ToUint32(isolate)->Value()); // NOLINT + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); + CHECK_EQ(-5726623061.75, + obj->ToNumber(env.local()).ToLocalChecked()->Value()); + CHECK_EQ(-1431655765, obj->ToInt32(env.local()).ToLocalChecked()->Value()); + CHECK(2863311531u == + obj->ToUint32(env.local()).ToLocalChecked()->Value()); // NOLINT } @@ -4739,52 +5455,61 @@ THREADED_TEST(isNumberType) { v8::HandleScope scope(env->GetIsolate()); // Very large number. CompileRun("var obj = Math.pow(2,32) * 1237;"); - Local<Value> obj = env->Global()->Get(v8_str("obj")); + Local<Value> obj = + env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); CHECK(!obj->IsInt32()); CHECK(!obj->IsUint32()); // Large negative number. CompileRun("var obj = -1234567890123;"); - obj = env->Global()->Get(v8_str("obj")); + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); CHECK(!obj->IsInt32()); CHECK(!obj->IsUint32()); // Small positive integer. CompileRun("var obj = 42;"); - obj = env->Global()->Get(v8_str("obj")); + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); CHECK(obj->IsInt32()); CHECK(obj->IsUint32()); // Negative integer. CompileRun("var obj = -37;"); - obj = env->Global()->Get(v8_str("obj")); + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); CHECK(obj->IsInt32()); CHECK(!obj->IsUint32()); // Positive non-int32 integer. CompileRun("var obj = 0x81234567;"); - obj = env->Global()->Get(v8_str("obj")); + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); CHECK(!obj->IsInt32()); CHECK(obj->IsUint32()); // Fraction. CompileRun("var obj = 42.3;"); - obj = env->Global()->Get(v8_str("obj")); + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); CHECK(!obj->IsInt32()); CHECK(!obj->IsUint32()); // Large negative fraction. CompileRun("var obj = -5726623061.75;"); - obj = env->Global()->Get(v8_str("obj")); + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); CHECK(!obj->IsInt32()); CHECK(!obj->IsUint32()); // Positive zero CompileRun("var obj = 0.0;"); - obj = env->Global()->Get(v8_str("obj")); + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); CHECK(obj->IsInt32()); CHECK(obj->IsUint32()); // Positive zero CompileRun("var obj = -0.0;"); - obj = env->Global()->Get(v8_str("obj")); + obj = env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); CHECK(!obj->IsInt32()); CHECK(!obj->IsUint32()); } +static void CheckUncle(v8::TryCatch* try_catch) { + CHECK(try_catch->HasCaught()); + String::Utf8Value str_value(try_catch->Exception()); + CHECK_EQ(0, strcmp(*str_value, "uncle?")); + try_catch->Reset(); +} + + THREADED_TEST(ConversionException) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); @@ -4793,49 +5518,40 @@ THREADED_TEST(ConversionException) { "function TestClass() { };" "TestClass.prototype.toString = function () { throw 'uncle?'; };" "var obj = new TestClass();"); - Local<Value> obj = env->Global()->Get(v8_str("obj")); + Local<Value> obj = + env->Global()->Get(env.local(), v8_str("obj")).ToLocalChecked(); v8::TryCatch try_catch(isolate); - Local<Value> to_string_result = obj->ToString(isolate); - CHECK(to_string_result.IsEmpty()); + CHECK(obj->ToString(env.local()).IsEmpty()); CheckUncle(&try_catch); - Local<Value> to_number_result = obj->ToNumber(isolate); - CHECK(to_number_result.IsEmpty()); + CHECK(obj->ToNumber(env.local()).IsEmpty()); CheckUncle(&try_catch); - Local<Value> to_integer_result = obj->ToInteger(isolate); - CHECK(to_integer_result.IsEmpty()); + CHECK(obj->ToInteger(env.local()).IsEmpty()); CheckUncle(&try_catch); - Local<Value> to_uint32_result = obj->ToUint32(isolate); - CHECK(to_uint32_result.IsEmpty()); + CHECK(obj->ToUint32(env.local()).IsEmpty()); CheckUncle(&try_catch); - Local<Value> to_int32_result = obj->ToInt32(isolate); - CHECK(to_int32_result.IsEmpty()); + CHECK(obj->ToInt32(env.local()).IsEmpty()); CheckUncle(&try_catch); - Local<Value> to_object_result = v8::Undefined(isolate)->ToObject(isolate); - CHECK(to_object_result.IsEmpty()); + CHECK(v8::Undefined(isolate)->ToObject(env.local()).IsEmpty()); CHECK(try_catch.HasCaught()); try_catch.Reset(); - int32_t int32_value = obj->Int32Value(); - CHECK_EQ(0, int32_value); + CHECK(obj->Int32Value(env.local()).IsNothing()); CheckUncle(&try_catch); - uint32_t uint32_value = obj->Uint32Value(); - CHECK_EQ(0u, uint32_value); + CHECK(obj->Uint32Value(env.local()).IsNothing()); CheckUncle(&try_catch); - double number_value = obj->NumberValue(); - CHECK(std::isnan(number_value)); + CHECK(obj->NumberValue(env.local()).IsNothing()); CheckUncle(&try_catch); - int64_t integer_value = obj->IntegerValue(); - CHECK_EQ(0, integer_value); + CHECK(obj->IntegerValue(env.local()).IsNothing()); CheckUncle(&try_catch); } @@ -4853,7 +5569,10 @@ void CCatcher(const v8::FunctionCallbackInfo<v8::Value>& args) { } v8::HandleScope scope(args.GetIsolate()); v8::TryCatch try_catch(args.GetIsolate()); - Local<Value> result = CompileRun(args[0]->ToString(args.GetIsolate())); + Local<Value> result = + CompileRun(args[0] + ->ToString(args.GetIsolate()->GetCurrentContext()) + .ToLocalChecked()); CHECK(!try_catch.HasCaught() || result.IsEmpty()); args.GetReturnValue().Set(try_catch.HasCaught()); } @@ -4873,8 +5592,10 @@ THREADED_TEST(APICatch) { "} catch (e) {" " thrown = true;" "}"); - Local<Value> thrown = context->Global()->Get(v8_str("thrown")); - CHECK(thrown->BooleanValue()); + Local<Value> thrown = context->Global() + ->Get(context.local(), v8_str("thrown")) + .ToLocalChecked(); + CHECK(thrown->BooleanValue(context.local()).FromJust()); } @@ -4916,75 +5637,20 @@ TEST(TryCatchInTryFinally) { } -static void check_reference_error_message(v8::Handle<v8::Message> message, - v8::Handle<v8::Value> data) { - const char* reference_error = "Uncaught ReferenceError: asdf is not defined"; - CHECK(message->Get()->Equals(v8_str(reference_error))); -} - - -static void Fail(const v8::FunctionCallbackInfo<v8::Value>& args) { - ApiTestFuzzer::Fuzz(); - CHECK(false); -} - - -// Test that overwritten methods are not invoked on uncaught exception -// formatting. However, they are invoked when performing normal error -// string conversions. -TEST(APIThrowMessageOverwrittenToString) { - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - v8::V8::AddMessageListener(check_reference_error_message); - Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); - templ->Set(v8_str("fail"), v8::FunctionTemplate::New(isolate, Fail)); - LocalContext context(NULL, templ); - CompileRun("asdf;"); - CompileRun( - "var limit = {};" - "limit.valueOf = fail;" - "Error.stackTraceLimit = limit;"); - CompileRun("asdf"); - CompileRun("Array.prototype.pop = fail;"); - CompileRun("Object.prototype.hasOwnProperty = fail;"); - CompileRun("Object.prototype.toString = function f() { return 'Yikes'; }"); - CompileRun("Number.prototype.toString = function f() { return 'Yikes'; }"); - CompileRun("String.prototype.toString = function f() { return 'Yikes'; }"); - CompileRun( - "ReferenceError.prototype.toString =" - " function() { return 'Whoops' }"); - CompileRun("asdf;"); - CompileRun("ReferenceError.prototype.constructor.name = void 0;"); - CompileRun("asdf;"); - CompileRun("ReferenceError.prototype.constructor = void 0;"); - CompileRun("asdf;"); - CompileRun("ReferenceError.prototype.__proto__ = new Object();"); - CompileRun("asdf;"); - CompileRun("ReferenceError.prototype = new Object();"); - CompileRun("asdf;"); - v8::Handle<Value> string = CompileRun("try { asdf; } catch(e) { e + ''; }"); - CHECK(string->Equals(v8_str("Whoops"))); - CompileRun( - "ReferenceError.prototype.constructor = new Object();" - "ReferenceError.prototype.constructor.name = 1;" - "Number.prototype.toString = function() { return 'Whoops'; };" - "ReferenceError.prototype.toString = Object.prototype.toString;"); - CompileRun("asdf;"); - v8::V8::RemoveMessageListeners(check_reference_error_message); -} - - -static void check_custom_error_tostring(v8::Handle<v8::Message> message, - v8::Handle<v8::Value> data) { +static void check_custom_error_tostring(v8::Local<v8::Message> message, + v8::Local<v8::Value> data) { const char* uncaught_error = "Uncaught MyError toString"; - CHECK(message->Get()->Equals(v8_str(uncaught_error))); + CHECK(message->Get() + ->Equals(CcTest::isolate()->GetCurrentContext(), + v8_str(uncaught_error)) + .FromJust()); } TEST(CustomErrorToString) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::V8::AddMessageListener(check_custom_error_tostring); + context->GetIsolate()->AddMessageListener(check_custom_error_tostring); CompileRun( "function MyError(name, message) { " " this.name = name; " @@ -4995,22 +5661,25 @@ TEST(CustomErrorToString) { " return 'MyError toString'; " "}; " "throw new MyError('my name', 'my message'); "); - v8::V8::RemoveMessageListeners(check_custom_error_tostring); + context->GetIsolate()->RemoveMessageListeners(check_custom_error_tostring); } -static void check_custom_error_message(v8::Handle<v8::Message> message, - v8::Handle<v8::Value> data) { +static void check_custom_error_message(v8::Local<v8::Message> message, + v8::Local<v8::Value> data) { const char* uncaught_error = "Uncaught MyError: my message"; printf("%s\n", *v8::String::Utf8Value(message->Get())); - CHECK(message->Get()->Equals(v8_str(uncaught_error))); + CHECK(message->Get() + ->Equals(CcTest::isolate()->GetCurrentContext(), + v8_str(uncaught_error)) + .FromJust()); } TEST(CustomErrorMessage) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::V8::AddMessageListener(check_custom_error_message); + context->GetIsolate()->AddMessageListener(check_custom_error_message); // Handlebars. CompileRun( @@ -5046,32 +5715,36 @@ TEST(CustomErrorMessage) { "MyError.prototype = Object.create(Error.prototype); " "throw new MyError('my message'); "); - v8::V8::RemoveMessageListeners(check_custom_error_message); + context->GetIsolate()->RemoveMessageListeners(check_custom_error_message); } -static void check_custom_rethrowing_message(v8::Handle<v8::Message> message, - v8::Handle<v8::Value> data) { +static void check_custom_rethrowing_message(v8::Local<v8::Message> message, + v8::Local<v8::Value> data) { const char* uncaught_error = "Uncaught exception"; - CHECK(message->Get()->Equals(v8_str(uncaught_error))); + CHECK(message->Get() + ->Equals(CcTest::isolate()->GetCurrentContext(), + v8_str(uncaught_error)) + .FromJust()); } TEST(CustomErrorRethrowsOnToString) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::V8::AddMessageListener(check_custom_rethrowing_message); + context->GetIsolate()->AddMessageListener(check_custom_rethrowing_message); CompileRun( "var e = { toString: function() { throw e; } };" "try { throw e; } finally {}"); - v8::V8::RemoveMessageListeners(check_custom_rethrowing_message); + context->GetIsolate()->RemoveMessageListeners( + check_custom_rethrowing_message); } -static void receive_message(v8::Handle<v8::Message> message, - v8::Handle<v8::Value> data) { +static void receive_message(v8::Local<v8::Message> message, + v8::Local<v8::Value> data) { message->Get(); message_received = true; } @@ -5081,14 +5754,14 @@ TEST(APIThrowMessage) { message_received = false; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::V8::AddMessageListener(receive_message); + isolate->AddMessageListener(receive_message); Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("ThrowFromC"), v8::FunctionTemplate::New(isolate, ThrowFromC)); LocalContext context(0, templ); CompileRun("ThrowFromC();"); CHECK(message_received); - v8::V8::RemoveMessageListeners(receive_message); + isolate->RemoveMessageListeners(receive_message); } @@ -5096,7 +5769,7 @@ TEST(APIThrowMessageAndVerboseTryCatch) { message_received = false; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::V8::AddMessageListener(receive_message); + isolate->AddMessageListener(receive_message); Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("ThrowFromC"), v8::FunctionTemplate::New(isolate, ThrowFromC)); @@ -5107,7 +5780,7 @@ TEST(APIThrowMessageAndVerboseTryCatch) { CHECK(try_catch.HasCaught()); CHECK(result.IsEmpty()); CHECK(message_received); - v8::V8::RemoveMessageListeners(receive_message); + isolate->RemoveMessageListeners(receive_message); } @@ -5115,14 +5788,14 @@ TEST(APIStackOverflowAndVerboseTryCatch) { message_received = false; LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::V8::AddMessageListener(receive_message); + context->GetIsolate()->AddMessageListener(receive_message); v8::TryCatch try_catch(context->GetIsolate()); try_catch.SetVerbose(true); Local<Value> result = CompileRun("function foo() { foo(); } foo();"); CHECK(try_catch.HasCaught()); CHECK(result.IsEmpty()); CHECK(message_received); - v8::V8::RemoveMessageListeners(receive_message); + context->GetIsolate()->RemoveMessageListeners(receive_message); } @@ -5146,19 +5819,23 @@ THREADED_TEST(ExternalScriptException) { void CThrowCountDown(const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); CHECK_EQ(4, args.Length()); - int count = args[0]->Int32Value(); - int cInterval = args[2]->Int32Value(); + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); + int count = args[0]->Int32Value(context).FromJust(); + int cInterval = args[2]->Int32Value(context).FromJust(); if (count == 0) { args.GetIsolate()->ThrowException(v8_str("FromC")); return; } else { - Local<v8::Object> global = args.GetIsolate()->GetCurrentContext()->Global(); - Local<Value> fun = global->Get(v8_str("JSThrowCountDown")); - v8::Handle<Value> argv[] = {v8_num(count - 1), args[1], args[2], args[3]}; + Local<v8::Object> global = context->Global(); + Local<Value> fun = + global->Get(context, v8_str("JSThrowCountDown")).ToLocalChecked(); + v8::Local<Value> argv[] = {v8_num(count - 1), args[1], args[2], args[3]}; if (count % cInterval == 0) { v8::TryCatch try_catch(args.GetIsolate()); - Local<Value> result = fun.As<Function>()->Call(global, 4, argv); - int expected = args[3]->Int32Value(); + Local<Value> result = fun.As<Function>() + ->Call(context, global, 4, argv) + .FromMaybe(Local<Value>()); + int expected = args[3]->Int32Value(context).FromJust(); if (try_catch.HasCaught()) { CHECK_EQ(expected, count); CHECK(result.IsEmpty()); @@ -5169,7 +5846,9 @@ void CThrowCountDown(const v8::FunctionCallbackInfo<v8::Value>& args) { args.GetReturnValue().Set(result); return; } else { - args.GetReturnValue().Set(fun.As<Function>()->Call(global, 4, argv)); + args.GetReturnValue().Set(fun.As<Function>() + ->Call(context, global, 4, argv) + .FromMaybe(v8::Local<v8::Value>())); return; } } @@ -5179,9 +5858,10 @@ void CThrowCountDown(const v8::FunctionCallbackInfo<v8::Value>& args) { void JSCheck(const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); CHECK_EQ(3, args.Length()); - bool equality = args[0]->BooleanValue(); - int count = args[1]->Int32Value(); - int expected = args[2]->Int32Value(); + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); + bool equality = args[0]->BooleanValue(context).FromJust(); + int count = args[1]->Int32Value(context).FromJust(); + int expected = args[2]->Int32Value(context).FromJust(); if (equality) { CHECK_EQ(count, expected); } else { @@ -5252,35 +5932,37 @@ TEST(ExceptionOrder) { " return CThrowCountDown(count - 1, jsInterval, cInterval, expected);" " }" "}"); - Local<Function> fun = - Local<Function>::Cast(context->Global()->Get(v8_str("JSThrowCountDown"))); + Local<Function> fun = Local<Function>::Cast( + context->Global() + ->Get(context.local(), v8_str("JSThrowCountDown")) + .ToLocalChecked()); const int argc = 4; // count jsInterval cInterval expected // *JS[4] *C[3] @JS[2] C[1] JS[0] - v8::Handle<Value> a0[argc] = {v8_num(4), v8_num(2), v8_num(3), v8_num(2)}; - fun->Call(fun, argc, a0); + v8::Local<Value> a0[argc] = {v8_num(4), v8_num(2), v8_num(3), v8_num(2)}; + fun->Call(context.local(), fun, argc, a0).ToLocalChecked(); // JS[5] *C[4] JS[3] @C[2] JS[1] C[0] - v8::Handle<Value> a1[argc] = {v8_num(5), v8_num(6), v8_num(1), v8_num(2)}; - fun->Call(fun, argc, a1); + v8::Local<Value> a1[argc] = {v8_num(5), v8_num(6), v8_num(1), v8_num(2)}; + fun->Call(context.local(), fun, argc, a1).ToLocalChecked(); // JS[6] @C[5] JS[4] C[3] JS[2] C[1] JS[0] - v8::Handle<Value> a2[argc] = {v8_num(6), v8_num(7), v8_num(5), v8_num(5)}; - fun->Call(fun, argc, a2); + v8::Local<Value> a2[argc] = {v8_num(6), v8_num(7), v8_num(5), v8_num(5)}; + fun->Call(context.local(), fun, argc, a2).ToLocalChecked(); // @JS[6] C[5] JS[4] C[3] JS[2] C[1] JS[0] - v8::Handle<Value> a3[argc] = {v8_num(6), v8_num(6), v8_num(7), v8_num(6)}; - fun->Call(fun, argc, a3); + v8::Local<Value> a3[argc] = {v8_num(6), v8_num(6), v8_num(7), v8_num(6)}; + fun->Call(context.local(), fun, argc, a3).ToLocalChecked(); // JS[6] *C[5] @JS[4] C[3] JS[2] C[1] JS[0] - v8::Handle<Value> a4[argc] = {v8_num(6), v8_num(4), v8_num(5), v8_num(4)}; - fun->Call(fun, argc, a4); + v8::Local<Value> a4[argc] = {v8_num(6), v8_num(4), v8_num(5), v8_num(4)}; + fun->Call(context.local(), fun, argc, a4).ToLocalChecked(); // JS[6] C[5] *JS[4] @C[3] JS[2] C[1] JS[0] - v8::Handle<Value> a5[argc] = {v8_num(6), v8_num(4), v8_num(3), v8_num(3)}; - fun->Call(fun, argc, a5); + v8::Local<Value> a5[argc] = {v8_num(6), v8_num(4), v8_num(3), v8_num(3)}; + fun->Call(context.local(), fun, argc, a5).ToLocalChecked(); } @@ -5297,24 +5979,40 @@ THREADED_TEST(ThrowValues) { Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("Throw"), v8::FunctionTemplate::New(isolate, ThrowValue)); LocalContext context(0, templ); - v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( - "function Run(obj) {" - " try {" - " Throw(obj);" - " } catch (e) {" - " return e;" - " }" - " return 'no exception';" - "}" - "[Run('str'), Run(1), Run(0), Run(null), Run(void 0)];")); + v8::Local<v8::Array> result = v8::Local<v8::Array>::Cast( + CompileRun("function Run(obj) {" + " try {" + " Throw(obj);" + " } catch (e) {" + " return e;" + " }" + " return 'no exception';" + "}" + "[Run('str'), Run(1), Run(0), Run(null), Run(void 0)];")); CHECK_EQ(5u, result->Length()); - CHECK(result->Get(v8::Integer::New(isolate, 0))->IsString()); - CHECK(result->Get(v8::Integer::New(isolate, 1))->IsNumber()); - CHECK_EQ(1, result->Get(v8::Integer::New(isolate, 1))->Int32Value()); - CHECK(result->Get(v8::Integer::New(isolate, 2))->IsNumber()); - CHECK_EQ(0, result->Get(v8::Integer::New(isolate, 2))->Int32Value()); - CHECK(result->Get(v8::Integer::New(isolate, 3))->IsNull()); - CHECK(result->Get(v8::Integer::New(isolate, 4))->IsUndefined()); + CHECK(result->Get(context.local(), v8::Integer::New(isolate, 0)) + .ToLocalChecked() + ->IsString()); + CHECK(result->Get(context.local(), v8::Integer::New(isolate, 1)) + .ToLocalChecked() + ->IsNumber()); + CHECK_EQ(1, result->Get(context.local(), v8::Integer::New(isolate, 1)) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK(result->Get(context.local(), v8::Integer::New(isolate, 2)) + .ToLocalChecked() + ->IsNumber()); + CHECK_EQ(0, result->Get(context.local(), v8::Integer::New(isolate, 2)) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK(result->Get(context.local(), v8::Integer::New(isolate, 3)) + .ToLocalChecked() + ->IsNull()); + CHECK(result->Get(context.local(), v8::Integer::New(isolate, 4)) + .ToLocalChecked() + ->IsUndefined()); } @@ -5325,12 +6023,12 @@ THREADED_TEST(CatchZero) { CHECK(!try_catch.HasCaught()); CompileRun("throw 10"); CHECK(try_catch.HasCaught()); - CHECK_EQ(10, try_catch.Exception()->Int32Value()); + CHECK_EQ(10, try_catch.Exception()->Int32Value(context.local()).FromJust()); try_catch.Reset(); CHECK(!try_catch.HasCaught()); CompileRun("throw 0"); CHECK(try_catch.HasCaught()); - CHECK_EQ(0, try_catch.Exception()->Int32Value()); + CHECK_EQ(0, try_catch.Exception()->Int32Value(context.local()).FromJust()); } @@ -5364,9 +6062,12 @@ THREADED_TEST(TryCatchAndFinally) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - context->Global()->Set( - v8_str("native_with_try_catch"), - v8::FunctionTemplate::New(isolate, WithTryCatch)->GetFunction()); + CHECK(context->Global() + ->Set(context.local(), v8_str("native_with_try_catch"), + v8::FunctionTemplate::New(isolate, WithTryCatch) + ->GetFunction(context.local()) + .ToLocalChecked()) + .FromJust()); v8::TryCatch try_catch(isolate); CHECK(!try_catch.HasCaught()); CompileRun( @@ -5430,13 +6131,15 @@ TEST(TryCatchNested) { void TryCatchMixedNestingCheck(v8::TryCatch* try_catch) { CHECK(try_catch->HasCaught()); - Handle<Message> message = try_catch->Message(); - Handle<Value> resource = message->GetScriptOrigin().ResourceName(); + Local<Message> message = try_catch->Message(); + Local<Value> resource = message->GetScriptOrigin().ResourceName(); CHECK_EQ(0, strcmp(*v8::String::Utf8Value(resource), "inner")); CHECK_EQ(0, strcmp(*v8::String::Utf8Value(message->Get()), "Uncaught Error: a")); - CHECK_EQ(1, message->GetLineNumber()); - CHECK_EQ(0, message->GetStartColumn()); + CHECK_EQ(1, message->GetLineNumber(CcTest::isolate()->GetCurrentContext()) + .FromJust()); + CHECK_EQ(0, message->GetStartColumn(CcTest::isolate()->GetCurrentContext()) + .FromJust()); } @@ -5522,14 +6225,14 @@ THREADED_TEST(Equality) { v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(context->GetIsolate()); // Check that equality works at all before relying on CHECK_EQ - CHECK(v8_str("a")->Equals(v8_str("a"))); - CHECK(!v8_str("a")->Equals(v8_str("b"))); + CHECK(v8_str("a")->Equals(context.local(), v8_str("a")).FromJust()); + CHECK(!v8_str("a")->Equals(context.local(), v8_str("b")).FromJust()); - CHECK(v8_str("a")->Equals(v8_str("a"))); - CHECK(!v8_str("a")->Equals(v8_str("b"))); - CHECK(v8_num(1)->Equals(v8_num(1))); - CHECK(v8_num(1.00)->Equals(v8_num(1))); - CHECK(!v8_num(1)->Equals(v8_num(2))); + CHECK(v8_str("a")->Equals(context.local(), v8_str("a")).FromJust()); + CHECK(!v8_str("a")->Equals(context.local(), v8_str("b")).FromJust()); + CHECK(v8_num(1)->Equals(context.local(), v8_num(1)).FromJust()); + CHECK(v8_num(1.00)->Equals(context.local(), v8_num(1)).FromJust()); + CHECK(!v8_num(1)->Equals(context.local(), v8_num(2)).FromJust()); // Assume String is not internalized. CHECK(v8_str("a")->StrictEquals(v8_str("a"))); @@ -5543,7 +6246,7 @@ THREADED_TEST(Equality) { CHECK(v8::False(isolate)->StrictEquals(v8::False(isolate))); CHECK(!v8::False(isolate)->StrictEquals(v8::Undefined(isolate))); - v8::Handle<v8::Object> obj = v8::Object::New(isolate); + v8::Local<v8::Object> obj = v8::Object::New(isolate); v8::Persistent<v8::Object> alias(isolate, obj); CHECK(v8::Local<v8::Object>::New(isolate, alias)->StrictEquals(obj)); alias.Reset(); @@ -5564,15 +6267,20 @@ THREADED_TEST(MultiRun) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); Local<Script> script = v8_compile("x"); - for (int i = 0; i < 10; i++) script->Run(); + for (int i = 0; i < 10; i++) { + script->Run(context.local()).IsEmpty(); + } } -static void GetXValue(Local<String> name, +static void GetXValue(Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - CHECK(info.Data()->Equals(v8_str("donut"))); - CHECK(name->Equals(v8_str("x"))); + CHECK(info.Data() + ->Equals(CcTest::isolate()->GetCurrentContext(), v8_str("donut")) + .FromJust()); + CHECK(name->Equals(CcTest::isolate()->GetCurrentContext(), v8_str("x")) + .FromJust()); info.GetReturnValue().Set(name); } @@ -5583,11 +6291,14 @@ THREADED_TEST(SimplePropertyRead) { v8::HandleScope scope(isolate); Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); Local<Script> script = v8_compile("obj.x"); for (int i = 0; i < 10; i++) { - Local<Value> result = script->Run(); - CHECK(result->Equals(v8_str("x"))); + Local<Value> result = script->Run(context.local()).ToLocalChecked(); + CHECK(result->Equals(context.local(), v8_str("x")).FromJust()); } } @@ -5598,15 +6309,18 @@ THREADED_TEST(DefinePropertyOnAPIAccessor) { v8::HandleScope scope(isolate); Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); // Uses getOwnPropertyDescriptor to check the configurable status Local<Script> script_desc = v8_compile( "var prop = Object.getOwnPropertyDescriptor( " "obj, 'x');" "prop.configurable;"); - Local<Value> result = script_desc->Run(); - CHECK_EQ(result->BooleanValue(), true); + Local<Value> result = script_desc->Run(context.local()).ToLocalChecked(); + CHECK_EQ(result->BooleanValue(context.local()).FromJust(), true); // Redefine get - but still configurable Local<Script> script_define = v8_compile( @@ -5614,12 +6328,12 @@ THREADED_TEST(DefinePropertyOnAPIAccessor) { " configurable: true };" "Object.defineProperty(obj, 'x', desc);" "obj.x"); - result = script_define->Run(); - CHECK(result->Equals(v8_num(42))); + result = script_define->Run(context.local()).ToLocalChecked(); + CHECK(result->Equals(context.local(), v8_num(42)).FromJust()); // Check that the accessor is still configurable - result = script_desc->Run(); - CHECK_EQ(result->BooleanValue(), true); + result = script_desc->Run(context.local()).ToLocalChecked(); + CHECK_EQ(result->BooleanValue(context.local()).FromJust(), true); // Redefine to a non-configurable script_define = v8_compile( @@ -5627,14 +6341,14 @@ THREADED_TEST(DefinePropertyOnAPIAccessor) { " configurable: false };" "Object.defineProperty(obj, 'x', desc);" "obj.x"); - result = script_define->Run(); - CHECK(result->Equals(v8_num(43))); - result = script_desc->Run(); - CHECK_EQ(result->BooleanValue(), false); + result = script_define->Run(context.local()).ToLocalChecked(); + CHECK(result->Equals(context.local(), v8_num(43)).FromJust()); + result = script_desc->Run(context.local()).ToLocalChecked(); + CHECK_EQ(result->BooleanValue(context.local()).FromJust(), false); // Make sure that it is not possible to redefine again v8::TryCatch try_catch(isolate); - result = script_define->Run(); + CHECK(script_define->Run(context.local()).IsEmpty()); CHECK(try_catch.HasCaught()); String::Utf8Value exception_value(try_catch.Exception()); CHECK_EQ(0, @@ -5648,42 +6362,43 @@ THREADED_TEST(DefinePropertyOnDefineGetterSetter) { Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")); LocalContext context; - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); Local<Script> script_desc = v8_compile( "var prop =" "Object.getOwnPropertyDescriptor( " "obj, 'x');" "prop.configurable;"); - Local<Value> result = script_desc->Run(); - CHECK_EQ(result->BooleanValue(), true); + Local<Value> result = script_desc->Run(context.local()).ToLocalChecked(); + CHECK_EQ(result->BooleanValue(context.local()).FromJust(), true); Local<Script> script_define = v8_compile( "var desc = {get: function(){return 42; }," " configurable: true };" "Object.defineProperty(obj, 'x', desc);" "obj.x"); - result = script_define->Run(); - CHECK(result->Equals(v8_num(42))); - - - result = script_desc->Run(); - CHECK_EQ(result->BooleanValue(), true); + result = script_define->Run(context.local()).ToLocalChecked(); + CHECK(result->Equals(context.local(), v8_num(42)).FromJust()); + result = script_desc->Run(context.local()).ToLocalChecked(); + CHECK_EQ(result->BooleanValue(context.local()).FromJust(), true); script_define = v8_compile( "var desc = {get: function(){return 43; }," " configurable: false };" "Object.defineProperty(obj, 'x', desc);" "obj.x"); - result = script_define->Run(); - CHECK(result->Equals(v8_num(43))); - result = script_desc->Run(); + result = script_define->Run(context.local()).ToLocalChecked(); + CHECK(result->Equals(context.local(), v8_num(43)).FromJust()); - CHECK_EQ(result->BooleanValue(), false); + result = script_desc->Run(context.local()).ToLocalChecked(); + CHECK_EQ(result->BooleanValue(context.local()).FromJust(), false); v8::TryCatch try_catch(isolate); - result = script_define->Run(); + CHECK(script_define->Run(context.local()).IsEmpty()); CHECK(try_catch.HasCaught()); String::Utf8Value exception_value(try_catch.Exception()); CHECK_EQ(0, @@ -5691,9 +6406,13 @@ THREADED_TEST(DefinePropertyOnDefineGetterSetter) { } -static v8::Handle<v8::Object> GetGlobalProperty(LocalContext* context, - char const* name) { - return v8::Handle<v8::Object>::Cast((*context)->Global()->Get(v8_str(name))); +static v8::Local<v8::Object> GetGlobalProperty(LocalContext* context, + char const* name) { + return v8::Local<v8::Object>::Cast( + (*context) + ->Global() + ->Get(CcTest::isolate()->GetCurrentContext(), v8_str(name)) + .ToLocalChecked()); } @@ -5703,20 +6422,27 @@ THREADED_TEST(DefineAPIAccessorOnObject) { Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); LocalContext context; - context->Global()->Set(v8_str("obj1"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj1"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun("var obj2 = {};"); CHECK(CompileRun("obj1.x")->IsUndefined()); CHECK(CompileRun("obj2.x")->IsUndefined()); CHECK(GetGlobalProperty(&context, "obj1") - ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); + ->SetAccessor(context.local(), v8_str("x"), GetXValue, NULL, + v8_str("donut")) + .FromJust()); ExpectString("obj1.x", "x"); CHECK(CompileRun("obj2.x")->IsUndefined()); CHECK(GetGlobalProperty(&context, "obj2") - ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); + ->SetAccessor(context.local(), v8_str("x"), GetXValue, NULL, + v8_str("donut")) + .FromJust()); ExpectString("obj1.x", "x"); ExpectString("obj2.x", "x"); @@ -5742,9 +6468,13 @@ THREADED_TEST(DefineAPIAccessorOnObject) { ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); CHECK(GetGlobalProperty(&context, "obj1") - ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); + ->SetAccessor(context.local(), v8_str("x"), GetXValue, NULL, + v8_str("donut")) + .FromJust()); CHECK(GetGlobalProperty(&context, "obj2") - ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); + ->SetAccessor(context.local(), v8_str("x"), GetXValue, NULL, + v8_str("donut")) + .FromJust()); ExpectString("obj1.x", "x"); ExpectString("obj2.x", "x"); @@ -5759,17 +6489,20 @@ THREADED_TEST(DefineAPIAccessorOnObject) { CompileRun( "Object.defineProperty(obj2, 'x'," "{ get: function() { return 'z'; }, configurable: false })"); - ExpectTrue("!Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); ExpectTrue("!Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); ExpectString("obj1.x", "z"); ExpectString("obj2.x", "z"); - CHECK(!GetGlobalProperty(&context, "obj1") - ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); - CHECK(!GetGlobalProperty(&context, "obj2") - ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); + CHECK(GetGlobalProperty(&context, "obj1") + ->SetAccessor(context.local(), v8_str("x"), GetXValue, NULL, + v8_str("donut")) + .IsNothing()); + CHECK(GetGlobalProperty(&context, "obj2") + ->SetAccessor(context.local(), v8_str("x"), GetXValue, NULL, + v8_str("donut")) + .IsNothing()); ExpectString("obj1.x", "z"); ExpectString("obj2.x", "z"); @@ -5782,15 +6515,20 @@ THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) { Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); LocalContext context; - context->Global()->Set(v8_str("obj1"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj1"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun("var obj2 = {};"); CHECK(GetGlobalProperty(&context, "obj1") - ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"), - v8::DEFAULT, v8::DontDelete)); + ->SetAccessor(context.local(), v8_str("x"), GetXValue, NULL, + v8_str("donut"), v8::DEFAULT, v8::DontDelete) + .FromJust()); CHECK(GetGlobalProperty(&context, "obj2") - ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"), - v8::DEFAULT, v8::DontDelete)); + ->SetAccessor(context.local(), v8_str("x"), GetXValue, NULL, + v8_str("donut"), v8::DEFAULT, v8::DontDelete) + .FromJust()); ExpectString("obj1.x", "x"); ExpectString("obj2.x", "x"); @@ -5798,10 +6536,14 @@ THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) { ExpectTrue("!Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); ExpectTrue("!Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); - CHECK(!GetGlobalProperty(&context, "obj1") - ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); - CHECK(!GetGlobalProperty(&context, "obj2") - ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); + CHECK(GetGlobalProperty(&context, "obj1") + ->SetAccessor(context.local(), v8_str("x"), GetXValue, NULL, + v8_str("donut")) + .IsNothing()); + CHECK(GetGlobalProperty(&context, "obj2") + ->SetAccessor(context.local(), v8_str("x"), GetXValue, NULL, + v8_str("donut")) + .IsNothing()); { v8::TryCatch try_catch(isolate); @@ -5826,11 +6568,14 @@ THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) { } -static void Get239Value(Local<String> name, +static void Get239Value(Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - CHECK(info.Data()->Equals(v8_str("donut"))); - CHECK(name->Equals(v8_str("239"))); + CHECK(info.Data() + ->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("donut")) + .FromJust()); + CHECK(name->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("239")) + .FromJust()); info.GetReturnValue().Set(name); } @@ -5841,13 +6586,20 @@ THREADED_TEST(ElementAPIAccessor) { Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); LocalContext context; - context->Global()->Set(v8_str("obj1"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj1"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun("var obj2 = {};"); CHECK(GetGlobalProperty(&context, "obj1") - ->SetAccessor(v8_str("239"), Get239Value, NULL, v8_str("donut"))); + ->SetAccessor(context.local(), v8_str("239"), Get239Value, NULL, + v8_str("donut")) + .FromJust()); CHECK(GetGlobalProperty(&context, "obj2") - ->SetAccessor(v8_str("239"), Get239Value, NULL, v8_str("donut"))); + ->SetAccessor(context.local(), v8_str("239"), Get239Value, NULL, + v8_str("donut")) + .FromJust()); ExpectString("obj1[239]", "239"); ExpectString("obj2[239]", "239"); @@ -5859,11 +6611,12 @@ THREADED_TEST(ElementAPIAccessor) { v8::Persistent<Value> xValue; -static void SetXValue(Local<String> name, Local<Value> value, +static void SetXValue(Local<Name> name, Local<Value> value, const v8::PropertyCallbackInfo<void>& info) { - CHECK(value->Equals(v8_num(4))); - CHECK(info.Data()->Equals(v8_str("donut"))); - CHECK(name->Equals(v8_str("x"))); + Local<Context> context = info.GetIsolate()->GetCurrentContext(); + CHECK(value->Equals(context, v8_num(4)).FromJust()); + CHECK(info.Data()->Equals(context, v8_str("donut")).FromJust()); + CHECK(name->Equals(context, v8_str("x")).FromJust()); CHECK(xValue.IsEmpty()); xValue.Reset(info.GetIsolate(), value); } @@ -5875,12 +6628,18 @@ THREADED_TEST(SimplePropertyWrite) { Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), GetXValue, SetXValue, v8_str("donut")); LocalContext context; - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); Local<Script> script = v8_compile("obj.x = 4"); for (int i = 0; i < 10; i++) { CHECK(xValue.IsEmpty()); - script->Run(); - CHECK(v8_num(4)->Equals(Local<Value>::New(CcTest::isolate(), xValue))); + script->Run(context.local()).ToLocalChecked(); + CHECK(v8_num(4) + ->Equals(context.local(), + Local<Value>::New(CcTest::isolate(), xValue)) + .FromJust()); xValue.Reset(); } } @@ -5892,12 +6651,18 @@ THREADED_TEST(SetterOnly) { Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), NULL, SetXValue, v8_str("donut")); LocalContext context; - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); Local<Script> script = v8_compile("obj.x = 4; obj.x"); for (int i = 0; i < 10; i++) { CHECK(xValue.IsEmpty()); - script->Run(); - CHECK(v8_num(4)->Equals(Local<Value>::New(CcTest::isolate(), xValue))); + script->Run(context.local()).ToLocalChecked(); + CHECK(v8_num(4) + ->Equals(context.local(), + Local<Value>::New(CcTest::isolate(), xValue)) + .FromJust()); xValue.Reset(); } } @@ -5910,10 +6675,13 @@ THREADED_TEST(NoAccessors) { templ->SetAccessor(v8_str("x"), static_cast<v8::AccessorGetterCallback>(NULL), NULL, v8_str("donut")); LocalContext context; - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); Local<Script> script = v8_compile("obj.x = 4; obj.x"); for (int i = 0; i < 10; i++) { - script->Run(); + script->Run(context.local()).ToLocalChecked(); } } @@ -5921,7 +6689,7 @@ THREADED_TEST(NoAccessors) { THREADED_TEST(MultiContexts) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("dummy"), v8::FunctionTemplate::New(isolate, DummyCallHandler)); @@ -5930,26 +6698,43 @@ THREADED_TEST(MultiContexts) { // Create an environment LocalContext context0(0, templ); context0->SetSecurityToken(password); - v8::Handle<v8::Object> global0 = context0->Global(); - global0->Set(v8_str("custom"), v8_num(1234)); - CHECK_EQ(1234, global0->Get(v8_str("custom"))->Int32Value()); + v8::Local<v8::Object> global0 = context0->Global(); + CHECK(global0->Set(context0.local(), v8_str("custom"), v8_num(1234)) + .FromJust()); + CHECK_EQ(1234, global0->Get(context0.local(), v8_str("custom")) + .ToLocalChecked() + ->Int32Value(context0.local()) + .FromJust()); // Create an independent environment LocalContext context1(0, templ); context1->SetSecurityToken(password); - v8::Handle<v8::Object> global1 = context1->Global(); - global1->Set(v8_str("custom"), v8_num(1234)); - CHECK(!global0->Equals(global1)); - CHECK_EQ(1234, global0->Get(v8_str("custom"))->Int32Value()); - CHECK_EQ(1234, global1->Get(v8_str("custom"))->Int32Value()); + v8::Local<v8::Object> global1 = context1->Global(); + CHECK(global1->Set(context1.local(), v8_str("custom"), v8_num(1234)) + .FromJust()); + CHECK(!global0->Equals(context1.local(), global1).FromJust()); + CHECK_EQ(1234, global0->Get(context1.local(), v8_str("custom")) + .ToLocalChecked() + ->Int32Value(context0.local()) + .FromJust()); + CHECK_EQ(1234, global1->Get(context1.local(), v8_str("custom")) + .ToLocalChecked() + ->Int32Value(context1.local()) + .FromJust()); // Now create a new context with the old global LocalContext context2(0, templ, global1); context2->SetSecurityToken(password); - v8::Handle<v8::Object> global2 = context2->Global(); - CHECK(global1->Equals(global2)); - CHECK_EQ(0, global1->Get(v8_str("custom"))->Int32Value()); - CHECK_EQ(0, global2->Get(v8_str("custom"))->Int32Value()); + v8::Local<v8::Object> global2 = context2->Global(); + CHECK(global1->Equals(context2.local(), global2).FromJust()); + CHECK_EQ(0, global1->Get(context2.local(), v8_str("custom")) + .ToLocalChecked() + ->Int32Value(context1.local()) + .FromJust()); + CHECK_EQ(0, global2->Get(context2.local(), v8_str("custom")) + .ToLocalChecked() + ->Int32Value(context2.local()) + .FromJust()); } @@ -5960,24 +6745,34 @@ THREADED_TEST(FunctionPrototypeAcrossContexts) { v8::HandleScope scope(CcTest::isolate()); LocalContext env0; - v8::Handle<v8::Object> global0 = env0->Global(); - v8::Handle<v8::Object> object0 = - global0->Get(v8_str("Object")).As<v8::Object>(); - v8::Handle<v8::Object> tostring0 = - object0->Get(v8_str("toString")).As<v8::Object>(); - v8::Handle<v8::Object> proto0 = - tostring0->Get(v8_str("__proto__")).As<v8::Object>(); - proto0->Set(v8_str("custom"), v8_num(1234)); + v8::Local<v8::Object> global0 = env0->Global(); + v8::Local<v8::Object> object0 = global0->Get(env0.local(), v8_str("Object")) + .ToLocalChecked() + .As<v8::Object>(); + v8::Local<v8::Object> tostring0 = + object0->Get(env0.local(), v8_str("toString")) + .ToLocalChecked() + .As<v8::Object>(); + v8::Local<v8::Object> proto0 = + tostring0->Get(env0.local(), v8_str("__proto__")) + .ToLocalChecked() + .As<v8::Object>(); + CHECK(proto0->Set(env0.local(), v8_str("custom"), v8_num(1234)).FromJust()); LocalContext env1; - v8::Handle<v8::Object> global1 = env1->Global(); - v8::Handle<v8::Object> object1 = - global1->Get(v8_str("Object")).As<v8::Object>(); - v8::Handle<v8::Object> tostring1 = - object1->Get(v8_str("toString")).As<v8::Object>(); - v8::Handle<v8::Object> proto1 = - tostring1->Get(v8_str("__proto__")).As<v8::Object>(); - CHECK(!proto1->Has(v8_str("custom"))); + v8::Local<v8::Object> global1 = env1->Global(); + v8::Local<v8::Object> object1 = global1->Get(env1.local(), v8_str("Object")) + .ToLocalChecked() + .As<v8::Object>(); + v8::Local<v8::Object> tostring1 = + object1->Get(env1.local(), v8_str("toString")) + .ToLocalChecked() + .As<v8::Object>(); + v8::Local<v8::Object> proto1 = + tostring1->Get(env1.local(), v8_str("__proto__")) + .ToLocalChecked() + .As<v8::Object>(); + CHECK(!proto1->Has(env1.local(), v8_str("custom")).FromJust()); } @@ -5997,11 +6792,17 @@ THREADED_TEST(Regress892105) { LocalContext env0; Local<Script> script0 = v8_compile(source); - CHECK_EQ(8901.0, script0->Run()->NumberValue()); + CHECK_EQ(8901.0, script0->Run(env0.local()) + .ToLocalChecked() + ->NumberValue(env0.local()) + .FromJust()); LocalContext env1; Local<Script> script1 = v8_compile(source); - CHECK_EQ(8901.0, script1->Run()->NumberValue()); + CHECK_EQ(8901.0, script1->Run(env1.local()) + .ToLocalChecked() + ->NumberValue(env1.local()) + .FromJust()); } @@ -6013,8 +6814,12 @@ THREADED_TEST(UndetectableObject) { v8::FunctionTemplate::New(env->GetIsolate()); desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable - Local<v8::Object> obj = desc->GetFunction()->NewInstance(); - env->Global()->Set(v8_str("undetectable"), obj); + Local<v8::Object> obj = desc->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked(); + CHECK( + env->Global()->Set(env.local(), v8_str("undetectable"), obj).FromJust()); ExpectString("undetectable.toString()", "[object Object]"); ExpectString("typeof undetectable", "undefined"); @@ -6057,8 +6862,12 @@ THREADED_TEST(VoidLiteral) { Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable - Local<v8::Object> obj = desc->GetFunction()->NewInstance(); - env->Global()->Set(v8_str("undetectable"), obj); + Local<v8::Object> obj = desc->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked(); + CHECK( + env->Global()->Set(env.local(), v8_str("undetectable"), obj).FromJust()); ExpectBoolean("undefined == void 0", true); ExpectBoolean("undetectable == void 0", true); @@ -6103,8 +6912,12 @@ THREADED_TEST(ExtensibleOnUndetectable) { Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable - Local<v8::Object> obj = desc->GetFunction()->NewInstance(); - env->Global()->Set(v8_str("undetectable"), obj); + Local<v8::Object> obj = desc->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked(); + CHECK( + env->Global()->Set(env.local(), v8_str("undetectable"), obj).FromJust()); Local<String> source = v8_str( "undetectable.x = 42;" @@ -6112,18 +6925,20 @@ THREADED_TEST(ExtensibleOnUndetectable) { Local<Script> script = v8_compile(source); - CHECK(v8::Integer::New(isolate, 42)->Equals(script->Run())); + CHECK(v8::Integer::New(isolate, 42) + ->Equals(env.local(), script->Run(env.local()).ToLocalChecked()) + .FromJust()); ExpectBoolean("Object.isExtensible(undetectable)", true); source = v8_str("Object.preventExtensions(undetectable);"); script = v8_compile(source); - script->Run(); + script->Run(env.local()).ToLocalChecked(); ExpectBoolean("Object.isExtensible(undetectable)", false); source = v8_str("undetectable.y = 2000;"); script = v8_compile(source); - script->Run(); + script->Run(env.local()).ToLocalChecked(); ExpectBoolean("undetectable.y == undefined", true); } @@ -6175,10 +6990,11 @@ TEST(SimpleExtensions) { v8::RegisterExtension(new Extension("simpletest", kSimpleExtensionSource)); const char* extension_names[] = {"simpletest"}; v8::ExtensionConfiguration extensions(1, extension_names); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); + v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); - v8::Handle<Value> result = CompileRun("Foo()"); - CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); + v8::Local<Value> result = CompileRun("Foo()"); + CHECK(result->Equals(context, v8::Integer::New(CcTest::isolate(), 4)) + .FromJust()); } @@ -6197,15 +7013,15 @@ TEST(StackTraceInExtension) { new Extension("stacktracetest", kStackTraceFromExtensionSource)); const char* extension_names[] = {"stacktracetest"}; v8::ExtensionConfiguration extensions(1, extension_names); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); + v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); CompileRun( "function user() { bar(); }" "var error;" "try{ user(); } catch (e) { error = e; }"); - CHECK_EQ(-1, CompileRun("error.stack.indexOf('foo')")->Int32Value()); - CHECK_EQ(-1, CompileRun("error.stack.indexOf('bar')")->Int32Value()); - CHECK_NE(-1, CompileRun("error.stack.indexOf('user')")->Int32Value()); + CHECK_EQ(-1, v8_run_int32value(v8_compile("error.stack.indexOf('foo')"))); + CHECK_EQ(-1, v8_run_int32value(v8_compile("error.stack.indexOf('bar')"))); + CHECK_NE(-1, v8_run_int32value(v8_compile("error.stack.indexOf('user')"))); } @@ -6214,10 +7030,11 @@ TEST(NullExtensions) { v8::RegisterExtension(new Extension("nulltest", NULL)); const char* extension_names[] = {"nulltest"}; v8::ExtensionConfiguration extensions(1, extension_names); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); + v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); - v8::Handle<Value> result = CompileRun("1+3"); - CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); + v8::Local<Value> result = CompileRun("1+3"); + CHECK(result->Equals(context, v8::Integer::New(CcTest::isolate(), 4)) + .FromJust()); } @@ -6233,7 +7050,7 @@ TEST(ExtensionMissingSourceLength) { new Extension("srclentest_fail", kEmbeddedExtensionSource)); const char* extension_names[] = {"srclentest_fail"}; v8::ExtensionConfiguration extensions(1, extension_names); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); + v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); CHECK(0 == *context); } @@ -6248,11 +7065,13 @@ TEST(ExtensionWithSourceLength) { extension_name.start(), kEmbeddedExtensionSource, 0, 0, source_len)); const char* extension_names[1] = {extension_name.start()}; v8::ExtensionConfiguration extensions(1, extension_names); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); + v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); if (source_len == kEmbeddedExtensionSourceValidLen) { Context::Scope lock(context); - v8::Handle<Value> result = CompileRun("Ret54321()"); - CHECK(v8::Integer::New(CcTest::isolate(), 54321)->Equals(result)); + v8::Local<Value> result = CompileRun("Ret54321()"); + CHECK(v8::Integer::New(CcTest::isolate(), 54321) + ->Equals(context, result) + .FromJust()); } else { // Anything but exactly the right length should fail to compile. CHECK(0 == *context); @@ -6284,12 +7103,14 @@ TEST(UseEvalFromExtension) { v8::RegisterExtension(new Extension("evaltest2", kEvalExtensionSource2)); const char* extension_names[] = {"evaltest1", "evaltest2"}; v8::ExtensionConfiguration extensions(2, extension_names); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); + v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); - v8::Handle<Value> result = CompileRun("UseEval1()"); - CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); + v8::Local<Value> result = CompileRun("UseEval1()"); + CHECK(result->Equals(context, v8::Integer::New(CcTest::isolate(), 42)) + .FromJust()); result = CompileRun("UseEval2()"); - CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); + CHECK(result->Equals(context, v8::Integer::New(CcTest::isolate(), 42)) + .FromJust()); } @@ -6316,12 +7137,14 @@ TEST(UseWithFromExtension) { v8::RegisterExtension(new Extension("withtest2", kWithExtensionSource2)); const char* extension_names[] = {"withtest1", "withtest2"}; v8::ExtensionConfiguration extensions(2, extension_names); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); + v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); - v8::Handle<Value> result = CompileRun("UseWith1()"); - CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 87))); + v8::Local<Value> result = CompileRun("UseWith1()"); + CHECK(result->Equals(context, v8::Integer::New(CcTest::isolate(), 87)) + .FromJust()); result = CompileRun("UseWith2()"); - CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 87))); + CHECK(result->Equals(context, v8::Integer::New(CcTest::isolate(), 87)) + .FromJust()); } @@ -6330,10 +7153,11 @@ TEST(AutoExtensions) { Extension* extension = new Extension("autotest", kSimpleExtensionSource); extension->set_auto_enable(true); v8::RegisterExtension(extension); - v8::Handle<Context> context = Context::New(CcTest::isolate()); + v8::Local<Context> context = Context::New(CcTest::isolate()); Context::Scope lock(context); - v8::Handle<Value> result = CompileRun("Foo()"); - CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); + v8::Local<Value> result = CompileRun("Foo()"); + CHECK(result->Equals(context, v8::Integer::New(CcTest::isolate(), 4)) + .FromJust()); } @@ -6348,7 +7172,7 @@ TEST(SyntaxErrorExtensions) { new Extension("syntaxerror", kSyntaxErrorInExtensionSource)); const char* extension_names[] = {"syntaxerror"}; v8::ExtensionConfiguration extensions(1, extension_names); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); + v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); CHECK(context.IsEmpty()); } @@ -6364,7 +7188,7 @@ TEST(ExceptionExtensions) { new Extension("exception", kExceptionInExtensionSource)); const char* extension_names[] = {"exception"}; v8::ExtensionConfiguration extensions(1, extension_names); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); + v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); CHECK(context.IsEmpty()); } @@ -6385,10 +7209,11 @@ TEST(NativeCallInExtensions) { new Extension("nativecall", kNativeCallInExtensionSource)); const char* extension_names[] = {"nativecall"}; v8::ExtensionConfiguration extensions(1, extension_names); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); + v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); - v8::Handle<Value> result = CompileRun(kNativeCallTest); - CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 3))); + v8::Local<Value> result = CompileRun(kNativeCallTest); + CHECK(result->Equals(context, v8::Integer::New(CcTest::isolate(), 3)) + .FromJust()); } @@ -6398,8 +7223,8 @@ class NativeFunctionExtension : public Extension { v8::FunctionCallback fun = &Echo) : Extension(name, source), function_(fun) {} - virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( - v8::Isolate* isolate, v8::Handle<v8::String> name) { + virtual v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate( + v8::Isolate* isolate, v8::Local<v8::String> name) { return v8::FunctionTemplate::New(isolate, function_); } @@ -6419,10 +7244,11 @@ TEST(NativeFunctionDeclaration) { new NativeFunctionExtension(name, "native function foo();")); const char* extension_names[] = {name}; v8::ExtensionConfiguration extensions(1, extension_names); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); + v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); Context::Scope lock(context); - v8::Handle<Value> result = CompileRun("foo(42);"); - CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); + v8::Local<Value> result = CompileRun("foo(42);"); + CHECK(result->Equals(context, v8::Integer::New(CcTest::isolate(), 42)) + .FromJust()); } @@ -6434,7 +7260,7 @@ TEST(NativeFunctionDeclarationError) { new NativeFunctionExtension(name, "native\nfunction foo();")); const char* extension_names[] = {name}; v8::ExtensionConfiguration extensions(1, extension_names); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); + v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); CHECK(context.IsEmpty()); } @@ -6448,7 +7274,7 @@ TEST(NativeFunctionDeclarationErrorEscape) { new NativeFunctionExtension(name, "nativ\\u0065 function foo();")); const char* extension_names[] = {name}; v8::ExtensionConfiguration extensions(1, extension_names); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); + v8::Local<Context> context = Context::New(CcTest::isolate(), &extensions); CHECK(context.IsEmpty()); } @@ -6457,8 +7283,12 @@ static void CheckDependencies(const char* name, const char* expected) { v8::HandleScope handle_scope(CcTest::isolate()); v8::ExtensionConfiguration config(1, &name); LocalContext context(&config); - CHECK(String::NewFromUtf8(CcTest::isolate(), expected) - ->Equals(context->Global()->Get(v8_str("loaded")))); + CHECK( + v8_str(expected) + ->Equals(context.local(), context->Global() + ->Get(context.local(), v8_str("loaded")) + .ToLocalChecked()) + .FromJust()); } @@ -6487,8 +7317,12 @@ THREADED_TEST(ExtensionDependency) { static const char* exts[2] = {"C", "E"}; v8::ExtensionConfiguration config(2, exts); LocalContext context(&config); - CHECK(v8_str("undefinedACBDE") - ->Equals(context->Global()->Get(v8_str("loaded")))); + CHECK( + v8_str("undefinedACBDE") + ->Equals(context.local(), context->Global() + ->Get(context.local(), v8_str("loaded")) + .ToLocalChecked()) + .FromJust()); } @@ -6506,7 +7340,10 @@ static const char* kExtensionTestScript = static void CallFun(const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); if (args.IsConstructCall()) { - args.This()->Set(v8_str("data"), args.Data()); + CHECK(args.This() + ->Set(args.GetIsolate()->GetCurrentContext(), v8_str("data"), + args.Data()) + .FromJust()); args.GetReturnValue().SetNull(); return; } @@ -6517,26 +7354,28 @@ static void CallFun(const v8::FunctionCallbackInfo<v8::Value>& args) { class FunctionExtension : public Extension { public: FunctionExtension() : Extension("functiontest", kExtensionTestScript) {} - virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( - v8::Isolate* isolate, v8::Handle<String> name); + virtual v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate( + v8::Isolate* isolate, v8::Local<String> name); }; static int lookup_count = 0; -v8::Handle<v8::FunctionTemplate> FunctionExtension::GetNativeFunctionTemplate( - v8::Isolate* isolate, v8::Handle<String> name) { +v8::Local<v8::FunctionTemplate> FunctionExtension::GetNativeFunctionTemplate( + v8::Isolate* isolate, v8::Local<String> name) { lookup_count++; - if (name->Equals(v8_str("A"))) { + if (name->Equals(isolate->GetCurrentContext(), v8_str("A")).FromJust()) { return v8::FunctionTemplate::New(isolate, CallFun, v8::Integer::New(isolate, 8)); - } else if (name->Equals(v8_str("B"))) { + } else if (name->Equals(isolate->GetCurrentContext(), v8_str("B")) + .FromJust()) { return v8::FunctionTemplate::New(isolate, CallFun, v8::Integer::New(isolate, 7)); - } else if (name->Equals(v8_str("C"))) { + } else if (name->Equals(isolate->GetCurrentContext(), v8_str("C")) + .FromJust()) { return v8::FunctionTemplate::New(isolate, CallFun, v8::Integer::New(isolate, 6)); } else { - return v8::Handle<v8::FunctionTemplate>(); + return v8::Local<v8::FunctionTemplate>(); } } @@ -6548,9 +7387,15 @@ THREADED_TEST(FunctionLookup) { v8::ExtensionConfiguration config(1, exts); LocalContext context(&config); CHECK_EQ(3, lookup_count); - CHECK(v8::Integer::New(CcTest::isolate(), 8)->Equals(CompileRun("Foo(0)"))); - CHECK(v8::Integer::New(CcTest::isolate(), 7)->Equals(CompileRun("Foo(1)"))); - CHECK(v8::Integer::New(CcTest::isolate(), 6)->Equals(CompileRun("Foo(2)"))); + CHECK(v8::Integer::New(CcTest::isolate(), 8) + ->Equals(context.local(), CompileRun("Foo(0)")) + .FromJust()); + CHECK(v8::Integer::New(CcTest::isolate(), 7) + ->Equals(context.local(), CompileRun("Foo(1)")) + .FromJust()); + CHECK(v8::Integer::New(CcTest::isolate(), 6) + ->Equals(context.local(), CompileRun("Foo(2)")) + .FromJust()); } @@ -6564,11 +7409,14 @@ THREADED_TEST(NativeFunctionConstructCall) { // Run a few times to ensure that allocation of objects doesn't // change behavior of a constructor function. CHECK(v8::Integer::New(CcTest::isolate(), 8) - ->Equals(CompileRun("(new A()).data"))); + ->Equals(context.local(), CompileRun("(new A()).data")) + .FromJust()); CHECK(v8::Integer::New(CcTest::isolate(), 7) - ->Equals(CompileRun("(new B()).data"))); + ->Equals(context.local(), CompileRun("(new B()).data")) + .FromJust()); CHECK(v8::Integer::New(CcTest::isolate(), 6) - ->Equals(CompileRun("(new C()).data"))); + ->Equals(context.local(), CompileRun("(new C()).data")) + .FromJust()); } } @@ -6587,35 +7435,39 @@ void StoringErrorCallback(const char* location, const char* message) { // tests that the fatal error handler gets called. This renders V8 // unusable and therefore this test cannot be run in parallel. TEST(ErrorReporting) { - v8::V8::SetFatalErrorHandler(StoringErrorCallback); + CcTest::isolate()->SetFatalErrorHandler(StoringErrorCallback); static const char* aDeps[] = {"B"}; v8::RegisterExtension(new Extension("A", "", 1, aDeps)); static const char* bDeps[] = {"A"}; v8::RegisterExtension(new Extension("B", "", 1, bDeps)); last_location = NULL; v8::ExtensionConfiguration config(1, bDeps); - v8::Handle<Context> context = Context::New(CcTest::isolate(), &config); + v8::Local<Context> context = Context::New(CcTest::isolate(), &config); CHECK(context.IsEmpty()); CHECK(last_location); } -static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message, - v8::Handle<Value> data) { +static void MissingScriptInfoMessageListener(v8::Local<v8::Message> message, + v8::Local<Value> data) { + v8::Isolate* isolate = CcTest::isolate(); + Local<Context> context = isolate->GetCurrentContext(); CHECK(message->GetScriptOrigin().ResourceName()->IsUndefined()); - CHECK(v8::Undefined(CcTest::isolate()) - ->Equals(message->GetScriptOrigin().ResourceName())); - message->GetLineNumber(); - message->GetSourceLine(); + CHECK(v8::Undefined(isolate) + ->Equals(context, message->GetScriptOrigin().ResourceName()) + .FromJust()); + message->GetLineNumber(context).FromJust(); + message->GetSourceLine(context).ToLocalChecked(); } THREADED_TEST(ErrorWithMissingScriptInfo) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::V8::AddMessageListener(MissingScriptInfoMessageListener); + context->GetIsolate()->AddMessageListener(MissingScriptInfoMessageListener); CompileRun("throw Error()"); - v8::V8::RemoveMessageListeners(MissingScriptInfoMessageListener); + context->GetIsolate()->RemoveMessageListeners( + MissingScriptInfoMessageListener); } @@ -6634,7 +7486,7 @@ static void SetFlag(const v8::WeakCallbackInfo<FlagAndPersistent>& data) { static void IndependentWeakHandle(bool global_gc, bool interlinked) { v8::Isolate* iso = CcTest::isolate(); v8::HandleScope scope(iso); - v8::Handle<Context> context = Context::New(iso); + v8::Local<Context> context = Context::New(iso); Context::Scope context_scope(context); FlagAndPersistent object_a, object_b; @@ -6648,8 +7500,8 @@ static void IndependentWeakHandle(bool global_gc, bool interlinked) { object_a.handle.Reset(iso, a); object_b.handle.Reset(iso, b); if (interlinked) { - a->Set(v8_str("x"), b); - b->Set(v8_str("x"), a); + a->Set(context, v8_str("x"), b).FromJust(); + b->Set(context, v8_str("x"), a).FromJust(); } if (global_gc) { CcTest::heap()->CollectAllGarbage(); @@ -6658,8 +7510,8 @@ static void IndependentWeakHandle(bool global_gc, bool interlinked) { } // We are relying on this creating a big flag array and reserving the space // up front. - v8::Handle<Value> big_array = CompileRun("new Array(5000)"); - a->Set(v8_str("y"), big_array); + v8::Local<Value> big_array = CompileRun("new Array(5000)"); + a->Set(context, v8_str("y"), big_array).FromJust(); big_heap_size = CcTest::heap()->SizeOfObjects(); } @@ -6726,8 +7578,8 @@ void CheckInternalFields( const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) { v8::Persistent<v8::Object>* handle = data.GetParameter(); handle->Reset(); - Trivial* t1 = reinterpret_cast<Trivial*>(data.GetInternalField1()); - Trivial2* t2 = reinterpret_cast<Trivial2*>(data.GetInternalField2()); + Trivial* t1 = reinterpret_cast<Trivial*>(data.GetInternalField(0)); + Trivial2* t2 = reinterpret_cast<Trivial2*>(data.GetInternalField(1)); CHECK_EQ(42, t1->x()); CHECK_EQ(103, t2->x()); t1->set_x(1729); @@ -6747,7 +7599,10 @@ void InternalFieldCallback(bool global_gc) { instance_templ->SetInternalFieldCount(2); { v8::HandleScope scope(isolate); - Local<v8::Object> obj = templ->GetFunction()->NewInstance(); + Local<v8::Object> obj = templ->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked(); v8::Persistent<v8::Object> handle(isolate, obj); CHECK_EQ(2, obj->InternalFieldCount()); CHECK(obj->GetInternalField(0)->IsUndefined()); @@ -6805,7 +7660,7 @@ void v8::internal::HeapTester::ResetWeakHandle(bool global_gc) { v8::Isolate* iso = CcTest::isolate(); v8::HandleScope scope(iso); - v8::Handle<Context> context = Context::New(iso); + v8::Local<Context> context = Context::New(iso); Context::Scope context_scope(context); FlagAndPersistent object_a, object_b; @@ -6886,7 +7741,7 @@ THREADED_TEST(GCFromWeakCallbacks) { v8::Isolate* isolate = CcTest::isolate(); v8::Locker locker(CcTest::isolate()); v8::HandleScope scope(isolate); - v8::Handle<Context> context = Context::New(isolate); + v8::Local<Context> context = Context::New(isolate); Context::Scope context_scope(context); static const int kNumberOfGCTypes = 2; @@ -6916,19 +7771,20 @@ THREADED_TEST(GCFromWeakCallbacks) { } -v8::Handle<Function> args_fun; +v8::Local<Function> args_fun; static void ArgumentsTestCallback( const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); v8::Isolate* isolate = args.GetIsolate(); - CHECK(args_fun->Equals(args.Callee())); + Local<Context> context = isolate->GetCurrentContext(); + CHECK(args_fun->Equals(context, args.Callee()).FromJust()); CHECK_EQ(3, args.Length()); - CHECK(v8::Integer::New(isolate, 1)->Equals(args[0])); - CHECK(v8::Integer::New(isolate, 2)->Equals(args[1])); - CHECK(v8::Integer::New(isolate, 3)->Equals(args[2])); - CHECK(v8::Undefined(isolate)->Equals(args[3])); + CHECK(v8::Integer::New(isolate, 1)->Equals(context, args[0]).FromJust()); + CHECK(v8::Integer::New(isolate, 2)->Equals(context, args[1]).FromJust()); + CHECK(v8::Integer::New(isolate, 3)->Equals(context, args[2]).FromJust()); + CHECK(v8::Undefined(isolate)->Equals(context, args[3]).FromJust()); v8::HandleScope scope(args.GetIsolate()); CcTest::heap()->CollectAllGarbage(); } @@ -6937,12 +7793,15 @@ static void ArgumentsTestCallback( THREADED_TEST(Arguments) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> global = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> global = ObjectTemplate::New(isolate); global->Set(v8_str("f"), v8::FunctionTemplate::New(isolate, ArgumentsTestCallback)); LocalContext context(NULL, global); - args_fun = context->Global()->Get(v8_str("f")).As<Function>(); - v8_compile("f(1, 2, 3)")->Run(); + args_fun = context->Global() + ->Get(context.local(), v8_str("f")) + .ToLocalChecked() + .As<Function>(); + v8_compile("f(1, 2, 3)")->Run(context.local()).ToLocalChecked(); } @@ -6950,29 +7809,47 @@ static int p_getter_count; static int p_getter_count2; -static void PGetter(Local<String> name, +static void PGetter(Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); p_getter_count++; - v8::Handle<v8::Object> global = - info.GetIsolate()->GetCurrentContext()->Global(); - CHECK(info.Holder()->Equals(global->Get(v8_str("o1")))); - if (name->Equals(v8_str("p1"))) { - CHECK(info.This()->Equals(global->Get(v8_str("o1")))); - } else if (name->Equals(v8_str("p2"))) { - CHECK(info.This()->Equals(global->Get(v8_str("o2")))); - } else if (name->Equals(v8_str("p3"))) { - CHECK(info.This()->Equals(global->Get(v8_str("o3")))); - } else if (name->Equals(v8_str("p4"))) { - CHECK(info.This()->Equals(global->Get(v8_str("o4")))); + v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); + v8::Local<v8::Object> global = context->Global(); + CHECK( + info.Holder() + ->Equals(context, global->Get(context, v8_str("o1")).ToLocalChecked()) + .FromJust()); + if (name->Equals(context, v8_str("p1")).FromJust()) { + CHECK(info.This() + ->Equals(context, + global->Get(context, v8_str("o1")).ToLocalChecked()) + .FromJust()); + } else if (name->Equals(context, v8_str("p2")).FromJust()) { + CHECK(info.This() + ->Equals(context, + global->Get(context, v8_str("o2")).ToLocalChecked()) + .FromJust()); + } else if (name->Equals(context, v8_str("p3")).FromJust()) { + CHECK(info.This() + ->Equals(context, + global->Get(context, v8_str("o3")).ToLocalChecked()) + .FromJust()); + } else if (name->Equals(context, v8_str("p4")).FromJust()) { + CHECK(info.This() + ->Equals(context, + global->Get(context, v8_str("o4")).ToLocalChecked()) + .FromJust()); } } -static void RunHolderTest(v8::Handle<v8::ObjectTemplate> obj) { +static void RunHolderTest(v8::Local<v8::ObjectTemplate> obj) { ApiTestFuzzer::Fuzz(); LocalContext context; - context->Global()->Set(v8_str("o1"), obj->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o1"), + obj->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun( "o1.__proto__ = { };" "var o2 = { __proto__: o1 };" @@ -6989,17 +7866,32 @@ static void PGetter2(Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); p_getter_count2++; - v8::Handle<v8::Object> global = - info.GetIsolate()->GetCurrentContext()->Global(); - CHECK(info.Holder()->Equals(global->Get(v8_str("o1")))); - if (name->Equals(v8_str("p1"))) { - CHECK(info.This()->Equals(global->Get(v8_str("o1")))); - } else if (name->Equals(v8_str("p2"))) { - CHECK(info.This()->Equals(global->Get(v8_str("o2")))); - } else if (name->Equals(v8_str("p3"))) { - CHECK(info.This()->Equals(global->Get(v8_str("o3")))); - } else if (name->Equals(v8_str("p4"))) { - CHECK(info.This()->Equals(global->Get(v8_str("o4")))); + v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); + v8::Local<v8::Object> global = context->Global(); + CHECK( + info.Holder() + ->Equals(context, global->Get(context, v8_str("o1")).ToLocalChecked()) + .FromJust()); + if (name->Equals(context, v8_str("p1")).FromJust()) { + CHECK(info.This() + ->Equals(context, + global->Get(context, v8_str("o1")).ToLocalChecked()) + .FromJust()); + } else if (name->Equals(context, v8_str("p2")).FromJust()) { + CHECK(info.This() + ->Equals(context, + global->Get(context, v8_str("o2")).ToLocalChecked()) + .FromJust()); + } else if (name->Equals(context, v8_str("p3")).FromJust()) { + CHECK(info.This() + ->Equals(context, + global->Get(context, v8_str("o3")).ToLocalChecked()) + .FromJust()); + } else if (name->Equals(context, v8_str("p4")).FromJust()) { + CHECK(info.This() + ->Equals(context, + global->Get(context, v8_str("o4")).ToLocalChecked()) + .FromJust()); } } @@ -7007,7 +7899,7 @@ static void PGetter2(Local<Name> name, THREADED_TEST(GetterHolders) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("p1"), PGetter); obj->SetAccessor(v8_str("p2"), PGetter); obj->SetAccessor(v8_str("p3"), PGetter); @@ -7021,7 +7913,7 @@ THREADED_TEST(GetterHolders) { THREADED_TEST(PreInterceptorHolders) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetHandler(v8::NamedPropertyHandlerConfiguration(PGetter2)); p_getter_count2 = 0; RunHolderTest(obj); @@ -7032,19 +7924,26 @@ THREADED_TEST(PreInterceptorHolders) { THREADED_TEST(ObjectInstantiation) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("t"), PGetter2); LocalContext context; - context->Global()->Set(v8_str("o"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); for (int i = 0; i < 100; i++) { v8::HandleScope inner_scope(CcTest::isolate()); - v8::Handle<v8::Object> obj = templ->NewInstance(); - CHECK(!obj->Equals(context->Global()->Get(v8_str("o")))); - context->Global()->Set(v8_str("o2"), obj); - v8::Handle<Value> value = - CompileRun("o.__proto__ === o2.__proto__"); - CHECK(v8::True(isolate)->Equals(value)); - context->Global()->Set(v8_str("o"), obj); + v8::Local<v8::Object> obj = + templ->NewInstance(context.local()).ToLocalChecked(); + CHECK(!obj->Equals(context.local(), context->Global() + ->Get(context.local(), v8_str("o")) + .ToLocalChecked()) + .FromJust()); + CHECK( + context->Global()->Set(context.local(), v8_str("o2"), obj).FromJust()); + v8::Local<Value> value = CompileRun("o.__proto__ === o2.__proto__"); + CHECK(v8::True(isolate)->Equals(context.local(), value).FromJust()); + CHECK(context->Global()->Set(context.local(), v8_str("o"), obj).FromJust()); } } @@ -7070,7 +7969,7 @@ static int StrNCmp16(uint16_t* a, uint16_t* b, int n) { } -int GetUtf8Length(Handle<String> str) { +int GetUtf8Length(Local<String> str) { int len = str->Utf8Length(); if (len < 0) { i::Handle<i::String> istr(v8::Utils::OpenHandle(*str)); @@ -7084,27 +7983,37 @@ int GetUtf8Length(Handle<String> str) { THREADED_TEST(StringWrite) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::Handle<String> str = v8_str("abcde"); + v8::Local<String> str = v8_str("abcde"); // abc<Icelandic eth><Unicode snowman>. - v8::Handle<String> str2 = v8_str("abc\303\260\342\230\203"); - v8::Handle<String> str3 = v8::String::NewFromUtf8( - context->GetIsolate(), "abc\0def", v8::String::kNormalString, 7); + v8::Local<String> str2 = v8_str("abc\303\260\342\230\203"); + v8::Local<String> str3 = + v8::String::NewFromUtf8(context->GetIsolate(), "abc\0def", + v8::NewStringType::kNormal, 7) + .ToLocalChecked(); // "ab" + lead surrogate + "cd" + trail surrogate + "ef" uint16_t orphans[8] = { 0x61, 0x62, 0xd800, 0x63, 0x64, 0xdc00, 0x65, 0x66 }; - v8::Handle<String> orphans_str = v8::String::NewFromTwoByte( - context->GetIsolate(), orphans, v8::String::kNormalString, 8); + v8::Local<String> orphans_str = + v8::String::NewFromTwoByte(context->GetIsolate(), orphans, + v8::NewStringType::kNormal, 8) + .ToLocalChecked(); // single lead surrogate uint16_t lead[1] = { 0xd800 }; - v8::Handle<String> lead_str = v8::String::NewFromTwoByte( - context->GetIsolate(), lead, v8::String::kNormalString, 1); + v8::Local<String> lead_str = + v8::String::NewFromTwoByte(context->GetIsolate(), lead, + v8::NewStringType::kNormal, 1) + .ToLocalChecked(); // single trail surrogate uint16_t trail[1] = { 0xdc00 }; - v8::Handle<String> trail_str = v8::String::NewFromTwoByte( - context->GetIsolate(), trail, v8::String::kNormalString, 1); + v8::Local<String> trail_str = + v8::String::NewFromTwoByte(context->GetIsolate(), trail, + v8::NewStringType::kNormal, 1) + .ToLocalChecked(); // surrogate pair uint16_t pair[2] = { 0xd800, 0xdc00 }; - v8::Handle<String> pair_str = v8::String::NewFromTwoByte( - context->GetIsolate(), pair, v8::String::kNormalString, 2); + v8::Local<String> pair_str = + v8::String::NewFromTwoByte(context->GetIsolate(), pair, + v8::NewStringType::kNormal, 2) + .ToLocalChecked(); const int kStride = 4; // Must match stride in for loops in JS below. CompileRun( "var left = '';" @@ -7116,9 +8025,13 @@ THREADED_TEST(StringWrite) { "for (var i = 0; i < 0xd800; i += 4) {" " right = String.fromCharCode(i) + right;" "}"); - v8::Handle<v8::Object> global = context->Global(); - Handle<String> left_tree = global->Get(v8_str("left")).As<String>(); - Handle<String> right_tree = global->Get(v8_str("right")).As<String>(); + v8::Local<v8::Object> global = context->Global(); + Local<String> left_tree = global->Get(context.local(), v8_str("left")) + .ToLocalChecked() + .As<String>(); + Local<String> right_tree = global->Get(context.local(), v8_str("right")) + .ToLocalChecked() + .As<String>(); CHECK_EQ(5, str2->Length()); CHECK_EQ(0xd800 / kStride, left_tree->Length()); @@ -7394,15 +8307,17 @@ static void Utf16Helper( const char* name, const char* lengths_name, int len) { - Local<v8::Array> a = - Local<v8::Array>::Cast(context->Global()->Get(v8_str(name))); + Local<v8::Array> a = Local<v8::Array>::Cast( + context->Global()->Get(context.local(), v8_str(name)).ToLocalChecked()); Local<v8::Array> alens = - Local<v8::Array>::Cast(context->Global()->Get(v8_str(lengths_name))); + Local<v8::Array>::Cast(context->Global() + ->Get(context.local(), v8_str(lengths_name)) + .ToLocalChecked()); for (int i = 0; i < len; i++) { Local<v8::String> string = - Local<v8::String>::Cast(a->Get(i)); - Local<v8::Number> expected_len = - Local<v8::Number>::Cast(alens->Get(i)); + Local<v8::String>::Cast(a->Get(context.local(), i).ToLocalChecked()); + Local<v8::Number> expected_len = Local<v8::Number>::Cast( + alens->Get(context.local(), i).ToLocalChecked()); int length = GetUtf8Length(string); CHECK_EQ(static_cast<int>(expected_len->Value()), length); } @@ -7458,7 +8373,7 @@ THREADED_TEST(Utf16) { } -static bool SameSymbol(Handle<String> s1, Handle<String> s2) { +static bool SameSymbol(Local<String> s1, Local<String> s2) { i::Handle<i::String> is1(v8::Utils::OpenHandle(*s1)); i::Handle<i::String> is2(v8::Utils::OpenHandle(*s2)); return *is1 == *is2; @@ -7469,10 +8384,14 @@ THREADED_TEST(Utf16Symbol) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - Handle<String> symbol1 = v8::String::NewFromUtf8( - context->GetIsolate(), "abc", v8::String::kInternalizedString); - Handle<String> symbol2 = v8::String::NewFromUtf8( - context->GetIsolate(), "abc", v8::String::kInternalizedString); + Local<String> symbol1 = + v8::String::NewFromUtf8(context->GetIsolate(), "abc", + v8::NewStringType::kInternalized) + .ToLocalChecked(); + Local<String> symbol2 = + v8::String::NewFromUtf8(context->GetIsolate(), "abc", + v8::NewStringType::kInternalized) + .ToLocalChecked(); CHECK(SameSymbol(symbol1, symbol2)); CompileRun( @@ -7490,35 +8409,49 @@ THREADED_TEST(Utf16Symbol) { "if (sym3.charCodeAt(2) != 0xdc07) throw sym1.charCodeAt(2);" "if (sym4.length != 3) throw sym4;" "if (sym4.charCodeAt(2) != 0xdc08) throw sym2.charCodeAt(2);"); - Handle<String> sym0 = v8::String::NewFromUtf8( - context->GetIsolate(), "benedictus", v8::String::kInternalizedString); - Handle<String> sym0b = v8::String::NewFromUtf8( - context->GetIsolate(), "S\303\270ren", v8::String::kInternalizedString); - Handle<String> sym1 = + Local<String> sym0 = + v8::String::NewFromUtf8(context->GetIsolate(), "benedictus", + v8::NewStringType::kInternalized) + .ToLocalChecked(); + Local<String> sym0b = + v8::String::NewFromUtf8(context->GetIsolate(), "S\303\270ren", + v8::NewStringType::kInternalized) + .ToLocalChecked(); + Local<String> sym1 = v8::String::NewFromUtf8(context->GetIsolate(), "\355\240\201\355\260\207", - v8::String::kInternalizedString); - Handle<String> sym2 = + v8::NewStringType::kInternalized) + .ToLocalChecked(); + Local<String> sym2 = v8::String::NewFromUtf8(context->GetIsolate(), "\360\220\220\210", - v8::String::kInternalizedString); - Handle<String> sym3 = v8::String::NewFromUtf8( - context->GetIsolate(), "x\355\240\201\355\260\207", - v8::String::kInternalizedString); - Handle<String> sym4 = + v8::NewStringType::kInternalized) + .ToLocalChecked(); + Local<String> sym3 = v8::String::NewFromUtf8(context->GetIsolate(), + "x\355\240\201\355\260\207", + v8::NewStringType::kInternalized) + .ToLocalChecked(); + Local<String> sym4 = v8::String::NewFromUtf8(context->GetIsolate(), "x\360\220\220\210", - v8::String::kInternalizedString); + v8::NewStringType::kInternalized) + .ToLocalChecked(); v8::Local<v8::Object> global = context->Global(); - Local<Value> s0 = global->Get(v8_str("sym0")); - Local<Value> s0b = global->Get(v8_str("sym0b")); - Local<Value> s1 = global->Get(v8_str("sym1")); - Local<Value> s2 = global->Get(v8_str("sym2")); - Local<Value> s3 = global->Get(v8_str("sym3")); - Local<Value> s4 = global->Get(v8_str("sym4")); - CHECK(SameSymbol(sym0, Handle<String>::Cast(s0))); - CHECK(SameSymbol(sym0b, Handle<String>::Cast(s0b))); - CHECK(SameSymbol(sym1, Handle<String>::Cast(s1))); - CHECK(SameSymbol(sym2, Handle<String>::Cast(s2))); - CHECK(SameSymbol(sym3, Handle<String>::Cast(s3))); - CHECK(SameSymbol(sym4, Handle<String>::Cast(s4))); + Local<Value> s0 = + global->Get(context.local(), v8_str("sym0")).ToLocalChecked(); + Local<Value> s0b = + global->Get(context.local(), v8_str("sym0b")).ToLocalChecked(); + Local<Value> s1 = + global->Get(context.local(), v8_str("sym1")).ToLocalChecked(); + Local<Value> s2 = + global->Get(context.local(), v8_str("sym2")).ToLocalChecked(); + Local<Value> s3 = + global->Get(context.local(), v8_str("sym3")).ToLocalChecked(); + Local<Value> s4 = + global->Get(context.local(), v8_str("sym4")).ToLocalChecked(); + CHECK(SameSymbol(sym0, Local<String>::Cast(s0))); + CHECK(SameSymbol(sym0b, Local<String>::Cast(s0b))); + CHECK(SameSymbol(sym1, Local<String>::Cast(s1))); + CHECK(SameSymbol(sym2, Local<String>::Cast(s2))); + CHECK(SameSymbol(sym3, Local<String>::Cast(s3))); + CHECK(SameSymbol(sym4, Local<String>::Cast(s4))); } @@ -7578,29 +8511,32 @@ THREADED_TEST(ToArrayIndex) { v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<String> str = v8_str("42"); - v8::Handle<v8::Uint32> index = str->ToArrayIndex(); + v8::Local<String> str = v8_str("42"); + v8::MaybeLocal<v8::Uint32> index = str->ToArrayIndex(context.local()); CHECK(!index.IsEmpty()); - CHECK_EQ(42.0, index->Uint32Value()); + CHECK_EQ(42.0, + index.ToLocalChecked()->Uint32Value(context.local()).FromJust()); str = v8_str("42asdf"); - index = str->ToArrayIndex(); + index = str->ToArrayIndex(context.local()); CHECK(index.IsEmpty()); str = v8_str("-42"); - index = str->ToArrayIndex(); + index = str->ToArrayIndex(context.local()); CHECK(index.IsEmpty()); str = v8_str("4294967294"); - index = str->ToArrayIndex(); + index = str->ToArrayIndex(context.local()); CHECK(!index.IsEmpty()); - CHECK_EQ(4294967294.0, index->Uint32Value()); - v8::Handle<v8::Number> num = v8::Number::New(isolate, 1); - index = num->ToArrayIndex(); + CHECK_EQ(4294967294.0, + index.ToLocalChecked()->Uint32Value(context.local()).FromJust()); + v8::Local<v8::Number> num = v8::Number::New(isolate, 1); + index = num->ToArrayIndex(context.local()); CHECK(!index.IsEmpty()); - CHECK_EQ(1.0, index->Uint32Value()); + CHECK_EQ(1.0, + index.ToLocalChecked()->Uint32Value(context.local()).FromJust()); num = v8::Number::New(isolate, -1); - index = num->ToArrayIndex(); + index = num->ToArrayIndex(context.local()); CHECK(index.IsEmpty()); - v8::Handle<v8::Object> obj = v8::Object::New(isolate); - index = obj->ToArrayIndex(); + v8::Local<v8::Object> obj = v8::Object::New(isolate); + index = obj->ToArrayIndex(context.local()); CHECK(index.IsEmpty()); } @@ -7609,33 +8545,58 @@ THREADED_TEST(ErrorConstruction) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::Handle<String> foo = v8_str("foo"); - v8::Handle<String> message = v8_str("message"); - v8::Handle<Value> range_error = v8::Exception::RangeError(foo); + v8::Local<String> foo = v8_str("foo"); + v8::Local<String> message = v8_str("message"); + v8::Local<Value> range_error = v8::Exception::RangeError(foo); CHECK(range_error->IsObject()); - CHECK(range_error.As<v8::Object>()->Get(message)->Equals(foo)); - v8::Handle<Value> reference_error = v8::Exception::ReferenceError(foo); + CHECK(range_error.As<v8::Object>() + ->Get(context.local(), message) + .ToLocalChecked() + ->Equals(context.local(), foo) + .FromJust()); + v8::Local<Value> reference_error = v8::Exception::ReferenceError(foo); CHECK(reference_error->IsObject()); - CHECK(reference_error.As<v8::Object>()->Get(message)->Equals(foo)); - v8::Handle<Value> syntax_error = v8::Exception::SyntaxError(foo); + CHECK(reference_error.As<v8::Object>() + ->Get(context.local(), message) + .ToLocalChecked() + ->Equals(context.local(), foo) + .FromJust()); + v8::Local<Value> syntax_error = v8::Exception::SyntaxError(foo); CHECK(syntax_error->IsObject()); - CHECK(syntax_error.As<v8::Object>()->Get(message)->Equals(foo)); - v8::Handle<Value> type_error = v8::Exception::TypeError(foo); + CHECK(syntax_error.As<v8::Object>() + ->Get(context.local(), message) + .ToLocalChecked() + ->Equals(context.local(), foo) + .FromJust()); + v8::Local<Value> type_error = v8::Exception::TypeError(foo); CHECK(type_error->IsObject()); - CHECK(type_error.As<v8::Object>()->Get(message)->Equals(foo)); - v8::Handle<Value> error = v8::Exception::Error(foo); + CHECK(type_error.As<v8::Object>() + ->Get(context.local(), message) + .ToLocalChecked() + ->Equals(context.local(), foo) + .FromJust()); + v8::Local<Value> error = v8::Exception::Error(foo); CHECK(error->IsObject()); - CHECK(error.As<v8::Object>()->Get(message)->Equals(foo)); + CHECK(error.As<v8::Object>() + ->Get(context.local(), message) + .ToLocalChecked() + ->Equals(context.local(), foo) + .FromJust()); } static void ThrowV8Exception(const v8::FunctionCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - v8::Handle<String> foo = v8_str("foo"); - v8::Handle<String> message = v8_str("message"); - v8::Handle<Value> error = v8::Exception::Error(foo); + v8::Local<String> foo = v8_str("foo"); + v8::Local<String> message = v8_str("message"); + v8::Local<Value> error = v8::Exception::Error(foo); CHECK(error->IsObject()); - CHECK(error.As<v8::Object>()->Get(message)->Equals(foo)); + v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); + CHECK(error.As<v8::Object>() + ->Get(context, message) + .ToLocalChecked() + ->Equals(context, foo) + .FromJust()); info.GetIsolate()->ThrowException(error); info.GetReturnValue().SetUndefined(); } @@ -7644,15 +8605,17 @@ static void ThrowV8Exception(const v8::FunctionCallbackInfo<v8::Value>& info) { THREADED_TEST(ExceptionCreateMessage) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::Handle<String> foo_str = v8_str("foo"); - v8::Handle<String> message_str = v8_str("message"); + v8::Local<String> foo_str = v8_str("foo"); + v8::Local<String> message_str = v8_str("message"); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); + context->GetIsolate()->SetCaptureStackTraceForUncaughtExceptions(true); Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(context->GetIsolate(), ThrowV8Exception); v8::Local<v8::Object> global = context->Global(); - global->Set(v8_str("throwV8Exception"), fun->GetFunction()); + CHECK(global->Set(context.local(), v8_str("throwV8Exception"), + fun->GetFunction(context.local()).ToLocalChecked()) + .FromJust()); TryCatch try_catch(context->GetIsolate()); CompileRun( @@ -7662,16 +8625,21 @@ THREADED_TEST(ExceptionCreateMessage) { "f1();"); CHECK(try_catch.HasCaught()); - v8::Handle<v8::Value> error = try_catch.Exception(); + v8::Local<v8::Value> error = try_catch.Exception(); CHECK(error->IsObject()); - CHECK(error.As<v8::Object>()->Get(message_str)->Equals(foo_str)); + CHECK(error.As<v8::Object>() + ->Get(context.local(), message_str) + .ToLocalChecked() + ->Equals(context.local(), foo_str) + .FromJust()); - v8::Handle<v8::Message> message = v8::Exception::CreateMessage(error); + v8::Local<v8::Message> message = + v8::Exception::CreateMessage(context->GetIsolate(), error); CHECK(!message.IsEmpty()); - CHECK_EQ(2, message->GetLineNumber()); - CHECK_EQ(2, message->GetStartColumn()); + CHECK_EQ(2, message->GetLineNumber(context.local()).FromJust()); + CHECK_EQ(2, message->GetStartColumn(context.local()).FromJust()); - v8::Handle<v8::StackTrace> stackTrace = message->GetStackTrace(); + v8::Local<v8::StackTrace> stackTrace = message->GetStackTrace(); CHECK(!stackTrace.IsEmpty()); CHECK_EQ(2, stackTrace->GetFrameCount()); @@ -7679,7 +8647,7 @@ THREADED_TEST(ExceptionCreateMessage) { CHECK(!stackTrace.IsEmpty()); CHECK_EQ(2, stackTrace->GetFrameCount()); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(false); + context->GetIsolate()->SetCaptureStackTraceForUncaughtExceptions(false); // Now check message location when SetCaptureStackTraceForUncaughtExceptions // is false. @@ -7694,12 +8662,16 @@ THREADED_TEST(ExceptionCreateMessage) { error = try_catch.Exception(); CHECK(error->IsObject()); - CHECK(error.As<v8::Object>()->Get(message_str)->Equals(foo_str)); + CHECK(error.As<v8::Object>() + ->Get(context.local(), message_str) + .ToLocalChecked() + ->Equals(context.local(), foo_str) + .FromJust()); - message = v8::Exception::CreateMessage(error); + message = v8::Exception::CreateMessage(context->GetIsolate(), error); CHECK(!message.IsEmpty()); - CHECK_EQ(2, message->GetLineNumber()); - CHECK_EQ(9, message->GetStartColumn()); + CHECK_EQ(2, message->GetLineNumber(context.local()).FromJust()); + CHECK_EQ(9, message->GetStartColumn(context.local()).FromJust()); // Should be empty stack trace. stackTrace = message->GetStackTrace(); @@ -7735,48 +8707,27 @@ static void YSetter(Local<String> name, Local<Value> value, const v8::PropertyCallbackInfo<void>& info) { Local<Object> this_obj = Local<Object>::Cast(info.This()); - if (this_obj->Has(name)) this_obj->Delete(name); - this_obj->Set(name, value); + v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); + if (this_obj->Has(context, name).FromJust()) + this_obj->Delete(context, name).FromJust(); + CHECK(this_obj->Set(context, name, value).FromJust()); } THREADED_TEST(DeleteAccessor) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("y"), YGetter, YSetter); LocalContext context; - v8::Handle<v8::Object> holder = obj->NewInstance(); - context->Global()->Set(v8_str("holder"), holder); - v8::Handle<Value> result = CompileRun( - "holder.y = 11; holder.y = 12; holder.y"); - CHECK_EQ(12u, result->Uint32Value()); -} - - -THREADED_TEST(TypeSwitch) { - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> templ1 = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> templ2 = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> templ3 = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> templs[3] = { templ1, templ2, templ3 }; - v8::Handle<v8::TypeSwitch> type_switch = v8::TypeSwitch::New(3, templs); - LocalContext context; - v8::Handle<v8::Object> obj0 = v8::Object::New(isolate); - v8::Handle<v8::Object> obj1 = templ1->GetFunction()->NewInstance(); - v8::Handle<v8::Object> obj2 = templ2->GetFunction()->NewInstance(); - v8::Handle<v8::Object> obj3 = templ3->GetFunction()->NewInstance(); - for (int i = 0; i < 10; i++) { - CHECK_EQ(0, type_switch->match(obj0)); - CHECK_EQ(1, type_switch->match(obj1)); - CHECK_EQ(2, type_switch->match(obj2)); - CHECK_EQ(3, type_switch->match(obj3)); - CHECK_EQ(3, type_switch->match(obj3)); - CHECK_EQ(2, type_switch->match(obj2)); - CHECK_EQ(1, type_switch->match(obj1)); - CHECK_EQ(0, type_switch->match(obj0)); - } + v8::Local<v8::Object> holder = + obj->NewInstance(context.local()).ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("holder"), holder) + .FromJust()); + v8::Local<Value> result = + CompileRun("holder.y = 11; holder.y = 12; holder.y"); + CHECK_EQ(12u, result->Uint32Value(context.local()).FromJust()); } @@ -7786,20 +8737,22 @@ static void TroubleCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { trouble_nesting++; // Call a JS function that throws an uncaught exception. - Local<v8::Object> arg_this = - args.GetIsolate()->GetCurrentContext()->Global(); - Local<Value> trouble_callee = (trouble_nesting == 3) ? - arg_this->Get(v8_str("trouble_callee")) : - arg_this->Get(v8_str("trouble_caller")); + Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); + Local<v8::Object> arg_this = context->Global(); + Local<Value> trouble_callee = + (trouble_nesting == 3) + ? arg_this->Get(context, v8_str("trouble_callee")).ToLocalChecked() + : arg_this->Get(context, v8_str("trouble_caller")).ToLocalChecked(); CHECK(trouble_callee->IsFunction()); - args.GetReturnValue().Set( - Function::Cast(*trouble_callee)->Call(arg_this, 0, NULL)); + args.GetReturnValue().Set(Function::Cast(*trouble_callee) + ->Call(context, arg_this, 0, NULL) + .FromMaybe(v8::Local<v8::Value>())); } static int report_count = 0; -static void ApiUncaughtExceptionTestListener(v8::Handle<v8::Message>, - v8::Handle<Value>) { +static void ApiUncaughtExceptionTestListener(v8::Local<v8::Message>, + v8::Local<Value>) { report_count++; } @@ -7811,12 +8764,14 @@ TEST(ApiUncaughtException) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::V8::AddMessageListener(ApiUncaughtExceptionTestListener); + isolate->AddMessageListener(ApiUncaughtExceptionTestListener); Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate, TroubleCallback); v8::Local<v8::Object> global = env->Global(); - global->Set(v8_str("trouble"), fun->GetFunction()); + CHECK(global->Set(env.local(), v8_str("trouble"), + fun->GetFunction(env.local()).ToLocalChecked()) + .FromJust()); CompileRun( "function trouble_callee() {" @@ -7826,25 +8781,31 @@ TEST(ApiUncaughtException) { "function trouble_caller() {" " trouble();" "};"); - Local<Value> trouble = global->Get(v8_str("trouble")); + Local<Value> trouble = + global->Get(env.local(), v8_str("trouble")).ToLocalChecked(); CHECK(trouble->IsFunction()); - Local<Value> trouble_callee = global->Get(v8_str("trouble_callee")); + Local<Value> trouble_callee = + global->Get(env.local(), v8_str("trouble_callee")).ToLocalChecked(); CHECK(trouble_callee->IsFunction()); - Local<Value> trouble_caller = global->Get(v8_str("trouble_caller")); + Local<Value> trouble_caller = + global->Get(env.local(), v8_str("trouble_caller")).ToLocalChecked(); CHECK(trouble_caller->IsFunction()); - Function::Cast(*trouble_caller)->Call(global, 0, NULL); + Function::Cast(*trouble_caller) + ->Call(env.local(), global, 0, NULL) + .FromMaybe(v8::Local<v8::Value>()); CHECK_EQ(1, report_count); - v8::V8::RemoveMessageListeners(ApiUncaughtExceptionTestListener); + isolate->RemoveMessageListeners(ApiUncaughtExceptionTestListener); } TEST(ApiUncaughtExceptionInObjectObserve) { + v8::internal::FLAG_harmony_object_observe = true; v8::internal::FLAG_stack_size = 150; report_count = 0; LocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::V8::AddMessageListener(ApiUncaughtExceptionTestListener); + isolate->AddMessageListener(ApiUncaughtExceptionTestListener); CompileRun( "var obj = {};" "var observe_count = 0;" @@ -7860,19 +8821,22 @@ TEST(ApiUncaughtExceptionInObjectObserve) { "obj.foo = 'bar';"); CHECK_EQ(3, report_count); ExpectInt32("observe_count", 2); - v8::V8::RemoveMessageListeners(ApiUncaughtExceptionTestListener); + isolate->RemoveMessageListeners(ApiUncaughtExceptionTestListener); } static const char* script_resource_name = "ExceptionInNativeScript.js"; -static void ExceptionInNativeScriptTestListener(v8::Handle<v8::Message> message, - v8::Handle<Value>) { - v8::Handle<v8::Value> name_val = message->GetScriptOrigin().ResourceName(); +static void ExceptionInNativeScriptTestListener(v8::Local<v8::Message> message, + v8::Local<Value>) { + v8::Local<v8::Value> name_val = message->GetScriptOrigin().ResourceName(); CHECK(!name_val.IsEmpty() && name_val->IsString()); v8::String::Utf8Value name(message->GetScriptOrigin().ResourceName()); CHECK_EQ(0, strcmp(script_resource_name, *name)); - CHECK_EQ(3, message->GetLineNumber()); - v8::String::Utf8Value source_line(message->GetSourceLine()); + v8::Local<v8::Context> context = + v8::Isolate::GetCurrent()->GetCurrentContext(); + CHECK_EQ(3, message->GetLineNumber(context).FromJust()); + v8::String::Utf8Value source_line( + message->GetSourceLine(context).ToLocalChecked()); CHECK_EQ(0, strcmp(" new o.foo();", *source_line)); } @@ -7881,12 +8845,14 @@ TEST(ExceptionInNativeScript) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::V8::AddMessageListener(ExceptionInNativeScriptTestListener); + isolate->AddMessageListener(ExceptionInNativeScriptTestListener); Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate, TroubleCallback); v8::Local<v8::Object> global = env->Global(); - global->Set(v8_str("trouble"), fun->GetFunction()); + CHECK(global->Set(env.local(), v8_str("trouble"), + fun->GetFunction(env.local()).ToLocalChecked()) + .FromJust()); CompileRunWithOrigin( "function trouble() {\n" @@ -7894,10 +8860,11 @@ TEST(ExceptionInNativeScript) { " new o.foo();\n" "};", script_resource_name); - Local<Value> trouble = global->Get(v8_str("trouble")); + Local<Value> trouble = + global->Get(env.local(), v8_str("trouble")).ToLocalChecked(); CHECK(trouble->IsFunction()); - Function::Cast(*trouble)->Call(global, 0, NULL); - v8::V8::RemoveMessageListeners(ExceptionInNativeScriptTestListener); + CHECK(Function::Cast(*trouble)->Call(env.local(), global, 0, NULL).IsEmpty()); + isolate->RemoveMessageListeners(ExceptionInNativeScriptTestListener); } @@ -7935,7 +8902,9 @@ TEST(TryCatchFinallyUsingTryCatchHandler) { void CEvaluate(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::HandleScope scope(args.GetIsolate()); - CompileRun(args[0]->ToString(args.GetIsolate())); + CompileRun(args[0] + ->ToString(args.GetIsolate()->GetCurrentContext()) + .ToLocalChecked()); } @@ -7981,56 +8950,60 @@ static bool SecurityTestCallback(Local<v8::Context> accessing_context, TEST(SecurityHandler) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope0(isolate); - v8::Handle<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallback(SecurityTestCallback); // Create an environment - v8::Handle<Context> context0 = Context::New(isolate, NULL, global_template); + v8::Local<Context> context0 = Context::New(isolate, NULL, global_template); context0->Enter(); - v8::Handle<v8::Object> global0 = context0->Global(); - v8::Handle<Script> script0 = v8_compile("foo = 111"); - script0->Run(); - global0->Set(v8_str("0"), v8_num(999)); - v8::Handle<Value> foo0 = global0->Get(v8_str("foo")); - CHECK_EQ(111, foo0->Int32Value()); - v8::Handle<Value> z0 = global0->Get(v8_str("0")); - CHECK_EQ(999, z0->Int32Value()); + v8::Local<v8::Object> global0 = context0->Global(); + v8::Local<Script> script0 = v8_compile("foo = 111"); + script0->Run(context0).ToLocalChecked(); + CHECK(global0->Set(context0, v8_str("0"), v8_num(999)).FromJust()); + v8::Local<Value> foo0 = + global0->Get(context0, v8_str("foo")).ToLocalChecked(); + CHECK_EQ(111, foo0->Int32Value(context0).FromJust()); + v8::Local<Value> z0 = global0->Get(context0, v8_str("0")).ToLocalChecked(); + CHECK_EQ(999, z0->Int32Value(context0).FromJust()); // Create another environment, should fail security checks. v8::HandleScope scope1(isolate); - v8::Handle<Context> context1 = - Context::New(isolate, NULL, global_template); + v8::Local<Context> context1 = Context::New(isolate, NULL, global_template); context1->Enter(); - v8::Handle<v8::Object> global1 = context1->Global(); - global1->Set(v8_str("othercontext"), global0); + v8::Local<v8::Object> global1 = context1->Global(); + global1->Set(context1, v8_str("othercontext"), global0).FromJust(); // This set will fail the security check. - v8::Handle<Script> script1 = - v8_compile("othercontext.foo = 222; othercontext[0] = 888;"); - script1->Run(); + v8::Local<Script> script1 = + v8_compile("othercontext.foo = 222; othercontext[0] = 888;"); + CHECK(script1->Run(context1).IsEmpty()); g_security_callback_result = true; // This read will pass the security check. - v8::Handle<Value> foo1 = global0->Get(v8_str("foo")); - CHECK_EQ(111, foo1->Int32Value()); + v8::Local<Value> foo1 = + global0->Get(context1, v8_str("foo")).ToLocalChecked(); + CHECK_EQ(111, foo1->Int32Value(context0).FromJust()); // This read will pass the security check. - v8::Handle<Value> z1 = global0->Get(v8_str("0")); - CHECK_EQ(999, z1->Int32Value()); + v8::Local<Value> z1 = global0->Get(context1, v8_str("0")).ToLocalChecked(); + CHECK_EQ(999, z1->Int32Value(context1).FromJust()); // Create another environment, should pass security checks. { v8::HandleScope scope2(isolate); LocalContext context2; - v8::Handle<v8::Object> global2 = context2->Global(); - global2->Set(v8_str("othercontext"), global0); - v8::Handle<Script> script2 = + v8::Local<v8::Object> global2 = context2->Global(); + CHECK(global2->Set(context2.local(), v8_str("othercontext"), global0) + .FromJust()); + v8::Local<Script> script2 = v8_compile("othercontext.foo = 333; othercontext[0] = 888;"); - script2->Run(); - v8::Handle<Value> foo2 = global0->Get(v8_str("foo")); - CHECK_EQ(333, foo2->Int32Value()); - v8::Handle<Value> z2 = global0->Get(v8_str("0")); - CHECK_EQ(888, z2->Int32Value()); + script2->Run(context2.local()).ToLocalChecked(); + v8::Local<Value> foo2 = + global0->Get(context2.local(), v8_str("foo")).ToLocalChecked(); + CHECK_EQ(333, foo2->Int32Value(context2.local()).FromJust()); + v8::Local<Value> z2 = + global0->Get(context2.local(), v8_str("0")).ToLocalChecked(); + CHECK_EQ(888, z2->Int32Value(context2.local()).FromJust()); } context1->Exit(); @@ -8041,7 +9014,7 @@ TEST(SecurityHandler) { THREADED_TEST(SecurityChecks) { LocalContext env1; v8::HandleScope handle_scope(env1->GetIsolate()); - v8::Handle<Context> env2 = Context::New(env1->GetIsolate()); + v8::Local<Context> env2 = Context::New(env1->GetIsolate()); Local<Value> foo = v8_str("foo"); Local<Value> bar = v8_str("bar"); @@ -8051,12 +9024,14 @@ THREADED_TEST(SecurityChecks) { // Create a function in env1. CompileRun("spy=function(){return spy;}"); - Local<Value> spy = env1->Global()->Get(v8_str("spy")); + Local<Value> spy = + env1->Global()->Get(env1.local(), v8_str("spy")).ToLocalChecked(); CHECK(spy->IsFunction()); // Create another function accessing global objects. CompileRun("spy2=function(){return new this.Array();}"); - Local<Value> spy2 = env1->Global()->Get(v8_str("spy2")); + Local<Value> spy2 = + env1->Global()->Get(env1.local(), v8_str("spy2")).ToLocalChecked(); CHECK(spy2->IsFunction()); // Switch to env2 in the same domain and invoke spy on env2. @@ -8064,7 +9039,9 @@ THREADED_TEST(SecurityChecks) { env2->SetSecurityToken(foo); // Enter env2 Context::Scope scope_env2(env2); - Local<Value> result = Function::Cast(*spy)->Call(env2->Global(), 0, NULL); + Local<Value> result = Function::Cast(*spy) + ->Call(env2, env2->Global(), 0, NULL) + .ToLocalChecked(); CHECK(result->IsFunction()); } @@ -8074,7 +9051,7 @@ THREADED_TEST(SecurityChecks) { // Call cross_domain_call, it should throw an exception v8::TryCatch try_catch(env1->GetIsolate()); - Function::Cast(*spy2)->Call(env2->Global(), 0, NULL); + CHECK(Function::Cast(*spy2)->Call(env2, env2->Global(), 0, NULL).IsEmpty()); CHECK(try_catch.HasCaught()); } } @@ -8084,18 +9061,25 @@ THREADED_TEST(SecurityChecks) { THREADED_TEST(SecurityChecksForPrototypeChain) { LocalContext current; v8::HandleScope scope(current->GetIsolate()); - v8::Handle<Context> other = Context::New(current->GetIsolate()); + v8::Local<Context> other = Context::New(current->GetIsolate()); // Change context to be able to get to the Object function in the // other context without hitting the security checks. v8::Local<Value> other_object; { Context::Scope scope(other); - other_object = other->Global()->Get(v8_str("Object")); - other->Global()->Set(v8_num(42), v8_num(87)); + other_object = + other->Global()->Get(other, v8_str("Object")).ToLocalChecked(); + CHECK(other->Global()->Set(other, v8_num(42), v8_num(87)).FromJust()); } - current->Global()->Set(v8_str("other"), other->Global()); - CHECK(v8_compile("other")->Run()->Equals(other->Global())); + CHECK(current->Global() + ->Set(current.local(), v8_str("other"), other->Global()) + .FromJust()); + CHECK(v8_compile("other") + ->Run(current.local()) + .ToLocalChecked() + ->Equals(current.local(), other->Global()) + .FromJust()); // Make sure the security check fails here and we get an undefined // result instead of getting the Object function. Repeat in a loop @@ -8103,41 +9087,50 @@ THREADED_TEST(SecurityChecksForPrototypeChain) { v8::Local<Script> access_other0 = v8_compile("other.Object"); v8::Local<Script> access_other1 = v8_compile("other[42]"); for (int i = 0; i < 5; i++) { - CHECK(access_other0->Run().IsEmpty()); - CHECK(access_other1->Run().IsEmpty()); + CHECK(access_other0->Run(current.local()).IsEmpty()); + CHECK(access_other1->Run(current.local()).IsEmpty()); } // Create an object that has 'other' in its prototype chain and make // sure we cannot access the Object function indirectly through // that. Repeat in a loop to make sure to exercise the IC code. - v8_compile("function F() { };" - "F.prototype = other;" - "var f = new F();")->Run(); + v8_compile( + "function F() { };" + "F.prototype = other;" + "var f = new F();") + ->Run(current.local()) + .ToLocalChecked(); v8::Local<Script> access_f0 = v8_compile("f.Object"); v8::Local<Script> access_f1 = v8_compile("f[42]"); for (int j = 0; j < 5; j++) { - CHECK(access_f0->Run().IsEmpty()); - CHECK(access_f1->Run().IsEmpty()); + CHECK(access_f0->Run(current.local()).IsEmpty()); + CHECK(access_f1->Run(current.local()).IsEmpty()); } // Now it gets hairy: Set the prototype for the other global object // to be the current global object. The prototype chain for 'f' now // goes through 'other' but ends up in the current global object. { Context::Scope scope(other); - other->Global()->Set(v8_str("__proto__"), current->Global()); + CHECK(other->Global() + ->Set(other, v8_str("__proto__"), current->Global()) + .FromJust()); } // Set a named and an index property on the current global // object. To force the lookup to go through the other global object, // the properties must not exist in the other global object. - current->Global()->Set(v8_str("foo"), v8_num(100)); - current->Global()->Set(v8_num(99), v8_num(101)); + CHECK(current->Global() + ->Set(current.local(), v8_str("foo"), v8_num(100)) + .FromJust()); + CHECK(current->Global() + ->Set(current.local(), v8_num(99), v8_num(101)) + .FromJust()); // Try to read the properties from f and make sure that the access // gets stopped by the security checks on the other global object. Local<Script> access_f2 = v8_compile("f.foo"); Local<Script> access_f3 = v8_compile("f[99]"); for (int k = 0; k < 5; k++) { - CHECK(access_f2->Run().IsEmpty()); - CHECK(access_f3->Run().IsEmpty()); + CHECK(access_f2->Run(current.local()).IsEmpty()); + CHECK(access_f3->Run(current.local()).IsEmpty()); } } @@ -8155,21 +9148,28 @@ static bool SecurityTestCallbackWithGC(Local<v8::Context> accessing_context, TEST(SecurityTestGCAllowed) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> object_template = + v8::Local<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(isolate); object_template->SetAccessCheckCallback(SecurityTestCallbackWithGC); - v8::Handle<Context> context = Context::New(isolate); + v8::Local<Context> context = Context::New(isolate); v8::Context::Scope context_scope(context); - context->Global()->Set(v8_str("obj"), object_template->NewInstance()); + CHECK(context->Global() + ->Set(context, v8_str("obj"), + object_template->NewInstance(context).ToLocalChecked()) + .FromJust()); security_check_with_gc_called = false; CompileRun("obj[0] = new String(1002);"); CHECK(security_check_with_gc_called); security_check_with_gc_called = false; - CHECK(CompileRun("obj[0]")->ToString(isolate)->Equals(v8_str("1002"))); + CHECK(CompileRun("obj[0]") + ->ToString(context) + .ToLocalChecked() + ->Equals(context, v8_str("1002")) + .FromJust()); CHECK(security_check_with_gc_called); } @@ -8177,7 +9177,7 @@ TEST(SecurityTestGCAllowed) { THREADED_TEST(CrossDomainDelete) { LocalContext env1; v8::HandleScope handle_scope(env1->GetIsolate()); - v8::Handle<Context> env2 = Context::New(env1->GetIsolate()); + v8::Local<Context> env2 = Context::New(env1->GetIsolate()); Local<Value> foo = v8_str("foo"); Local<Value> bar = v8_str("bar"); @@ -8186,8 +9186,9 @@ THREADED_TEST(CrossDomainDelete) { env1->SetSecurityToken(foo); env2->SetSecurityToken(foo); - env1->Global()->Set(v8_str("prop"), v8_num(3)); - env2->Global()->Set(v8_str("env1"), env1->Global()); + CHECK( + env1->Global()->Set(env1.local(), v8_str("prop"), v8_num(3)).FromJust()); + CHECK(env2->Global()->Set(env2, v8_str("env1"), env1->Global()).FromJust()); // Change env2 to a different domain and delete env1.prop. env2->SetSecurityToken(bar); @@ -8199,16 +9200,17 @@ THREADED_TEST(CrossDomainDelete) { } // Check that env1.prop still exists. - Local<Value> v = env1->Global()->Get(v8_str("prop")); + Local<Value> v = + env1->Global()->Get(env1.local(), v8_str("prop")).ToLocalChecked(); CHECK(v->IsNumber()); - CHECK_EQ(3, v->Int32Value()); + CHECK_EQ(3, v->Int32Value(env1.local()).FromJust()); } -THREADED_TEST(CrossDomainIsPropertyEnumerable) { +THREADED_TEST(CrossDomainPropertyIsEnumerable) { LocalContext env1; v8::HandleScope handle_scope(env1->GetIsolate()); - v8::Handle<Context> env2 = Context::New(env1->GetIsolate()); + v8::Local<Context> env2 = Context::New(env1->GetIsolate()); Local<Value> foo = v8_str("foo"); Local<Value> bar = v8_str("bar"); @@ -8217,8 +9219,9 @@ THREADED_TEST(CrossDomainIsPropertyEnumerable) { env1->SetSecurityToken(foo); env2->SetSecurityToken(foo); - env1->Global()->Set(v8_str("prop"), v8_num(3)); - env2->Global()->Set(v8_str("env1"), env1->Global()); + CHECK( + env1->Global()->Set(env1.local(), v8_str("prop"), v8_num(3)).FromJust()); + CHECK(env2->Global()->Set(env2, v8_str("env1"), env1->Global()).FromJust()); // env1.prop is enumerable in env2. Local<String> test = v8_str("propertyIsEnumerable.call(env1, 'prop')"); @@ -8241,7 +9244,7 @@ THREADED_TEST(CrossDomainIsPropertyEnumerable) { THREADED_TEST(CrossDomainFor) { LocalContext env1; v8::HandleScope handle_scope(env1->GetIsolate()); - v8::Handle<Context> env2 = Context::New(env1->GetIsolate()); + v8::Local<Context> env2 = Context::New(env1->GetIsolate()); Local<Value> foo = v8_str("foo"); Local<Value> bar = v8_str("bar"); @@ -8250,13 +9253,14 @@ THREADED_TEST(CrossDomainFor) { env1->SetSecurityToken(foo); env2->SetSecurityToken(foo); - env1->Global()->Set(v8_str("prop"), v8_num(3)); - env2->Global()->Set(v8_str("env1"), env1->Global()); + CHECK( + env1->Global()->Set(env1.local(), v8_str("prop"), v8_num(3)).FromJust()); + CHECK(env2->Global()->Set(env2, v8_str("env1"), env1->Global()).FromJust()); // 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. + // object. It shouldn't throw either, just silently ignore them. env2->SetSecurityToken(bar); { Context::Scope scope_env2(env2); @@ -8279,7 +9283,7 @@ THREADED_TEST(CrossDomainFor) { THREADED_TEST(CrossDomainForInOnPrototype) { LocalContext env1; v8::HandleScope handle_scope(env1->GetIsolate()); - v8::Handle<Context> env2 = Context::New(env1->GetIsolate()); + v8::Local<Context> env2 = Context::New(env1->GetIsolate()); Local<Value> foo = v8_str("foo"); Local<Value> bar = v8_str("bar"); @@ -8288,8 +9292,9 @@ THREADED_TEST(CrossDomainForInOnPrototype) { env1->SetSecurityToken(foo); env2->SetSecurityToken(foo); - env1->Global()->Set(v8_str("prop"), v8_num(3)); - env2->Global()->Set(v8_str("env1"), env1->Global()); + CHECK( + env1->Global()->Set(env1.local(), v8_str("prop"), v8_num(3)).FromJust()); + CHECK(env2->Global()->Set(env2, v8_str("env1"), env1->Global()).FromJust()); // Change env2 to a different domain and set env1's global object // as the __proto__ of an object in env2 and enumerate properties @@ -8305,9 +9310,9 @@ THREADED_TEST(CrossDomainForInOnPrototype) { " for (var p in obj) {" " if (p == 'prop') return false;" " }" - " return false;" - " } catch (e) {" " return true;" + " } catch (e) {" + " return false;" " }" "})()"); CHECK(result->IsTrue()); @@ -8318,9 +9323,8 @@ THREADED_TEST(CrossDomainForInOnPrototype) { TEST(ContextDetachGlobal) { LocalContext env1; v8::HandleScope handle_scope(env1->GetIsolate()); - v8::Handle<Context> env2 = Context::New(env1->GetIsolate()); + v8::Local<Context> env2 = Context::New(env1->GetIsolate()); - Local<v8::Object> global1 = env1->Global(); Local<Value> foo = v8_str("foo"); @@ -8333,44 +9337,54 @@ TEST(ContextDetachGlobal) { // Create a function in env2 and add a reference to it in env1. Local<v8::Object> global2 = env2->Global(); - global2->Set(v8_str("prop"), v8::Integer::New(env2->GetIsolate(), 1)); + CHECK(global2->Set(env2, v8_str("prop"), + v8::Integer::New(env2->GetIsolate(), 1)) + .FromJust()); CompileRun("function getProp() {return prop;}"); - env1->Global()->Set(v8_str("getProp"), - global2->Get(v8_str("getProp"))); + CHECK(env1->Global() + ->Set(env1.local(), v8_str("getProp"), + global2->Get(env2, v8_str("getProp")).ToLocalChecked()) + .FromJust()); // Detach env2's global, and reuse the global object of env2 env2->Exit(); env2->DetachGlobal(); - v8::Handle<Context> env3 = Context::New(env1->GetIsolate(), - 0, - v8::Handle<v8::ObjectTemplate>(), - global2); + v8::Local<Context> env3 = Context::New( + env1->GetIsolate(), 0, v8::Local<v8::ObjectTemplate>(), global2); env3->SetSecurityToken(v8_str("bar")); - env3->Enter(); + env3->Enter(); Local<v8::Object> global3 = env3->Global(); - CHECK(global2->Equals(global3)); - CHECK(global3->Get(v8_str("prop"))->IsUndefined()); - CHECK(global3->Get(v8_str("getProp"))->IsUndefined()); - global3->Set(v8_str("prop"), v8::Integer::New(env3->GetIsolate(), -1)); - global3->Set(v8_str("prop2"), v8::Integer::New(env3->GetIsolate(), 2)); + CHECK(global2->Equals(env3, global3).FromJust()); + CHECK(global3->Get(env3, v8_str("prop")).ToLocalChecked()->IsUndefined()); + CHECK(global3->Get(env3, v8_str("getProp")).ToLocalChecked()->IsUndefined()); + CHECK(global3->Set(env3, v8_str("prop"), + v8::Integer::New(env3->GetIsolate(), -1)) + .FromJust()); + CHECK(global3->Set(env3, v8_str("prop2"), + v8::Integer::New(env3->GetIsolate(), 2)) + .FromJust()); env3->Exit(); // Call getProp in env1, and it should return the value 1 { - Local<Value> get_prop = global1->Get(v8_str("getProp")); + Local<v8::Object> global1 = env1->Global(); + Local<Value> get_prop = + global1->Get(env1.local(), v8_str("getProp")).ToLocalChecked(); CHECK(get_prop->IsFunction()); v8::TryCatch try_catch(env1->GetIsolate()); - Local<Value> r = Function::Cast(*get_prop)->Call(global1, 0, NULL); + Local<Value> r = Function::Cast(*get_prop) + ->Call(env1.local(), global1, 0, NULL) + .ToLocalChecked(); CHECK(!try_catch.HasCaught()); - CHECK_EQ(1, r->Int32Value()); + CHECK_EQ(1, r->Int32Value(env1.local()).FromJust()); } // Check that env3 is not accessible from env1 { - Local<Value> r = global3->Get(v8_str("prop2")); + v8::MaybeLocal<Value> r = global3->Get(env1.local(), v8_str("prop2")); CHECK(r.IsEmpty()); } } @@ -8381,7 +9395,7 @@ TEST(DetachGlobal) { v8::HandleScope scope(env1->GetIsolate()); // Create second environment. - v8::Handle<Context> env2 = Context::New(env1->GetIsolate()); + v8::Local<Context> env2 = Context::New(env1->GetIsolate()); Local<Value> foo = v8_str("foo"); @@ -8392,16 +9406,20 @@ TEST(DetachGlobal) { // Create a property on the global object in env2. { v8::Context::Scope scope(env2); - env2->Global()->Set(v8_str("p"), v8::Integer::New(env2->GetIsolate(), 42)); + CHECK(env2->Global() + ->Set(env2, v8_str("p"), v8::Integer::New(env2->GetIsolate(), 42)) + .FromJust()); } // Create a reference to env2 global from env1 global. - env1->Global()->Set(v8_str("other"), env2->Global()); + CHECK(env1->Global() + ->Set(env1.local(), v8_str("other"), env2->Global()) + .FromJust()); // Check that we have access to other.p in env2 from env1. Local<Value> result = CompileRun("other.p"); CHECK(result->IsInt32()); - CHECK_EQ(42, result->Int32Value()); + CHECK_EQ(42, result->Int32Value(env1.local()).FromJust()); // Hold on to global from env2 and detach global from env2. Local<v8::Object> global2 = env2->Global(); @@ -8413,11 +9431,9 @@ TEST(DetachGlobal) { CHECK(result.IsEmpty()); // Reuse global2 for env3. - v8::Handle<Context> env3 = Context::New(env1->GetIsolate(), - 0, - v8::Handle<v8::ObjectTemplate>(), - global2); - CHECK(global2->Equals(env3->Global())); + v8::Local<Context> env3 = Context::New( + env1->GetIsolate(), 0, v8::Local<v8::ObjectTemplate>(), global2); + CHECK(global2->Equals(env1.local(), env3->Global()).FromJust()); // Start by using the same security token for env3 as for env1 and env2. env3->SetSecurityToken(foo); @@ -8425,13 +9441,15 @@ TEST(DetachGlobal) { // Create a property on the global object in env3. { v8::Context::Scope scope(env3); - env3->Global()->Set(v8_str("p"), v8::Integer::New(env3->GetIsolate(), 24)); + CHECK(env3->Global() + ->Set(env3, v8_str("p"), v8::Integer::New(env3->GetIsolate(), 24)) + .FromJust()); } // Check that other.p is now the property in env3 and that we have access. result = CompileRun("other.p"); CHECK(result->IsInt32()); - CHECK_EQ(24, result->Int32Value()); + CHECK_EQ(24, result->Int32Value(env3).FromJust()); // Change security token for env3 to something different from env1 and env2. env3->SetSecurityToken(v8_str("bar")); @@ -8445,8 +9463,9 @@ TEST(DetachGlobal) { void GetThisX(const v8::FunctionCallbackInfo<v8::Value>& info) { + v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); info.GetReturnValue().Set( - info.GetIsolate()->GetCurrentContext()->Global()->Get(v8_str("x"))); + context->Global()->Get(context, v8_str("x")).ToLocalChecked()); } @@ -8468,21 +9487,30 @@ TEST(DetachedAccesses) { env1->SetSecurityToken(foo); env2->SetSecurityToken(foo); - env1->Global()->Set(v8_str("x"), v8_str("env1_x")); + CHECK(env1->Global() + ->Set(env1.local(), v8_str("x"), v8_str("env1_x")) + .FromJust()); { v8::Context::Scope scope(env2); - env2->Global()->Set(v8_str("x"), v8_str("env2_x")); + CHECK(env2->Global()->Set(env2, v8_str("x"), v8_str("env2_x")).FromJust()); CompileRun( "function bound_x() { return x; }" "function get_x() { return this.x; }" "function get_x_w() { return (function() {return this.x;})(); }"); - env1->Global()->Set(v8_str("bound_x"), CompileRun("bound_x")); - env1->Global()->Set(v8_str("get_x"), CompileRun("get_x")); - env1->Global()->Set(v8_str("get_x_w"), CompileRun("get_x_w")); - env1->Global()->Set( - v8_str("this_x"), - CompileRun("Object.getOwnPropertyDescriptor(this, 'this_x').get")); + CHECK(env1->Global() + ->Set(env1.local(), v8_str("bound_x"), CompileRun("bound_x")) + .FromJust()); + CHECK(env1->Global() + ->Set(env1.local(), v8_str("get_x"), CompileRun("get_x")) + .FromJust()); + CHECK(env1->Global() + ->Set(env1.local(), v8_str("get_x_w"), CompileRun("get_x_w")) + .FromJust()); + env1->Global() + ->Set(env1.local(), v8_str("this_x"), + CompileRun("Object.getOwnPropertyDescriptor(this, 'this_x').get")) + .FromJust(); } Local<Object> env2_global = env2->Global(); @@ -8490,24 +9518,22 @@ TEST(DetachedAccesses) { Local<Value> result; result = CompileRun("bound_x()"); - CHECK(v8_str("env2_x")->Equals(result)); + CHECK(v8_str("env2_x")->Equals(env1.local(), result).FromJust()); result = CompileRun("get_x()"); CHECK(result.IsEmpty()); result = CompileRun("get_x_w()"); CHECK(result.IsEmpty()); result = CompileRun("this_x()"); - CHECK(v8_str("env2_x")->Equals(result)); + CHECK(v8_str("env2_x")->Equals(env1.local(), result).FromJust()); // Reattach env2's proxy - env2 = Context::New(env1->GetIsolate(), - 0, - v8::Handle<v8::ObjectTemplate>(), + env2 = Context::New(env1->GetIsolate(), 0, v8::Local<v8::ObjectTemplate>(), env2_global); env2->SetSecurityToken(foo); { v8::Context::Scope scope(env2); - env2->Global()->Set(v8_str("x"), v8_str("env3_x")); - env2->Global()->Set(v8_str("env1"), env1->Global()); + CHECK(env2->Global()->Set(env2, v8_str("x"), v8_str("env3_x")).FromJust()); + CHECK(env2->Global()->Set(env2, v8_str("env1"), env1->Global()).FromJust()); result = CompileRun( "results = [];" "for (var i = 0; i < 4; i++ ) {" @@ -8520,10 +9546,18 @@ TEST(DetachedAccesses) { Local<v8::Array> results = Local<v8::Array>::Cast(result); CHECK_EQ(16u, results->Length()); for (int i = 0; i < 16; i += 4) { - CHECK(v8_str("env2_x")->Equals(results->Get(i + 0))); - CHECK(v8_str("env1_x")->Equals(results->Get(i + 1))); - CHECK(v8_str("env3_x")->Equals(results->Get(i + 2))); - CHECK(v8_str("env2_x")->Equals(results->Get(i + 3))); + CHECK(v8_str("env2_x") + ->Equals(env2, results->Get(env2, i + 0).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("env1_x") + ->Equals(env2, results->Get(env2, i + 1).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("env3_x") + ->Equals(env2, results->Get(env2, i + 2).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("env2_x") + ->Equals(env2, results->Get(env2, i + 3).ToLocalChecked()) + .FromJust()); } } @@ -8539,10 +9573,22 @@ TEST(DetachedAccesses) { Local<v8::Array> results = Local<v8::Array>::Cast(result); CHECK_EQ(16u, results->Length()); for (int i = 0; i < 16; i += 4) { - CHECK(v8_str("env2_x")->Equals(results->Get(i + 0))); - CHECK(v8_str("env3_x")->Equals(results->Get(i + 1))); - CHECK(v8_str("env3_x")->Equals(results->Get(i + 2))); - CHECK(v8_str("env2_x")->Equals(results->Get(i + 3))); + CHECK(v8_str("env2_x") + ->Equals(env1.local(), + results->Get(env1.local(), i + 0).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("env3_x") + ->Equals(env1.local(), + results->Get(env1.local(), i + 1).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("env3_x") + ->Equals(env1.local(), + results->Get(env1.local(), i + 2).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("env2_x") + ->Equals(env1.local(), + results->Get(env1.local(), i + 3).ToLocalChecked()) + .FromJust()); } result = CompileRun( @@ -8557,10 +9603,22 @@ TEST(DetachedAccesses) { results = Local<v8::Array>::Cast(result); CHECK_EQ(16u, results->Length()); for (int i = 0; i < 16; i += 4) { - CHECK(v8_str("env2_x")->Equals(results->Get(i + 0))); - CHECK(v8_str("env1_x")->Equals(results->Get(i + 1))); - CHECK(v8_str("env3_x")->Equals(results->Get(i + 2))); - CHECK(v8_str("env2_x")->Equals(results->Get(i + 3))); + CHECK(v8_str("env2_x") + ->Equals(env1.local(), + results->Get(env1.local(), i + 0).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("env1_x") + ->Equals(env1.local(), + results->Get(env1.local(), i + 1).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("env3_x") + ->Equals(env1.local(), + results->Get(env1.local(), i + 2).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("env2_x") + ->Equals(env1.local(), + results->Get(env1.local(), i + 3).ToLocalChecked()) + .FromJust()); } } @@ -8568,8 +9626,8 @@ TEST(DetachedAccesses) { static bool allowed_access = false; static bool AccessBlocker(Local<v8::Context> accessing_context, Local<v8::Object> accessed_object) { - return CcTest::isolate()->GetCurrentContext()->Global()->Equals( - accessed_object) || + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); + return context->Global()->Equals(context, accessed_object).FromJust() || allowed_access; } @@ -8584,11 +9642,11 @@ static void EchoGetter( } -static void EchoSetter(Local<String> name, - Local<Value> value, - const v8::PropertyCallbackInfo<void>&) { +static void EchoSetter(Local<String> name, Local<Value> value, + const v8::PropertyCallbackInfo<void>& args) { if (value->IsNumber()) - g_echo_value = value->Int32Value(); + g_echo_value = + value->Int32Value(args.GetIsolate()->GetCurrentContext()).FromJust(); } @@ -8615,23 +9673,20 @@ static void UnreachableFunction( TEST(AccessControl) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallback(AccessBlocker); // Add an accessor accessible by cross-domain JS code. global_template->SetAccessor( - v8_str("accessible_prop"), - EchoGetter, EchoSetter, - v8::Handle<Value>(), + v8_str("accessible_prop"), EchoGetter, EchoSetter, v8::Local<Value>(), v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE)); // Add an accessor that is not accessible by cross-domain JS code. - global_template->SetAccessor(v8_str("blocked_prop"), - UnreachableGetter, UnreachableSetter, - v8::Handle<Value>(), + global_template->SetAccessor(v8_str("blocked_prop"), UnreachableGetter, + UnreachableSetter, v8::Local<Value>(), v8::DEFAULT); global_template->SetAccessorProperty( @@ -8645,7 +9700,7 @@ TEST(AccessControl) { v8::Local<Context> context0 = Context::New(isolate, NULL, global_template); context0->Enter(); - v8::Handle<v8::Object> global0 = context0->Global(); + v8::Local<v8::Object> global0 = context0->Global(); // Define a property with JS getter and setter. CompileRun( @@ -8653,11 +9708,13 @@ TEST(AccessControl) { "function setter() { return 'setter'; }\n" "Object.defineProperty(this, 'js_accessor_p', {get:getter, set:setter})"); - Local<Value> getter = global0->Get(v8_str("getter")); - Local<Value> setter = global0->Get(v8_str("setter")); + Local<Value> getter = + global0->Get(context0, v8_str("getter")).ToLocalChecked(); + Local<Value> setter = + global0->Get(context0, v8_str("setter")).ToLocalChecked(); // And define normal element. - global0->Set(239, v8_str("239")); + CHECK(global0->Set(context0, 239, v8_str("239")).FromJust()); // Define an element with JS getter and setter. CompileRun( @@ -8665,16 +9722,18 @@ TEST(AccessControl) { "function el_setter() { return 'el_setter'; };\n" "Object.defineProperty(this, '42', {get: el_getter, set: el_setter});"); - Local<Value> el_getter = global0->Get(v8_str("el_getter")); - Local<Value> el_setter = global0->Get(v8_str("el_setter")); + Local<Value> el_getter = + global0->Get(context0, v8_str("el_getter")).ToLocalChecked(); + Local<Value> el_setter = + global0->Get(context0, v8_str("el_setter")).ToLocalChecked(); v8::HandleScope scope1(isolate); v8::Local<Context> context1 = Context::New(isolate); context1->Enter(); - v8::Handle<v8::Object> global1 = context1->Global(); - global1->Set(v8_str("other"), global0); + v8::Local<v8::Object> global1 = context1->Global(); + CHECK(global1->Set(context1, v8_str("other"), global0).FromJust()); // Access blocked property. CompileRun("other.blocked_prop = 1"); @@ -8731,28 +9790,29 @@ TEST(AccessControl) { allowed_access = false; - v8::Handle<Value> value; + v8::Local<Value> value; // Access accessible property value = CompileRun("other.accessible_prop = 3"); CHECK(value->IsNumber()); - CHECK_EQ(3, value->Int32Value()); + CHECK_EQ(3, value->Int32Value(context1).FromJust()); CHECK_EQ(3, g_echo_value); value = CompileRun("other.accessible_prop"); CHECK(value->IsNumber()); - CHECK_EQ(3, value->Int32Value()); + CHECK_EQ(3, value->Int32Value(context1).FromJust()); value = CompileRun( "Object.getOwnPropertyDescriptor(other, 'accessible_prop').value"); CHECK(value->IsNumber()); - CHECK_EQ(3, value->Int32Value()); + CHECK_EQ(3, value->Int32Value(context1).FromJust()); value = CompileRun("propertyIsEnumerable.call(other, 'accessible_prop')"); CHECK(value->IsTrue()); // Enumeration doesn't enumerate accessors from inaccessible objects in // the prototype chain even if the accessors are in themselves accessible. + // Enumeration doesn't throw, it silently ignores what it can't access. value = CompileRun( "(function() {" " var obj = { '__proto__': other };" @@ -8764,16 +9824,18 @@ TEST(AccessControl) { " return false;" " }" " }" - " return false;" - " } catch (e) {" " return true;" + " } catch (e) {" + " return false;" " }" "})()"); CHECK(value->IsTrue()); // Test that preventExtensions fails on a non-accessible object even if that // object is already non-extensible. - global1->Set(v8_str("checked_object"), global_template->NewInstance()); + CHECK(global1->Set(context1, v8_str("checked_object"), + global_template->NewInstance(context1).ToLocalChecked()) + .FromJust()); allowed_access = true; CompileRun("Object.preventExtensions(checked_object)"); ExpectFalse("Object.isExtensible(checked_object)"); @@ -8788,38 +9850,40 @@ TEST(AccessControl) { TEST(AccessControlES5) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallback(AccessBlocker); // Add accessible accessor. global_template->SetAccessor( - v8_str("accessible_prop"), - EchoGetter, EchoSetter, - v8::Handle<Value>(), + v8_str("accessible_prop"), EchoGetter, EchoSetter, v8::Local<Value>(), v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE)); // Add an accessor that is not accessible by cross-domain JS code. - global_template->SetAccessor(v8_str("blocked_prop"), - UnreachableGetter, UnreachableSetter, - v8::Handle<Value>(), + global_template->SetAccessor(v8_str("blocked_prop"), UnreachableGetter, + UnreachableSetter, v8::Local<Value>(), v8::DEFAULT); // Create an environment v8::Local<Context> context0 = Context::New(isolate, NULL, global_template); context0->Enter(); - v8::Handle<v8::Object> global0 = context0->Global(); + v8::Local<v8::Object> global0 = context0->Global(); v8::Local<Context> context1 = Context::New(isolate); context1->Enter(); - v8::Handle<v8::Object> global1 = context1->Global(); - global1->Set(v8_str("other"), global0); + v8::Local<v8::Object> global1 = context1->Global(); + CHECK(global1->Set(context1, v8_str("other"), global0).FromJust()); // Regression test for issue 1154. - CHECK(CompileRun("Object.keys(other).length == 0")->BooleanValue()); + CHECK(CompileRun("Object.keys(other).length == 1") + ->BooleanValue(context1) + .FromJust()); + CHECK(CompileRun("Object.keys(other)[0] == 'accessible_prop'") + ->BooleanValue(context1) + .FromJust()); CHECK(CompileRun("other.blocked_prop").IsEmpty()); // Regression test for issue 1027. @@ -8866,33 +9930,34 @@ static bool AccessAlwaysBlocked(Local<v8::Context> accessing_context, THREADED_TEST(AccessControlGetOwnPropertyNames) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> obj_template = - v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(isolate); obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42)); obj_template->SetAccessCheckCallback(AccessAlwaysBlocked); // Add an accessor accessible by cross-domain JS code. obj_template->SetAccessor( - v8_str("accessible_prop"), EchoGetter, EchoSetter, v8::Handle<Value>(), + v8_str("accessible_prop"), EchoGetter, EchoSetter, v8::Local<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(); - v8::Handle<v8::Object> global0 = context0->Global(); + v8::Local<v8::Object> global0 = context0->Global(); v8::HandleScope scope1(CcTest::isolate()); v8::Local<Context> context1 = Context::New(isolate); context1->Enter(); - v8::Handle<v8::Object> global1 = context1->Global(); - global1->Set(v8_str("other"), global0); - global1->Set(v8_str("object"), obj_template->NewInstance()); + v8::Local<v8::Object> global1 = context1->Global(); + CHECK(global1->Set(context1, v8_str("other"), global0).FromJust()); + CHECK(global1->Set(context1, v8_str("object"), + obj_template->NewInstance(context1).ToLocalChecked()) + .FromJust()); - v8::Handle<Value> value; + v8::Local<Value> value; // Attempt to get the property names of the other global object and // of an object that requires access checks. Accessing the other @@ -8902,12 +9967,12 @@ THREADED_TEST(AccessControlGetOwnPropertyNames) { value = CompileRun( "var names = Object.getOwnPropertyNames(other);" "names.length == 1 && names[0] == 'accessible_prop';"); - CHECK(value->BooleanValue()); + CHECK(value->BooleanValue(context1).FromJust()); value = CompileRun( "var names = Object.getOwnPropertyNames(object);" "names.length == 1 && names[0] == 'accessible_prop';"); - CHECK(value->BooleanValue()); + CHECK(value->BooleanValue(context1).FromJust()); context1->Exit(); context0->Exit(); @@ -8917,11 +9982,13 @@ THREADED_TEST(AccessControlGetOwnPropertyNames) { TEST(Regress470113) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> obj_template = - v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(isolate); obj_template->SetAccessCheckCallback(AccessAlwaysBlocked); LocalContext env; - env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance()); + CHECK(env->Global() + ->Set(env.local(), v8_str("prohibited"), + obj_template->NewInstance(env.local()).ToLocalChecked()) + .FromJust()); { v8::TryCatch try_catch(isolate); @@ -8948,49 +10015,47 @@ THREADED_TEST(CrossDomainAccessors) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::FunctionTemplate> func_template = + v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate> global_template = func_template->InstanceTemplate(); - v8::Handle<v8::ObjectTemplate> proto_template = + v8::Local<v8::ObjectTemplate> proto_template = func_template->PrototypeTemplate(); // Add an accessor to proto that's accessible by cross-domain JS code. - proto_template->SetAccessor(v8_str("accessible"), - ConstTenGetter, 0, - v8::Handle<Value>(), - v8::ALL_CAN_READ); + proto_template->SetAccessor(v8_str("accessible"), ConstTenGetter, 0, + v8::Local<Value>(), v8::ALL_CAN_READ); // Add an accessor that is not accessible by cross-domain JS code. - global_template->SetAccessor(v8_str("unreachable"), - UnreachableGetter, 0, - v8::Handle<Value>(), - v8::DEFAULT); + global_template->SetAccessor(v8_str("unreachable"), UnreachableGetter, 0, + v8::Local<Value>(), v8::DEFAULT); v8::Local<Context> context0 = Context::New(isolate, NULL, global_template); context0->Enter(); Local<v8::Object> global = context0->Global(); // Add a normal property that shadows 'accessible' - global->Set(v8_str("accessible"), v8_num(11)); + CHECK(global->Set(context0, v8_str("accessible"), v8_num(11)).FromJust()); // Enter a new context. v8::HandleScope scope1(CcTest::isolate()); v8::Local<Context> context1 = Context::New(isolate); context1->Enter(); - v8::Handle<v8::Object> global1 = context1->Global(); - global1->Set(v8_str("other"), global); + v8::Local<v8::Object> global1 = context1->Global(); + CHECK(global1->Set(context1, v8_str("other"), global).FromJust()); // Should return 10, instead of 11 - v8::Handle<Value> value = v8_compile("other.accessible")->Run(); + v8::Local<Value> value = + v8_compile("other.accessible")->Run(context1).ToLocalChecked(); CHECK(value->IsNumber()); - CHECK_EQ(10, value->Int32Value()); + CHECK_EQ(10, value->Int32Value(context1).FromJust()); - value = v8_compile("other.unreachable")->Run(); - CHECK(value.IsEmpty()); + v8::MaybeLocal<v8::Value> maybe_value = + v8_compile("other.unreachable")->Run(context1); + CHECK(maybe_value.IsEmpty()); context1->Exit(); context0->Exit(); @@ -9019,10 +10084,11 @@ TEST(AccessControlIC) { // Create an object that requires access-check functions to be // called for cross-domain access. - v8::Handle<v8::ObjectTemplate> object_template = + v8::Local<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(isolate); object_template->SetAccessCheckCallback(AccessCounter); - Local<v8::Object> object = object_template->NewInstance(); + Local<v8::Object> object = + object_template->NewInstance(context0).ToLocalChecked(); v8::HandleScope scope1(isolate); @@ -9031,10 +10097,10 @@ TEST(AccessControlIC) { context1->Enter(); // Make easy access to the object from the other environment. - v8::Handle<v8::Object> global1 = context1->Global(); - global1->Set(v8_str("obj"), object); + v8::Local<v8::Object> global1 = context1->Global(); + CHECK(global1->Set(context1, v8_str("obj"), object).FromJust()); - v8::Handle<Value> value; + v8::Local<Value> value; // Check that the named access-control function is called every time. CompileRun("function testProp(obj) {" @@ -9044,7 +10110,7 @@ TEST(AccessControlIC) { "}"); value = CompileRun("testProp(obj)"); CHECK(value->IsNumber()); - CHECK_EQ(1, value->Int32Value()); + CHECK_EQ(1, value->Int32Value(context1).FromJust()); CHECK_EQ(21, access_count); // Check that the named access-control function is called every time. @@ -9058,14 +10124,14 @@ TEST(AccessControlIC) { // in that case. value = CompileRun("testKeyed(obj)"); CHECK(value->IsNumber()); - CHECK_EQ(1, value->Int32Value()); + CHECK_EQ(1, value->Int32Value(context1).FromJust()); CHECK_EQ(42, access_count); // Force the inline caches into generic state and try again. CompileRun("testKeyed({ a: 0 })"); CompileRun("testKeyed({ b: 0 })"); value = CompileRun("testKeyed(obj)"); CHECK(value->IsNumber()); - CHECK_EQ(1, value->Int32Value()); + CHECK_EQ(1, value->Int32Value(context1).FromJust()); CHECK_EQ(63, access_count); // Check that the indexed access-control function is called every time. @@ -9078,14 +10144,14 @@ TEST(AccessControlIC) { "}"); value = CompileRun("testIndexed(obj)"); CHECK(value->IsNumber()); - CHECK_EQ(1, value->Int32Value()); + CHECK_EQ(1, value->Int32Value(context1).FromJust()); CHECK_EQ(21, access_count); // Force the inline caches into generic state. CompileRun("testIndexed(new Array(1))"); // Test that the indexed access check is called. value = CompileRun("testIndexed(obj)"); CHECK(value->IsNumber()); - CHECK_EQ(1, value->Int32Value()); + CHECK_EQ(1, value->Int32Value(context1).FromJust()); CHECK_EQ(42, access_count); access_count = 0; @@ -9101,13 +10167,13 @@ TEST(AccessControlIC) { // Force obj into slow case. value = CompileRun("delete obj.prop"); - CHECK(value->BooleanValue()); + CHECK(value->BooleanValue(context1).FromJust()); // Force inline caches into dictionary probing mode. CompileRun("var o = { x: 0 }; delete o.x; testProp(o);"); // Test that the named access check is called. value = CompileRun("testProp(obj);"); CHECK(value->IsNumber()); - CHECK_EQ(1, value->Int32Value()); + CHECK_EQ(1, value->Int32Value(context1).FromJust()); CHECK_EQ(33, access_count); // Force the call inline cache into dictionary probing mode. @@ -9144,14 +10210,17 @@ THREADED_TEST(InstanceProperties) { instance->Set(v8_str("f"), v8::FunctionTemplate::New(isolate, InstanceFunctionCallback)); - Local<Value> o = t->GetFunction()->NewInstance(); + Local<Value> o = t->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); - context->Global()->Set(v8_str("i"), o); + CHECK(context->Global()->Set(context.local(), v8_str("i"), o).FromJust()); Local<Value> value = CompileRun("i.x"); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(context.local()).FromJust()); value = CompileRun("i.f()"); - CHECK_EQ(12, value->Int32Value()); + CHECK_EQ(12, value->Int32Value(context.local()).FromJust()); } @@ -9199,22 +10268,22 @@ THREADED_TEST(GlobalObjectInstanceProperties) { global_object = env->Global(); Local<Value> value = CompileRun("x"); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(env.local()).FromJust()); value = CompileRun("f()"); - CHECK_EQ(12, value->Int32Value()); + CHECK_EQ(12, value->Int32Value(env.local()).FromJust()); value = CompileRun(script); - CHECK_EQ(1, value->Int32Value()); + CHECK_EQ(1, value->Int32Value(env.local()).FromJust()); } { // Create new environment reusing the global object. LocalContext env(NULL, instance_template, global_object); Local<Value> value = CompileRun("x"); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(env.local()).FromJust()); value = CompileRun("f()"); - CHECK_EQ(12, value->Int32Value()); + CHECK_EQ(12, value->Int32Value(env.local()).FromJust()); value = CompileRun(script); - CHECK_EQ(1, value->Int32Value()); + CHECK_EQ(1, value->Int32Value(env.local()).FromJust()); } } @@ -9254,7 +10323,7 @@ THREADED_TEST(CallKnownGlobalReceiver) { { // Create new environment reusing the global object. LocalContext env(NULL, instance_template, global_object); - env->Global()->Set(v8_str("foo"), foo); + CHECK(env->Global()->Set(env.local(), v8_str("foo"), foo).FromJust()); CompileRun("foo()"); } } @@ -9321,25 +10390,30 @@ THREADED_TEST(ShadowObject) { instance->SetAccessor(v8_str("y"), ShadowYGetter, ShadowYSetter); - Local<Value> o = t->GetFunction()->NewInstance(); - context->Global()->Set(v8_str("__proto__"), o); + Local<Value> o = t->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("__proto__"), o) + .FromJust()); Local<Value> value = CompileRun("this.propertyIsEnumerable(0)"); CHECK(value->IsBoolean()); - CHECK(!value->BooleanValue()); + CHECK(!value->BooleanValue(context.local()).FromJust()); value = CompileRun("x"); - CHECK_EQ(12, value->Int32Value()); + CHECK_EQ(12, value->Int32Value(context.local()).FromJust()); value = CompileRun("f()"); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(context.local()).FromJust()); CompileRun("y = 43"); CHECK_EQ(1, shadow_y_setter_call_count); value = CompileRun("y"); CHECK_EQ(1, shadow_y_getter_call_count); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(context.local()).FromJust()); } @@ -9359,32 +10433,78 @@ THREADED_TEST(HiddenPrototype) { Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate); t3->InstanceTemplate()->Set(v8_str("u"), v8_num(3)); - Local<v8::Object> o0 = t0->GetFunction()->NewInstance(); - Local<v8::Object> o1 = t1->GetFunction()->NewInstance(); - Local<v8::Object> o2 = t2->GetFunction()->NewInstance(); - Local<v8::Object> o3 = t3->GetFunction()->NewInstance(); + Local<v8::Object> o0 = t0->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<v8::Object> o1 = t1->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<v8::Object> o2 = t2->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<v8::Object> o3 = t3->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); // Setting the prototype on an object skips hidden prototypes. - CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value()); - o0->Set(v8_str("__proto__"), o1); - CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value()); - CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value()); - o0->Set(v8_str("__proto__"), o2); - CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value()); - CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value()); - CHECK_EQ(2, o0->Get(v8_str("z"))->Int32Value()); - o0->Set(v8_str("__proto__"), o3); - CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value()); - CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value()); - CHECK_EQ(2, o0->Get(v8_str("z"))->Int32Value()); - CHECK_EQ(3, o0->Get(v8_str("u"))->Int32Value()); + CHECK_EQ(0, o0->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK(o0->Set(context.local(), v8_str("__proto__"), o1).FromJust()); + CHECK_EQ(0, o0->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(1, o0->Get(context.local(), v8_str("y")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK(o0->Set(context.local(), v8_str("__proto__"), o2).FromJust()); + CHECK_EQ(0, o0->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(1, o0->Get(context.local(), v8_str("y")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(2, o0->Get(context.local(), v8_str("z")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK(o0->Set(context.local(), v8_str("__proto__"), o3).FromJust()); + CHECK_EQ(0, o0->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(1, o0->Get(context.local(), v8_str("y")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(2, o0->Get(context.local(), v8_str("z")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(3, o0->Get(context.local(), v8_str("u")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); // Getting the prototype of o0 should get the first visible one // which is o3. Therefore, z should not be defined on the prototype // object. - Local<Value> proto = o0->Get(v8_str("__proto__")); + Local<Value> proto = + o0->Get(context.local(), v8_str("__proto__")).ToLocalChecked(); CHECK(proto->IsObject()); - CHECK(proto.As<v8::Object>()->Get(v8_str("z"))->IsUndefined()); + CHECK(proto.As<v8::Object>() + ->Get(context.local(), v8_str("z")) + .ToLocalChecked() + ->IsUndefined()); } @@ -9399,34 +10519,70 @@ THREADED_TEST(HiddenPrototypeSet) { Local<v8::FunctionTemplate> pt = v8::FunctionTemplate::New(isolate); ht->InstanceTemplate()->Set(v8_str("x"), v8_num(0)); - Local<v8::Object> o = ot->GetFunction()->NewInstance(); - Local<v8::Object> h = ht->GetFunction()->NewInstance(); - Local<v8::Object> p = pt->GetFunction()->NewInstance(); - o->Set(v8_str("__proto__"), h); - h->Set(v8_str("__proto__"), p); + Local<v8::Object> o = ot->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<v8::Object> h = ht->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<v8::Object> p = pt->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + CHECK(o->Set(context.local(), v8_str("__proto__"), h).FromJust()); + CHECK(h->Set(context.local(), v8_str("__proto__"), p).FromJust()); // Setting a property that exists on the hidden prototype goes there. - o->Set(v8_str("x"), v8_num(7)); - CHECK_EQ(7, o->Get(v8_str("x"))->Int32Value()); - CHECK_EQ(7, h->Get(v8_str("x"))->Int32Value()); - CHECK(p->Get(v8_str("x"))->IsUndefined()); + CHECK(o->Set(context.local(), v8_str("x"), v8_num(7)).FromJust()); + CHECK_EQ(7, o->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(7, h->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK(p->Get(context.local(), v8_str("x")).ToLocalChecked()->IsUndefined()); // Setting a new property should not be forwarded to the hidden prototype. - o->Set(v8_str("y"), v8_num(6)); - CHECK_EQ(6, o->Get(v8_str("y"))->Int32Value()); - CHECK(h->Get(v8_str("y"))->IsUndefined()); - CHECK(p->Get(v8_str("y"))->IsUndefined()); + CHECK(o->Set(context.local(), v8_str("y"), v8_num(6)).FromJust()); + CHECK_EQ(6, o->Get(context.local(), v8_str("y")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK(h->Get(context.local(), v8_str("y")).ToLocalChecked()->IsUndefined()); + CHECK(p->Get(context.local(), v8_str("y")).ToLocalChecked()->IsUndefined()); // Setting a property that only exists on a prototype of the hidden prototype // is treated normally again. - p->Set(v8_str("z"), v8_num(8)); - CHECK_EQ(8, o->Get(v8_str("z"))->Int32Value()); - CHECK_EQ(8, h->Get(v8_str("z"))->Int32Value()); - CHECK_EQ(8, p->Get(v8_str("z"))->Int32Value()); - o->Set(v8_str("z"), v8_num(9)); - CHECK_EQ(9, o->Get(v8_str("z"))->Int32Value()); - CHECK_EQ(8, h->Get(v8_str("z"))->Int32Value()); - CHECK_EQ(8, p->Get(v8_str("z"))->Int32Value()); + CHECK(p->Set(context.local(), v8_str("z"), v8_num(8)).FromJust()); + CHECK_EQ(8, o->Get(context.local(), v8_str("z")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(8, h->Get(context.local(), v8_str("z")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(8, p->Get(context.local(), v8_str("z")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK(o->Set(context.local(), v8_str("z"), v8_num(9)).FromJust()); + CHECK_EQ(9, o->Get(context.local(), v8_str("z")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(8, h->Get(context.local(), v8_str("z")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(8, p->Get(context.local(), v8_str("z")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } @@ -9435,17 +10591,20 @@ THREADED_TEST(HiddenPrototypeIdentityHash) { LocalContext context; v8::HandleScope handle_scope(context->GetIsolate()); - Handle<FunctionTemplate> t = FunctionTemplate::New(context->GetIsolate()); + Local<FunctionTemplate> t = FunctionTemplate::New(context->GetIsolate()); t->SetHiddenPrototype(true); t->InstanceTemplate()->Set(v8_str("foo"), v8_num(75)); - Handle<Object> p = t->GetFunction()->NewInstance(); - Handle<Object> o = Object::New(context->GetIsolate()); - o->SetPrototype(p); + Local<Object> p = t->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<Object> o = Object::New(context->GetIsolate()); + CHECK(o->SetPrototype(context.local(), p).FromJust()); int hash = o->GetIdentityHash(); USE(hash); - o->Set(v8_str("foo"), v8_num(42)); - DCHECK_EQ(hash, o->GetIdentityHash()); + CHECK(o->Set(context.local(), v8_str("foo"), v8_num(42)).FromJust()); + CHECK_EQ(hash, o->GetIdentityHash()); } @@ -9465,45 +10624,88 @@ THREADED_TEST(SetPrototype) { Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate); t3->InstanceTemplate()->Set(v8_str("u"), v8_num(3)); - Local<v8::Object> o0 = t0->GetFunction()->NewInstance(); - Local<v8::Object> o1 = t1->GetFunction()->NewInstance(); - Local<v8::Object> o2 = t2->GetFunction()->NewInstance(); - Local<v8::Object> o3 = t3->GetFunction()->NewInstance(); + Local<v8::Object> o0 = t0->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<v8::Object> o1 = t1->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<v8::Object> o2 = t2->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<v8::Object> o3 = t3->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); // Setting the prototype on an object does not skip hidden prototypes. - CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value()); - CHECK(o0->SetPrototype(o1)); - CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value()); - CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value()); - CHECK(o1->SetPrototype(o2)); - CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value()); - CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value()); - CHECK_EQ(2, o0->Get(v8_str("z"))->Int32Value()); - CHECK(o2->SetPrototype(o3)); - CHECK_EQ(0, o0->Get(v8_str("x"))->Int32Value()); - CHECK_EQ(1, o0->Get(v8_str("y"))->Int32Value()); - CHECK_EQ(2, o0->Get(v8_str("z"))->Int32Value()); - CHECK_EQ(3, o0->Get(v8_str("u"))->Int32Value()); + CHECK_EQ(0, o0->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK(o0->SetPrototype(context.local(), o1).FromJust()); + CHECK_EQ(0, o0->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(1, o0->Get(context.local(), v8_str("y")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK(o1->SetPrototype(context.local(), o2).FromJust()); + CHECK_EQ(0, o0->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(1, o0->Get(context.local(), v8_str("y")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(2, o0->Get(context.local(), v8_str("z")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK(o2->SetPrototype(context.local(), o3).FromJust()); + CHECK_EQ(0, o0->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(1, o0->Get(context.local(), v8_str("y")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(2, o0->Get(context.local(), v8_str("z")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(3, o0->Get(context.local(), v8_str("u")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); // Getting the prototype of o0 should get the first visible one // which is o3. Therefore, z should not be defined on the prototype // object. - Local<Value> proto = o0->Get(v8_str("__proto__")); + Local<Value> proto = + o0->Get(context.local(), v8_str("__proto__")).ToLocalChecked(); CHECK(proto->IsObject()); - CHECK(proto.As<v8::Object>()->Equals(o3)); + CHECK(proto.As<v8::Object>()->Equals(context.local(), o3).FromJust()); // However, Object::GetPrototype ignores hidden prototype. Local<Value> proto0 = o0->GetPrototype(); CHECK(proto0->IsObject()); - CHECK(proto0.As<v8::Object>()->Equals(o1)); + CHECK(proto0.As<v8::Object>()->Equals(context.local(), o1).FromJust()); Local<Value> proto1 = o1->GetPrototype(); CHECK(proto1->IsObject()); - CHECK(proto1.As<v8::Object>()->Equals(o2)); + CHECK(proto1.As<v8::Object>()->Equals(context.local(), o2).FromJust()); Local<Value> proto2 = o2->GetPrototype(); CHECK(proto2->IsObject()); - CHECK(proto2.As<v8::Object>()->Equals(o3)); + CHECK(proto2.As<v8::Object>()->Equals(context.local(), o3).FromJust()); } @@ -9537,21 +10739,33 @@ THREADED_TEST(Regress91517) { t2->InstanceTemplate()->Set(v8_str(name_buf.start()), v8_num(2)); } - Local<v8::Object> o1 = t1->GetFunction()->NewInstance(); - Local<v8::Object> o2 = t2->GetFunction()->NewInstance(); - Local<v8::Object> o3 = t3->GetFunction()->NewInstance(); - Local<v8::Object> o4 = t4->GetFunction()->NewInstance(); + Local<v8::Object> o1 = t1->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<v8::Object> o2 = t2->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<v8::Object> o3 = t3->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<v8::Object> o4 = t4->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); // Create prototype chain of hidden prototypes. - CHECK(o4->SetPrototype(o3)); - CHECK(o3->SetPrototype(o2)); - CHECK(o2->SetPrototype(o1)); + CHECK(o4->SetPrototype(context.local(), o3).FromJust()); + CHECK(o3->SetPrototype(context.local(), o2).FromJust()); + CHECK(o2->SetPrototype(context.local(), o1).FromJust()); // Call the runtime version of GetOwnPropertyNames() on the natively // created object through JavaScript. - context->Global()->Set(v8_str("obj"), o4); - // PROPERTY_ATTRIBUTES_NONE = 0 - CompileRun("var names = %GetOwnPropertyNames(obj, 0);"); + CHECK(context->Global()->Set(context.local(), v8_str("obj"), o4).FromJust()); + // PROPERTY_FILTER_NONE = 0 + CompileRun("var names = %GetOwnPropertyKeys(obj, 0);"); ExpectInt32("names.length", 1006); ExpectTrue("names.indexOf(\"baz\") >= 0"); @@ -9584,7 +10798,10 @@ THREADED_TEST(Regress269562) { i1->Set(v8_str("n1"), v8_num(1)); i1->Set(v8_str("n2"), v8_num(2)); - Local<v8::Object> o1 = t1->GetFunction()->NewInstance(); + Local<v8::Object> o1 = t1->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(context->GetIsolate()); t2->SetHiddenPrototype(true); @@ -9593,12 +10810,15 @@ THREADED_TEST(Regress269562) { t2->Inherit(t1); t2->InstanceTemplate()->Set(v8_str("mine"), v8_num(4)); - Local<v8::Object> o2 = t2->GetFunction()->NewInstance(); - CHECK(o2->SetPrototype(o1)); + Local<v8::Object> o2 = t2->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + CHECK(o2->SetPrototype(context.local(), o1).FromJust()); v8::Local<v8::Symbol> sym = v8::Symbol::New(context->GetIsolate(), v8_str("s1")); - o1->Set(sym, v8_num(3)); + CHECK(o1->Set(context.local(), sym, v8_num(3)).FromJust()); o1->SetPrivate(context.local(), v8::Private::New(context->GetIsolate(), v8_str("h1")), v8::Integer::New(context->GetIsolate(), 2013)) @@ -9606,10 +10826,10 @@ THREADED_TEST(Regress269562) { // Call the runtime version of GetOwnPropertyNames() on // the natively created object through JavaScript. - context->Global()->Set(v8_str("obj"), o2); - context->Global()->Set(v8_str("sym"), sym); - // PROPERTY_ATTRIBUTES_NONE = 0 - CompileRun("var names = %GetOwnPropertyNames(obj, 0);"); + CHECK(context->Global()->Set(context.local(), v8_str("obj"), o2).FromJust()); + CHECK(context->Global()->Set(context.local(), v8_str("sym"), sym).FromJust()); + // PROPERTY_FILTER_NONE = 0 + CompileRun("var names = %GetOwnPropertyKeys(obj, 0);"); ExpectInt32("names.length", 7); ExpectTrue("names.indexOf(\"foo\") >= 0"); @@ -9630,27 +10850,44 @@ THREADED_TEST(FunctionReadOnlyPrototype) { Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); t1->PrototypeTemplate()->Set(v8_str("x"), v8::Integer::New(isolate, 42)); t1->ReadOnlyPrototype(); - context->Global()->Set(v8_str("func1"), t1->GetFunction()); + CHECK(context->Global() + ->Set(context.local(), v8_str("func1"), + t1->GetFunction(context.local()).ToLocalChecked()) + .FromJust()); // Configured value of ReadOnly flag. - CHECK(CompileRun( - "(function() {" - " descriptor = Object.getOwnPropertyDescriptor(func1, 'prototype');" - " return (descriptor['writable'] == false);" - "})()")->BooleanValue()); - CHECK_EQ(42, CompileRun("func1.prototype.x")->Int32Value()); - CHECK_EQ(42, - CompileRun("func1.prototype = {}; func1.prototype.x")->Int32Value()); + CHECK( + CompileRun( + "(function() {" + " descriptor = Object.getOwnPropertyDescriptor(func1, 'prototype');" + " return (descriptor['writable'] == false);" + "})()") + ->BooleanValue(context.local()) + .FromJust()); + CHECK_EQ( + 42, + CompileRun("func1.prototype.x")->Int32Value(context.local()).FromJust()); + CHECK_EQ(42, CompileRun("func1.prototype = {}; func1.prototype.x") + ->Int32Value(context.local()) + .FromJust()); Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate); t2->PrototypeTemplate()->Set(v8_str("x"), v8::Integer::New(isolate, 42)); - context->Global()->Set(v8_str("func2"), t2->GetFunction()); + CHECK(context->Global() + ->Set(context.local(), v8_str("func2"), + t2->GetFunction(context.local()).ToLocalChecked()) + .FromJust()); // Default value of ReadOnly flag. - CHECK(CompileRun( - "(function() {" - " descriptor = Object.getOwnPropertyDescriptor(func2, 'prototype');" - " return (descriptor['writable'] == true);" - "})()")->BooleanValue()); - CHECK_EQ(42, CompileRun("func2.prototype.x")->Int32Value()); + CHECK( + CompileRun( + "(function() {" + " descriptor = Object.getOwnPropertyDescriptor(func2, 'prototype');" + " return (descriptor['writable'] == true);" + "})()") + ->BooleanValue(context.local()) + .FromJust()); + CHECK_EQ( + 42, + CompileRun("func2.prototype.x")->Int32Value(context.local()).FromJust()); } @@ -9661,18 +10898,26 @@ THREADED_TEST(SetPrototypeThrows) { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); - Local<v8::Object> o0 = t->GetFunction()->NewInstance(); - Local<v8::Object> o1 = t->GetFunction()->NewInstance(); + Local<v8::Object> o0 = t->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<v8::Object> o1 = t->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); - CHECK(o0->SetPrototype(o1)); + CHECK(o0->SetPrototype(context.local(), o1).FromJust()); // If setting the prototype leads to the cycle, SetPrototype should // return false and keep VM in sane state. v8::TryCatch try_catch(isolate); - CHECK(!o1->SetPrototype(o0)); + CHECK(o1->SetPrototype(context.local(), o0).IsNothing()); CHECK(!try_catch.HasCaught()); - DCHECK(!CcTest::i_isolate()->has_pending_exception()); + CHECK(!CcTest::i_isolate()->has_pending_exception()); - CHECK_EQ(42, CompileRun("function f() { return 42; }; f()")->Int32Value()); + CHECK_EQ(42, CompileRun("function f() { return 42; }; f()") + ->Int32Value(context.local()) + .FromJust()); } @@ -9683,16 +10928,18 @@ THREADED_TEST(FunctionRemovePrototype) { Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); t1->RemovePrototype(); - Local<v8::Function> fun = t1->GetFunction(); - context->Global()->Set(v8_str("fun"), fun); - CHECK(!CompileRun("'prototype' in fun")->BooleanValue()); + Local<v8::Function> fun = t1->GetFunction(context.local()).ToLocalChecked(); + CHECK(context->Global()->Set(context.local(), v8_str("fun"), fun).FromJust()); + CHECK(!CompileRun("'prototype' in fun") + ->BooleanValue(context.local()) + .FromJust()); v8::TryCatch try_catch(isolate); CompileRun("new fun()"); CHECK(try_catch.HasCaught()); try_catch.Reset(); - fun->NewInstance(); + CHECK(fun->NewInstance(context.local()).IsEmpty()); CHECK(try_catch.HasCaught()); } @@ -9707,17 +10954,21 @@ THREADED_TEST(GetterSetterExceptions) { "var x = { };" "x.__defineSetter__('set', Throw);" "x.__defineGetter__('get', Throw);"); - Local<v8::Object> x = - Local<v8::Object>::Cast(context->Global()->Get(v8_str("x"))); + Local<v8::Object> x = Local<v8::Object>::Cast( + context->Global()->Get(context.local(), v8_str("x")).ToLocalChecked()); v8::TryCatch try_catch(isolate); - x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); - x->Get(v8_str("get")); - x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); - x->Get(v8_str("get")); - x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); - x->Get(v8_str("get")); - x->Set(v8_str("set"), v8::Integer::New(isolate, 8)); - x->Get(v8_str("get")); + CHECK(x->Set(context.local(), v8_str("set"), v8::Integer::New(isolate, 8)) + .IsNothing()); + CHECK(x->Get(context.local(), v8_str("get")).IsEmpty()); + CHECK(x->Set(context.local(), v8_str("set"), v8::Integer::New(isolate, 8)) + .IsNothing()); + CHECK(x->Get(context.local(), v8_str("get")).IsEmpty()); + CHECK(x->Set(context.local(), v8_str("set"), v8::Integer::New(isolate, 8)) + .IsNothing()); + CHECK(x->Get(context.local(), v8_str("get")).IsEmpty()); + CHECK(x->Set(context.local(), v8_str("set"), v8::Integer::New(isolate, 8)) + .IsNothing()); + CHECK(x->Get(context.local(), v8_str("get")).IsEmpty()); } @@ -9727,13 +10978,14 @@ THREADED_TEST(Constructor) { v8::HandleScope handle_scope(isolate); Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); templ->SetClassName(v8_str("Fun")); - Local<Function> cons = templ->GetFunction(); - context->Global()->Set(v8_str("Fun"), cons); - Local<v8::Object> inst = cons->NewInstance(); - i::Handle<i::JSObject> obj(v8::Utils::OpenHandle(*inst)); + Local<Function> cons = templ->GetFunction(context.local()).ToLocalChecked(); + CHECK( + context->Global()->Set(context.local(), v8_str("Fun"), cons).FromJust()); + Local<v8::Object> inst = cons->NewInstance(context.local()).ToLocalChecked(); + i::Handle<i::JSReceiver> obj(v8::Utils::OpenHandle(*inst)); CHECK(obj->IsJSObject()); Local<Value> value = CompileRun("(new Fun()).constructor === Fun"); - CHECK(value->BooleanValue()); + CHECK(value->BooleanValue(context.local()).FromJust()); } @@ -9742,18 +10994,19 @@ static void ConstructorCallback( ApiTestFuzzer::Fuzz(); Local<Object> This; + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); if (args.IsConstructCall()) { Local<Object> Holder = args.Holder(); This = Object::New(args.GetIsolate()); Local<Value> proto = Holder->GetPrototype(); if (proto->IsObject()) { - This->SetPrototype(proto); + This->SetPrototype(context, proto).FromJust(); } } else { This = args.This(); } - This->Set(v8_str("a"), args[0]); + This->Set(context, v8_str("a"), args[0]).FromJust(); args.GetReturnValue().Set(This); } @@ -9773,8 +11026,11 @@ THREADED_TEST(ConstructorForObject) { { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); instance_template->SetCallAsFunctionHandler(ConstructorCallback); - Local<Object> instance = instance_template->NewInstance(); - context->Global()->Set(v8_str("obj"), instance); + Local<Object> instance = + instance_template->NewInstance(context.local()).ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj"), instance) + .FromJust()); v8::TryCatch try_catch(isolate); Local<Value> value; CHECK(!try_catch.HasCaught()); @@ -9783,65 +11039,72 @@ THREADED_TEST(ConstructorForObject) { value = CompileRun("(function() { var o = new obj(28); return o.a; })()"); CHECK(!try_catch.HasCaught()); CHECK(value->IsInt32()); - CHECK_EQ(28, value->Int32Value()); + CHECK_EQ(28, value->Int32Value(context.local()).FromJust()); Local<Value> args1[] = {v8_num(28)}; - Local<Value> value_obj1 = instance->CallAsConstructor(1, args1); + Local<Value> value_obj1 = + instance->CallAsConstructor(context.local(), 1, args1).ToLocalChecked(); CHECK(value_obj1->IsObject()); Local<Object> object1 = Local<Object>::Cast(value_obj1); - value = object1->Get(v8_str("a")); + value = object1->Get(context.local(), v8_str("a")).ToLocalChecked(); CHECK(value->IsInt32()); CHECK(!try_catch.HasCaught()); - CHECK_EQ(28, value->Int32Value()); + CHECK_EQ(28, value->Int32Value(context.local()).FromJust()); // Call the Object's constructor with a String. value = CompileRun("(function() { var o = new obj('tipli'); return o.a; })()"); CHECK(!try_catch.HasCaught()); CHECK(value->IsString()); - String::Utf8Value string_value1(value->ToString(isolate)); + String::Utf8Value string_value1( + value->ToString(context.local()).ToLocalChecked()); CHECK_EQ(0, strcmp("tipli", *string_value1)); Local<Value> args2[] = {v8_str("tipli")}; - Local<Value> value_obj2 = instance->CallAsConstructor(1, args2); + Local<Value> value_obj2 = + instance->CallAsConstructor(context.local(), 1, args2).ToLocalChecked(); CHECK(value_obj2->IsObject()); Local<Object> object2 = Local<Object>::Cast(value_obj2); - value = object2->Get(v8_str("a")); + value = object2->Get(context.local(), v8_str("a")).ToLocalChecked(); CHECK(!try_catch.HasCaught()); CHECK(value->IsString()); - String::Utf8Value string_value2(value->ToString(isolate)); + String::Utf8Value string_value2( + value->ToString(context.local()).ToLocalChecked()); CHECK_EQ(0, strcmp("tipli", *string_value2)); // Call the Object's constructor with a Boolean. value = CompileRun("(function() { var o = new obj(true); return o.a; })()"); CHECK(!try_catch.HasCaught()); CHECK(value->IsBoolean()); - CHECK_EQ(true, value->BooleanValue()); + CHECK_EQ(true, value->BooleanValue(context.local()).FromJust()); - Handle<Value> args3[] = {v8::True(isolate)}; - Local<Value> value_obj3 = instance->CallAsConstructor(1, args3); + Local<Value> args3[] = {v8::True(isolate)}; + Local<Value> value_obj3 = + instance->CallAsConstructor(context.local(), 1, args3).ToLocalChecked(); CHECK(value_obj3->IsObject()); Local<Object> object3 = Local<Object>::Cast(value_obj3); - value = object3->Get(v8_str("a")); + value = object3->Get(context.local(), v8_str("a")).ToLocalChecked(); CHECK(!try_catch.HasCaught()); CHECK(value->IsBoolean()); - CHECK_EQ(true, value->BooleanValue()); + CHECK_EQ(true, value->BooleanValue(context.local()).FromJust()); // Call the Object's constructor with undefined. - Handle<Value> args4[] = {v8::Undefined(isolate)}; - Local<Value> value_obj4 = instance->CallAsConstructor(1, args4); + Local<Value> args4[] = {v8::Undefined(isolate)}; + Local<Value> value_obj4 = + instance->CallAsConstructor(context.local(), 1, args4).ToLocalChecked(); CHECK(value_obj4->IsObject()); Local<Object> object4 = Local<Object>::Cast(value_obj4); - value = object4->Get(v8_str("a")); + value = object4->Get(context.local(), v8_str("a")).ToLocalChecked(); CHECK(!try_catch.HasCaught()); CHECK(value->IsUndefined()); // Call the Object's constructor with null. - Handle<Value> args5[] = {v8::Null(isolate)}; - Local<Value> value_obj5 = instance->CallAsConstructor(1, args5); + Local<Value> args5[] = {v8::Null(isolate)}; + Local<Value> value_obj5 = + instance->CallAsConstructor(context.local(), 1, args5).ToLocalChecked(); CHECK(value_obj5->IsObject()); Local<Object> object5 = Local<Object>::Cast(value_obj5); - value = object5->Get(v8_str("a")); + value = object5->Get(context.local(), v8_str("a")).ToLocalChecked(); CHECK(!try_catch.HasCaught()); CHECK(value->IsNull()); } @@ -9849,8 +11112,11 @@ THREADED_TEST(ConstructorForObject) { // Check exception handling when there is no constructor set for the Object. { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); - Local<Object> instance = instance_template->NewInstance(); - context->Global()->Set(v8_str("obj2"), instance); + Local<Object> instance = + instance_template->NewInstance(context.local()).ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj2"), instance) + .FromJust()); v8::TryCatch try_catch(isolate); Local<Value> value; CHECK(!try_catch.HasCaught()); @@ -9858,15 +11124,16 @@ THREADED_TEST(ConstructorForObject) { value = CompileRun("new obj2(28)"); CHECK(try_catch.HasCaught()); String::Utf8Value exception_value1(try_catch.Exception()); - CHECK_EQ(0, strcmp("TypeError: obj2 is not a function", *exception_value1)); + CHECK_EQ(0, + strcmp("TypeError: obj2 is not a constructor", *exception_value1)); try_catch.Reset(); Local<Value> args[] = {v8_num(29)}; - value = instance->CallAsConstructor(1, args); + CHECK(instance->CallAsConstructor(context.local(), 1, args).IsEmpty()); CHECK(try_catch.HasCaught()); String::Utf8Value exception_value2(try_catch.Exception()); - CHECK_EQ(0, - strcmp("TypeError: object is not a function", *exception_value2)); + CHECK_EQ( + 0, strcmp("TypeError: object is not a constructor", *exception_value2)); try_catch.Reset(); } @@ -9874,8 +11141,11 @@ THREADED_TEST(ConstructorForObject) { { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); instance_template->SetCallAsFunctionHandler(ThrowValue); - Local<Object> instance = instance_template->NewInstance(); - context->Global()->Set(v8_str("obj3"), instance); + Local<Object> instance = + instance_template->NewInstance(context.local()).ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj3"), instance) + .FromJust()); v8::TryCatch try_catch(isolate); Local<Value> value; CHECK(!try_catch.HasCaught()); @@ -9887,7 +11157,7 @@ THREADED_TEST(ConstructorForObject) { try_catch.Reset(); Local<Value> args[] = {v8_num(23)}; - value = instance->CallAsConstructor(1, args); + CHECK(instance->CallAsConstructor(context.local(), 1, args).IsEmpty()); CHECK(try_catch.HasCaught()); String::Utf8Value exception_value2(try_catch.Exception()); CHECK_EQ(0, strcmp("23", *exception_value2)); @@ -9898,9 +11168,12 @@ THREADED_TEST(ConstructorForObject) { { Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate, FakeConstructorCallback); - Local<Function> function = function_template->GetFunction(); + Local<Function> function = + function_template->GetFunction(context.local()).ToLocalChecked(); Local<Object> instance1 = function; - context->Global()->Set(v8_str("obj4"), instance1); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj4"), instance1) + .FromJust()); v8::TryCatch try_catch(isolate); Local<Value> value; CHECK(!try_catch.HasCaught()); @@ -9913,14 +11186,18 @@ THREADED_TEST(ConstructorForObject) { CHECK(value->IsObject()); Local<Value> args1[] = {v8_num(28)}; - value = instance1->CallAsConstructor(1, args1); + value = instance1->CallAsConstructor(context.local(), 1, args1) + .ToLocalChecked(); CHECK(!try_catch.HasCaught()); CHECK(value->IsObject()); Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); instance_template->SetCallAsFunctionHandler(FakeConstructorCallback); - Local<Object> instance2 = instance_template->NewInstance(); - context->Global()->Set(v8_str("obj5"), instance2); + Local<Object> instance2 = + instance_template->NewInstance(context.local()).ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj5"), instance2) + .FromJust()); CHECK(!try_catch.HasCaught()); CHECK(instance2->IsObject()); @@ -9931,7 +11208,8 @@ THREADED_TEST(ConstructorForObject) { CHECK(!value->IsObject()); Local<Value> args2[] = {v8_num(28)}; - value = instance2->CallAsConstructor(1, args2); + value = instance2->CallAsConstructor(context.local(), 1, args2) + .ToLocalChecked(); CHECK(!try_catch.HasCaught()); CHECK(!value->IsObject()); } @@ -9944,8 +11222,9 @@ THREADED_TEST(FunctionDescriptorException) { v8::HandleScope handle_scope(isolate); Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); templ->SetClassName(v8_str("Fun")); - Local<Function> cons = templ->GetFunction(); - context->Global()->Set(v8_str("Fun"), cons); + Local<Function> cons = templ->GetFunction(context.local()).ToLocalChecked(); + CHECK( + context->Global()->Set(context.local(), v8_str("Fun"), cons).FromJust()); Local<Value> value = CompileRun( "function test() {" " try {" @@ -9960,7 +11239,7 @@ THREADED_TEST(FunctionDescriptorException) { " return 4;" "}" "test();"); - CHECK_EQ(0, value->Int32Value()); + CHECK_EQ(0, value->Int32Value(context.local()).FromJust()); } @@ -9980,10 +11259,22 @@ THREADED_TEST(EvalAliasedDynamic) { "var x = new Object();" "x.eval = function(x) { return 1; };" "result3 = f(x);"); - script->Run(); - CHECK_EQ(2, current->Global()->Get(v8_str("result1"))->Int32Value()); - CHECK_EQ(0, current->Global()->Get(v8_str("result2"))->Int32Value()); - CHECK_EQ(1, current->Global()->Get(v8_str("result3"))->Int32Value()); + script->Run(current.local()).ToLocalChecked(); + CHECK_EQ(2, current->Global() + ->Get(current.local(), v8_str("result1")) + .ToLocalChecked() + ->Int32Value(current.local()) + .FromJust()); + CHECK_EQ(0, current->Global() + ->Get(current.local(), v8_str("result2")) + .ToLocalChecked() + ->Int32Value(current.local()) + .FromJust()); + CHECK_EQ(1, current->Global() + ->Get(current.local(), v8_str("result3")) + .ToLocalChecked() + ->Int32Value(current.local()) + .FromJust()); v8::TryCatch try_catch(current->GetIsolate()); script = v8_compile( @@ -9992,9 +11283,13 @@ THREADED_TEST(EvalAliasedDynamic) { " with (x) { return eval('bar'); }" "}" "result4 = f(this)"); - script->Run(); + script->Run(current.local()).ToLocalChecked(); CHECK(!try_catch.HasCaught()); - CHECK_EQ(2, current->Global()->Get(v8_str("result4"))->Int32Value()); + CHECK_EQ(2, current->Global() + ->Get(current.local(), v8_str("result4")) + .ToLocalChecked() + ->Int32Value(current.local()) + .FromJust()); try_catch.Reset(); } @@ -10010,27 +11305,34 @@ THREADED_TEST(CrossEval) { current->SetSecurityToken(token); // Set up reference from current to other. - current->Global()->Set(v8_str("other"), other->Global()); + CHECK(current->Global() + ->Set(current.local(), v8_str("other"), other->Global()) + .FromJust()); // Check that new variables are introduced in other context. Local<Script> script = v8_compile("other.eval('var foo = 1234')"); - script->Run(); - Local<Value> foo = other->Global()->Get(v8_str("foo")); - CHECK_EQ(1234, foo->Int32Value()); - CHECK(!current->Global()->Has(v8_str("foo"))); + script->Run(current.local()).ToLocalChecked(); + Local<Value> foo = + other->Global()->Get(current.local(), v8_str("foo")).ToLocalChecked(); + CHECK_EQ(1234, foo->Int32Value(other.local()).FromJust()); + CHECK(!current->Global()->Has(current.local(), v8_str("foo")).FromJust()); // Check that writing to non-existing properties introduces them in // the other context. script = v8_compile("other.eval('na = 1234')"); - script->Run(); - CHECK_EQ(1234, other->Global()->Get(v8_str("na"))->Int32Value()); - CHECK(!current->Global()->Has(v8_str("na"))); + script->Run(current.local()).ToLocalChecked(); + CHECK_EQ(1234, other->Global() + ->Get(current.local(), v8_str("na")) + .ToLocalChecked() + ->Int32Value(other.local()) + .FromJust()); + CHECK(!current->Global()->Has(current.local(), v8_str("na")).FromJust()); // Check that global variables in current context are not visible in other // context. v8::TryCatch try_catch(CcTest::isolate()); script = v8_compile("var bar = 42; other.eval('bar');"); - Local<Value> result = script->Run(); + CHECK(script->Run(current.local()).IsEmpty()); CHECK(try_catch.HasCaught()); try_catch.Reset(); @@ -10041,36 +11343,43 @@ THREADED_TEST(CrossEval) { " var baz = 87;" " return other.eval('baz');" "})();"); - result = script->Run(); + CHECK(script->Run(current.local()).IsEmpty()); CHECK(try_catch.HasCaught()); try_catch.Reset(); // Check that global variables in the other environment are visible // when evaluting code. - other->Global()->Set(v8_str("bis"), v8_num(1234)); + CHECK(other->Global() + ->Set(other.local(), v8_str("bis"), v8_num(1234)) + .FromJust()); script = v8_compile("other.eval('bis')"); - CHECK_EQ(1234, script->Run()->Int32Value()); + CHECK_EQ(1234, script->Run(current.local()) + .ToLocalChecked() + ->Int32Value(current.local()) + .FromJust()); CHECK(!try_catch.HasCaught()); // Check that the 'this' pointer points to the global object evaluating // code. - other->Global()->Set(v8_str("t"), other->Global()); + CHECK(other->Global() + ->Set(current.local(), v8_str("t"), other->Global()) + .FromJust()); script = v8_compile("other.eval('this == t')"); - result = script->Run(); + Local<Value> result = script->Run(current.local()).ToLocalChecked(); CHECK(result->IsTrue()); CHECK(!try_catch.HasCaught()); // Check that variables introduced in with-statement are not visible in // other context. script = v8_compile("with({x:2}){other.eval('x')}"); - result = script->Run(); + CHECK(script->Run(current.local()).IsEmpty()); CHECK(try_catch.HasCaught()); try_catch.Reset(); // Check that you cannot use 'eval.call' with another object than the // current global object. script = v8_compile("other.y = 1; eval.call(other, 'y')"); - result = script->Run(); + CHECK(script->Run(current.local()).IsEmpty()); CHECK(try_catch.HasCaught()); } @@ -10086,7 +11395,7 @@ THREADED_TEST(EvalInDetachedGlobal) { // Set up function in context0 that uses eval from context0. context0->Enter(); - v8::Handle<v8::Value> fun = CompileRun( + v8::Local<v8::Value> fun = CompileRun( "var x = 42;" "(function() {" " var e = eval;" @@ -10098,13 +11407,13 @@ THREADED_TEST(EvalInDetachedGlobal) { // detaching the global. Before detaching, the call succeeds and // after detaching and exception is thrown. context1->Enter(); - context1->Global()->Set(v8_str("fun"), fun); - v8::Handle<v8::Value> x_value = CompileRun("fun('x')"); - CHECK_EQ(42, x_value->Int32Value()); + CHECK(context1->Global()->Set(context1, v8_str("fun"), fun).FromJust()); + v8::Local<v8::Value> x_value = CompileRun("fun('x')"); + CHECK_EQ(42, x_value->Int32Value(context1).FromJust()); context0->DetachGlobal(); v8::TryCatch catcher(isolate); x_value = CompileRun("fun('x')"); - CHECK_EQ(42, x_value->Int32Value()); + CHECK_EQ(42, x_value->Int32Value(context1).FromJust()); context1->Exit(); } @@ -10119,12 +11428,14 @@ THREADED_TEST(CrossLazyLoad) { current->SetSecurityToken(token); // Set up reference from current to other. - current->Global()->Set(v8_str("other"), other->Global()); + CHECK(current->Global() + ->Set(current.local(), v8_str("other"), other->Global()) + .FromJust()); // Trigger lazy loading in other context. Local<Script> script = v8_compile("other.eval('new Date(42)')"); - Local<Value> value = script->Run(); - CHECK_EQ(42.0, value->NumberValue()); + Local<Value> value = script->Run(current.local()).ToLocalChecked(); + CHECK_EQ(42.0, value->NumberValue(current.local()).FromJust()); } @@ -10132,7 +11443,10 @@ static void call_as_function(const v8::FunctionCallbackInfo<v8::Value>& args) { ApiTestFuzzer::Fuzz(); if (args.IsConstructCall()) { if (args[0]->IsInt32()) { - args.GetReturnValue().Set(v8_num(-args[0]->Int32Value())); + args.GetReturnValue().Set( + v8_num(-args[0] + ->Int32Value(args.GetIsolate()->GetCurrentContext()) + .FromJust())); return; } } @@ -10158,63 +11472,74 @@ THREADED_TEST(CallAsFunction) { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); Local<ObjectTemplate> instance_template = t->InstanceTemplate(); instance_template->SetCallAsFunctionHandler(call_as_function); - Local<v8::Object> instance = t->GetFunction()->NewInstance(); - context->Global()->Set(v8_str("obj"), instance); + Local<v8::Object> instance = t->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj"), instance) + .FromJust()); v8::TryCatch try_catch(isolate); Local<Value> value; CHECK(!try_catch.HasCaught()); value = CompileRun("obj(42)"); CHECK(!try_catch.HasCaught()); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(context.local()).FromJust()); value = CompileRun("(function(o){return o(49)})(obj)"); CHECK(!try_catch.HasCaught()); - CHECK_EQ(49, value->Int32Value()); + CHECK_EQ(49, value->Int32Value(context.local()).FromJust()); // test special case of call as function value = CompileRun("[obj]['0'](45)"); CHECK(!try_catch.HasCaught()); - CHECK_EQ(45, value->Int32Value()); + CHECK_EQ(45, value->Int32Value(context.local()).FromJust()); value = CompileRun( "obj.call = Function.prototype.call;" "obj.call(null, 87)"); CHECK(!try_catch.HasCaught()); - CHECK_EQ(87, value->Int32Value()); + CHECK_EQ(87, value->Int32Value(context.local()).FromJust()); // Regression tests for bug #1116356: Calling call through call/apply // must work for non-function receivers. const char* apply_99 = "Function.prototype.call.apply(obj, [this, 99])"; value = CompileRun(apply_99); CHECK(!try_catch.HasCaught()); - CHECK_EQ(99, value->Int32Value()); + CHECK_EQ(99, value->Int32Value(context.local()).FromJust()); const char* call_17 = "Function.prototype.call.call(obj, this, 17)"; value = CompileRun(call_17); CHECK(!try_catch.HasCaught()); - CHECK_EQ(17, value->Int32Value()); + CHECK_EQ(17, value->Int32Value(context.local()).FromJust()); // Check that the call-as-function handler can be called through // new. value = CompileRun("new obj(43)"); CHECK(!try_catch.HasCaught()); - CHECK_EQ(-43, value->Int32Value()); + CHECK_EQ(-43, value->Int32Value(context.local()).FromJust()); // Check that the call-as-function handler can be called through // the API. - v8::Handle<Value> args[] = {v8_num(28)}; - value = instance->CallAsFunction(instance, 1, args); + v8::Local<Value> args[] = {v8_num(28)}; + value = instance->CallAsFunction(context.local(), instance, 1, args) + .ToLocalChecked(); CHECK(!try_catch.HasCaught()); - CHECK_EQ(28, value->Int32Value()); + CHECK_EQ(28, value->Int32Value(context.local()).FromJust()); } { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); Local<ObjectTemplate> instance_template(t->InstanceTemplate()); USE(instance_template); - Local<v8::Object> instance = t->GetFunction()->NewInstance(); - context->Global()->Set(v8_str("obj2"), instance); + Local<v8::Object> instance = t->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj2"), instance) + .FromJust()); v8::TryCatch try_catch(isolate); Local<Value> value; CHECK(!try_catch.HasCaught()); @@ -10230,9 +11555,9 @@ THREADED_TEST(CallAsFunction) { // Call an object without call-as-function handler through the API value = CompileRun("obj2(28)"); - v8::Handle<Value> args[] = {v8_num(28)}; - value = instance->CallAsFunction(instance, 1, args); - CHECK(value.IsEmpty()); + v8::Local<Value> args[] = {v8_num(28)}; + CHECK( + instance->CallAsFunction(context.local(), instance, 1, args).IsEmpty()); CHECK(try_catch.HasCaught()); String::Utf8Value exception_value2(try_catch.Exception()); CHECK_EQ(0, @@ -10244,8 +11569,13 @@ THREADED_TEST(CallAsFunction) { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); Local<ObjectTemplate> instance_template = t->InstanceTemplate(); instance_template->SetCallAsFunctionHandler(ThrowValue); - Local<v8::Object> instance = t->GetFunction()->NewInstance(); - context->Global()->Set(v8_str("obj3"), instance); + Local<v8::Object> instance = t->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj3"), instance) + .FromJust()); v8::TryCatch try_catch(isolate); Local<Value> value; CHECK(!try_catch.HasCaught()); @@ -10257,8 +11587,9 @@ THREADED_TEST(CallAsFunction) { CHECK_EQ(0, strcmp("22", *exception_value1)); try_catch.Reset(); - v8::Handle<Value> args[] = {v8_num(23)}; - value = instance->CallAsFunction(instance, 1, args); + v8::Local<Value> args[] = {v8_num(23)}; + CHECK( + instance->CallAsFunction(context.local(), instance, 1, args).IsEmpty()); CHECK(try_catch.HasCaught()); String::Utf8Value exception_value2(try_catch.Exception()); CHECK_EQ(0, strcmp("23", *exception_value2)); @@ -10269,18 +11600,31 @@ THREADED_TEST(CallAsFunction) { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); Local<ObjectTemplate> instance_template = t->InstanceTemplate(); instance_template->SetCallAsFunctionHandler(ReturnThis); - Local<v8::Object> instance = t->GetFunction()->NewInstance(); + Local<v8::Object> instance = t->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); Local<v8::Value> a1 = - instance->CallAsFunction(v8::Undefined(isolate), 0, NULL); + instance->CallAsFunction(context.local(), v8::Undefined(isolate), 0, + NULL) + .ToLocalChecked(); CHECK(a1->StrictEquals(instance)); - Local<v8::Value> a2 = instance->CallAsFunction(v8::Null(isolate), 0, NULL); + Local<v8::Value> a2 = + instance->CallAsFunction(context.local(), v8::Null(isolate), 0, NULL) + .ToLocalChecked(); CHECK(a2->StrictEquals(instance)); - Local<v8::Value> a3 = instance->CallAsFunction(v8_num(42), 0, NULL); + Local<v8::Value> a3 = + instance->CallAsFunction(context.local(), v8_num(42), 0, NULL) + .ToLocalChecked(); CHECK(a3->StrictEquals(instance)); - Local<v8::Value> a4 = instance->CallAsFunction(v8_str("hello"), 0, NULL); + Local<v8::Value> a4 = + instance->CallAsFunction(context.local(), v8_str("hello"), 0, NULL) + .ToLocalChecked(); CHECK(a4->StrictEquals(instance)); - Local<v8::Value> a5 = instance->CallAsFunction(v8::True(isolate), 0, NULL); + Local<v8::Value> a5 = + instance->CallAsFunction(context.local(), v8::True(isolate), 0, NULL) + .ToLocalChecked(); CHECK(a5->StrictEquals(instance)); } @@ -10294,41 +11638,65 @@ THREADED_TEST(CallAsFunction) { " return this;" "}"); Local<Function> ReturnThisSloppy = Local<Function>::Cast( - context->Global()->Get(v8_str("ReturnThisSloppy"))); + context->Global() + ->Get(context.local(), v8_str("ReturnThisSloppy")) + .ToLocalChecked()); Local<Function> ReturnThisStrict = Local<Function>::Cast( - context->Global()->Get(v8_str("ReturnThisStrict"))); + context->Global() + ->Get(context.local(), v8_str("ReturnThisStrict")) + .ToLocalChecked()); Local<v8::Value> a1 = - ReturnThisSloppy->CallAsFunction(v8::Undefined(isolate), 0, NULL); + ReturnThisSloppy->CallAsFunction(context.local(), + v8::Undefined(isolate), 0, NULL) + .ToLocalChecked(); CHECK(a1->StrictEquals(context->Global())); Local<v8::Value> a2 = - ReturnThisSloppy->CallAsFunction(v8::Null(isolate), 0, NULL); + ReturnThisSloppy->CallAsFunction(context.local(), v8::Null(isolate), 0, + NULL) + .ToLocalChecked(); CHECK(a2->StrictEquals(context->Global())); - Local<v8::Value> a3 = ReturnThisSloppy->CallAsFunction(v8_num(42), 0, NULL); + Local<v8::Value> a3 = + ReturnThisSloppy->CallAsFunction(context.local(), v8_num(42), 0, NULL) + .ToLocalChecked(); CHECK(a3->IsNumberObject()); CHECK_EQ(42.0, a3.As<v8::NumberObject>()->ValueOf()); Local<v8::Value> a4 = - ReturnThisSloppy->CallAsFunction(v8_str("hello"), 0, NULL); + ReturnThisSloppy->CallAsFunction(context.local(), v8_str("hello"), 0, + NULL) + .ToLocalChecked(); CHECK(a4->IsStringObject()); CHECK(a4.As<v8::StringObject>()->ValueOf()->StrictEquals(v8_str("hello"))); Local<v8::Value> a5 = - ReturnThisSloppy->CallAsFunction(v8::True(isolate), 0, NULL); + ReturnThisSloppy->CallAsFunction(context.local(), v8::True(isolate), 0, + NULL) + .ToLocalChecked(); CHECK(a5->IsBooleanObject()); CHECK(a5.As<v8::BooleanObject>()->ValueOf()); Local<v8::Value> a6 = - ReturnThisStrict->CallAsFunction(v8::Undefined(isolate), 0, NULL); + ReturnThisStrict->CallAsFunction(context.local(), + v8::Undefined(isolate), 0, NULL) + .ToLocalChecked(); CHECK(a6->IsUndefined()); Local<v8::Value> a7 = - ReturnThisStrict->CallAsFunction(v8::Null(isolate), 0, NULL); + ReturnThisStrict->CallAsFunction(context.local(), v8::Null(isolate), 0, + NULL) + .ToLocalChecked(); CHECK(a7->IsNull()); - Local<v8::Value> a8 = ReturnThisStrict->CallAsFunction(v8_num(42), 0, NULL); + Local<v8::Value> a8 = + ReturnThisStrict->CallAsFunction(context.local(), v8_num(42), 0, NULL) + .ToLocalChecked(); CHECK(a8->StrictEquals(v8_num(42))); Local<v8::Value> a9 = - ReturnThisStrict->CallAsFunction(v8_str("hello"), 0, NULL); + ReturnThisStrict->CallAsFunction(context.local(), v8_str("hello"), 0, + NULL) + .ToLocalChecked(); CHECK(a9->StrictEquals(v8_str("hello"))); Local<v8::Value> a10 = - ReturnThisStrict->CallAsFunction(v8::True(isolate), 0, NULL); + ReturnThisStrict->CallAsFunction(context.local(), v8::True(isolate), 0, + NULL) + .ToLocalChecked(); CHECK(a10->StrictEquals(v8::True(isolate))); } } @@ -10343,7 +11711,8 @@ THREADED_TEST(CallableObject) { { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); instance_template->SetCallAsFunctionHandler(call_as_function); - Local<Object> instance = instance_template->NewInstance(); + Local<Object> instance = + instance_template->NewInstance(context.local()).ToLocalChecked(); v8::TryCatch try_catch(isolate); CHECK(instance->IsCallable()); @@ -10352,7 +11721,8 @@ THREADED_TEST(CallableObject) { { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); - Local<Object> instance = instance_template->NewInstance(); + Local<Object> instance = + instance_template->NewInstance(context.local()).ToLocalChecked(); v8::TryCatch try_catch(isolate); CHECK(!instance->IsCallable()); @@ -10362,7 +11732,8 @@ THREADED_TEST(CallableObject) { { Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate, call_as_function); - Local<Function> function = function_template->GetFunction(); + Local<Function> function = + function_template->GetFunction(context.local()).ToLocalChecked(); Local<Object> instance = function; v8::TryCatch try_catch(isolate); @@ -10372,7 +11743,8 @@ THREADED_TEST(CallableObject) { { Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate); - Local<Function> function = function_template->GetFunction(); + Local<Function> function = + function_template->GetFunction(context.local()).ToLocalChecked(); Local<Object> instance = function; v8::TryCatch try_catch(isolate); @@ -10489,9 +11861,14 @@ static void FastApiCallback_TrivialSignature( CheckReturnValue(args, FUNCTION_ADDR(FastApiCallback_TrivialSignature)); v8::Isolate* isolate = CcTest::isolate(); CHECK_EQ(isolate, args.GetIsolate()); - CHECK(args.This()->Equals(args.Holder())); - CHECK(args.Data()->Equals(v8_str("method_data"))); - args.GetReturnValue().Set(args[0]->Int32Value() + 1); + CHECK(args.This() + ->Equals(isolate->GetCurrentContext(), args.Holder()) + .FromJust()); + CHECK(args.Data() + ->Equals(isolate->GetCurrentContext(), v8_str("method_data")) + .FromJust()); + args.GetReturnValue().Set( + args[0]->Int32Value(isolate->GetCurrentContext()).FromJust() + 1); } static void FastApiCallback_SimpleSignature( @@ -10500,12 +11877,20 @@ static void FastApiCallback_SimpleSignature( CheckReturnValue(args, FUNCTION_ADDR(FastApiCallback_SimpleSignature)); v8::Isolate* isolate = CcTest::isolate(); CHECK_EQ(isolate, args.GetIsolate()); - CHECK(args.This()->GetPrototype()->Equals(args.Holder())); - CHECK(args.Data()->Equals(v8_str("method_data"))); + CHECK(args.This() + ->GetPrototype() + ->Equals(isolate->GetCurrentContext(), args.Holder()) + .FromJust()); + CHECK(args.Data() + ->Equals(isolate->GetCurrentContext(), v8_str("method_data")) + .FromJust()); // Note, we're using HasRealNamedProperty instead of Has to avoid // invoking the interceptor again. - CHECK(args.Holder()->HasRealNamedProperty(v8_str("foo"))); - args.GetReturnValue().Set(args[0]->Int32Value() + 1); + CHECK(args.Holder() + ->HasRealNamedProperty(isolate->GetCurrentContext(), v8_str("foo")) + .FromJust()); + args.GetReturnValue().Set( + args[0]->Int32Value(isolate->GetCurrentContext()).FromJust() + 1); } @@ -10534,13 +11919,16 @@ THREADED_TEST(CallICFastApi_DirectCall_GCMoveStub) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> nativeobject_templ = + v8::Local<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New(isolate); nativeobject_templ->Set(isolate, "callback", v8::FunctionTemplate::New(isolate, DirectApiCallback)); - v8::Local<v8::Object> nativeobject_obj = nativeobject_templ->NewInstance(); - context->Global()->Set(v8_str("nativeobject"), nativeobject_obj); + v8::Local<v8::Object> nativeobject_obj = + nativeobject_templ->NewInstance(context.local()).ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("nativeobject"), nativeobject_obj) + .FromJust()); // call the api function multiple times to ensure direct call stub creation. CompileRun( "function f() {" @@ -10562,15 +11950,18 @@ THREADED_TEST(CallICFastApi_DirectCall_Throw) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> nativeobject_templ = + v8::Local<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New(isolate); nativeobject_templ->Set(isolate, "callback", v8::FunctionTemplate::New(isolate, ThrowingDirectApiCallback)); - v8::Local<v8::Object> nativeobject_obj = nativeobject_templ->NewInstance(); - context->Global()->Set(v8_str("nativeobject"), nativeobject_obj); + v8::Local<v8::Object> nativeobject_obj = + nativeobject_templ->NewInstance(context.local()).ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("nativeobject"), nativeobject_obj) + .FromJust()); // call the api function multiple times to ensure direct call stub creation. - v8::Handle<Value> result = CompileRun( + v8::Local<Value> result = CompileRun( "var result = '';" "function f() {" " for (var i = 1; i <= 5; i++) {" @@ -10578,14 +11969,14 @@ THREADED_TEST(CallICFastApi_DirectCall_Throw) { " }" "}" "f(); result;"); - CHECK(v8_str("ggggg")->Equals(result)); + CHECK(v8_str("ggggg")->Equals(context.local(), result).FromJust()); } static int p_getter_count_3; -static Handle<Value> DoDirectGetter() { +static Local<Value> DoDirectGetter() { if (++p_getter_count_3 % 3 == 0) { CcTest::heap()->CollectAllGarbage(); GenerateSomeGarbage(); @@ -10607,17 +11998,22 @@ static void LoadICFastApi_DirectCall_GCMoveStub(Accessor accessor) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("p1"), accessor); - context->Global()->Set(v8_str("o1"), obj->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o1"), + obj->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); p_getter_count_3 = 0; - v8::Handle<v8::Value> result = CompileRun( + v8::Local<v8::Value> result = CompileRun( "function f() {" " for (var i = 0; i < 30; i++) o1.p1;" " return o1.p1" "}" "f();"); - CHECK(v8_str("Direct Getter Result")->Equals(result)); + CHECK(v8_str("Direct Getter Result") + ->Equals(context.local(), result) + .FromJust()); CHECK_EQ(31, p_getter_count_3); } @@ -10638,16 +12034,19 @@ THREADED_TEST(LoadICFastApi_DirectCall_Throw) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(isolate); obj->SetAccessor(v8_str("p1"), ThrowingDirectGetterCallback); - context->Global()->Set(v8_str("o1"), obj->NewInstance()); - v8::Handle<Value> result = CompileRun( + CHECK(context->Global() + ->Set(context.local(), v8_str("o1"), + obj->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); + v8::Local<Value> result = CompileRun( "var result = '';" "for (var i = 0; i < 5; i++) {" " try { o1.p1; } catch (e) { result += e; }" "}" "result;"); - CHECK(v8_str("ggggg")->Equals(result)); + CHECK(v8_str("ggggg")->Equals(context.local(), result).FromJust()); } @@ -10655,29 +12054,35 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_TrivialSignature) { int interceptor_call_count = 0; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> fun_templ = + v8::Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> method_templ = - v8::FunctionTemplate::New(isolate, - FastApiCallback_TrivialSignature, - v8_str("method_data"), - v8::Handle<v8::Signature>()); - v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); + v8::Local<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + isolate, FastApiCallback_TrivialSignature, v8_str("method_data"), + v8::Local<v8::Signature>()); + v8::Local<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); - v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); + v8::Local<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); templ->SetHandler(v8::NamedPropertyHandlerConfiguration( InterceptorCallICFastApi, NULL, NULL, NULL, NULL, v8::External::New(isolate, &interceptor_call_count))); LocalContext context; - v8::Handle<v8::Function> fun = fun_templ->GetFunction(); + v8::Local<v8::Function> fun = + fun_templ->GetFunction(context.local()).ToLocalChecked(); GenerateSomeGarbage(); - context->Global()->Set(v8_str("o"), fun->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), + fun->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun( "var result = 0;" "for (var i = 0; i < 100; i++) {" " result = o.method(41);" "}"); - CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(42, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); CHECK_EQ(100, interceptor_call_count); } @@ -10686,22 +12091,26 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature) { int interceptor_call_count = 0; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> fun_templ = + v8::Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + v8::Local<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), v8::Signature::New(isolate, fun_templ)); - v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); + v8::Local<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); - v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); + v8::Local<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); templ->SetHandler(v8::NamedPropertyHandlerConfiguration( InterceptorCallICFastApi, NULL, NULL, NULL, NULL, v8::External::New(isolate, &interceptor_call_count))); LocalContext context; - v8::Handle<v8::Function> fun = fun_templ->GetFunction(); + v8::Local<v8::Function> fun = + fun_templ->GetFunction(context.local()).ToLocalChecked(); GenerateSomeGarbage(); - context->Global()->Set(v8_str("o"), fun->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), + fun->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun( "o.foo = 17;" "var receiver = {};" @@ -10710,7 +12119,11 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature) { "for (var i = 0; i < 100; i++) {" " result = receiver.method(41);" "}"); - CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(42, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); CHECK_EQ(100, interceptor_call_count); } @@ -10719,22 +12132,26 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) { int interceptor_call_count = 0; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> fun_templ = + v8::Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + v8::Local<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), v8::Signature::New(isolate, fun_templ)); - v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); + v8::Local<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); - v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); + v8::Local<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); templ->SetHandler(v8::NamedPropertyHandlerConfiguration( InterceptorCallICFastApi, NULL, NULL, NULL, NULL, v8::External::New(isolate, &interceptor_call_count))); LocalContext context; - v8::Handle<v8::Function> fun = fun_templ->GetFunction(); + v8::Local<v8::Function> fun = + fun_templ->GetFunction(context.local()).ToLocalChecked(); GenerateSomeGarbage(); - context->Global()->Set(v8_str("o"), fun->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), + fun->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun( "o.foo = 17;" "var receiver = {};" @@ -10748,8 +12165,16 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) { " receiver = {method: function(x) { return x - 1 }};" " }" "}"); - CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); + CHECK_EQ(40, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(42, context->Global() + ->Get(context.local(), v8_str("saved_result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); CHECK_GE(interceptor_call_count, 50); } @@ -10758,22 +12183,26 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) { int interceptor_call_count = 0; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> fun_templ = + v8::Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + v8::Local<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), v8::Signature::New(isolate, fun_templ)); - v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); + v8::Local<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); - v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); + v8::Local<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); templ->SetHandler(v8::NamedPropertyHandlerConfiguration( InterceptorCallICFastApi, NULL, NULL, NULL, NULL, v8::External::New(isolate, &interceptor_call_count))); LocalContext context; - v8::Handle<v8::Function> fun = fun_templ->GetFunction(); + v8::Local<v8::Function> fun = + fun_templ->GetFunction(context.local()).ToLocalChecked(); GenerateSomeGarbage(); - context->Global()->Set(v8_str("o"), fun->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), + fun->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun( "o.foo = 17;" "var receiver = {};" @@ -10787,8 +12216,16 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) { " o.method = function(x) { return x - 1 };" " }" "}"); - CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); + CHECK_EQ(40, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(42, context->Global() + ->Get(context.local(), v8_str("saved_result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); CHECK_GE(interceptor_call_count, 50); } @@ -10797,22 +12234,26 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) { int interceptor_call_count = 0; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> fun_templ = + v8::Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + v8::Local<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), v8::Signature::New(isolate, fun_templ)); - v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); + v8::Local<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); - v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); + v8::Local<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); templ->SetHandler(v8::NamedPropertyHandlerConfiguration( InterceptorCallICFastApi, NULL, NULL, NULL, NULL, v8::External::New(isolate, &interceptor_call_count))); LocalContext context; - v8::Handle<v8::Function> fun = fun_templ->GetFunction(); + v8::Local<v8::Function> fun = + fun_templ->GetFunction(context.local()).ToLocalChecked(); GenerateSomeGarbage(); - context->Global()->Set(v8_str("o"), fun->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), + fun->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); v8::TryCatch try_catch(isolate); CompileRun( "o.foo = 17;" @@ -10829,9 +12270,17 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) { "}"); CHECK(try_catch.HasCaught()); // TODO(verwaest): Adjust message. - CHECK(v8_str("TypeError: receiver.method is not a function") - ->Equals(try_catch.Exception()->ToString(isolate))); - CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); + CHECK( + v8_str("TypeError: receiver.method is not a function") + ->Equals( + context.local(), + try_catch.Exception()->ToString(context.local()).ToLocalChecked()) + .FromJust()); + CHECK_EQ(42, context->Global() + ->Get(context.local(), v8_str("saved_result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); CHECK_GE(interceptor_call_count, 50); } @@ -10840,22 +12289,26 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) { int interceptor_call_count = 0; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> fun_templ = + v8::Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + v8::Local<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), v8::Signature::New(isolate, fun_templ)); - v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); + v8::Local<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); - v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); + v8::Local<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate(); templ->SetHandler(v8::NamedPropertyHandlerConfiguration( InterceptorCallICFastApi, NULL, NULL, NULL, NULL, v8::External::New(isolate, &interceptor_call_count))); LocalContext context; - v8::Handle<v8::Function> fun = fun_templ->GetFunction(); + v8::Local<v8::Function> fun = + fun_templ->GetFunction(context.local()).ToLocalChecked(); GenerateSomeGarbage(); - context->Global()->Set(v8_str("o"), fun->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), + fun->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); v8::TryCatch try_catch(isolate); CompileRun( "o.foo = 17;" @@ -10871,9 +12324,17 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) { " }" "}"); CHECK(try_catch.HasCaught()); - CHECK(v8_str("TypeError: Illegal invocation") - ->Equals(try_catch.Exception()->ToString(isolate))); - CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); + CHECK( + v8_str("TypeError: Illegal invocation") + ->Equals( + context.local(), + try_catch.Exception()->ToString(context.local()).ToLocalChecked()) + .FromJust()); + CHECK_EQ(42, context->Global() + ->Get(context.local(), v8_str("saved_result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); CHECK_GE(interceptor_call_count, 50); } @@ -10881,48 +12342,58 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) { THREADED_PROFILED_TEST(CallICFastApi_TrivialSignature) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> fun_templ = + v8::Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> method_templ = - v8::FunctionTemplate::New(isolate, - FastApiCallback_TrivialSignature, - v8_str("method_data"), - v8::Handle<v8::Signature>()); - v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); + v8::Local<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + isolate, FastApiCallback_TrivialSignature, v8_str("method_data"), + v8::Local<v8::Signature>()); + v8::Local<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); - v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); + v8::Local<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); USE(templ); LocalContext context; - v8::Handle<v8::Function> fun = fun_templ->GetFunction(); + v8::Local<v8::Function> fun = + fun_templ->GetFunction(context.local()).ToLocalChecked(); GenerateSomeGarbage(); - context->Global()->Set(v8_str("o"), fun->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), + fun->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun( "var result = 0;" "for (var i = 0; i < 100; i++) {" " result = o.method(41);" "}"); - CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(42, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> fun_templ = + v8::Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + v8::Local<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), v8::Signature::New(isolate, fun_templ)); - v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); + v8::Local<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); - v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); + v8::Local<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); CHECK(!templ.IsEmpty()); LocalContext context; - v8::Handle<v8::Function> fun = fun_templ->GetFunction(); + v8::Local<v8::Function> fun = + fun_templ->GetFunction(context.local()).ToLocalChecked(); GenerateSomeGarbage(); - context->Global()->Set(v8_str("o"), fun->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), + fun->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun( "o.foo = 17;" "var receiver = {};" @@ -10932,27 +12403,35 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature) { " result = receiver.method(41);" "}"); - CHECK_EQ(42, context->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(42, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss1) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> fun_templ = + v8::Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + v8::Local<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), v8::Signature::New(isolate, fun_templ)); - v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); + v8::Local<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); - v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); + v8::Local<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); CHECK(!templ.IsEmpty()); LocalContext context; - v8::Handle<v8::Function> fun = fun_templ->GetFunction(); + v8::Local<v8::Function> fun = + fun_templ->GetFunction(context.local()).ToLocalChecked(); GenerateSomeGarbage(); - context->Global()->Set(v8_str("o"), fun->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), + fun->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun( "o.foo = 17;" "var receiver = {};" @@ -10966,28 +12445,40 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss1) { " receiver = {method: function(x) { return x - 1 }};" " }" "}"); - CHECK_EQ(40, context->Global()->Get(v8_str("result"))->Int32Value()); - CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); + CHECK_EQ(40, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(42, context->Global() + ->Get(context.local(), v8_str("saved_result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss2) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> fun_templ = + v8::Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + v8::Local<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), v8::Signature::New(isolate, fun_templ)); - v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); + v8::Local<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); - v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); + v8::Local<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); CHECK(!templ.IsEmpty()); LocalContext context; - v8::Handle<v8::Function> fun = fun_templ->GetFunction(); + v8::Local<v8::Function> fun = + fun_templ->GetFunction(context.local()).ToLocalChecked(); GenerateSomeGarbage(); - context->Global()->Set(v8_str("o"), fun->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), + fun->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); v8::TryCatch try_catch(isolate); CompileRun( "o.foo = 17;" @@ -11004,29 +12495,41 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss2) { "}"); CHECK(try_catch.HasCaught()); // TODO(verwaest): Adjust message. - CHECK(v8_str("TypeError: receiver.method is not a function") - ->Equals(try_catch.Exception()->ToString(isolate))); - CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); + CHECK( + v8_str("TypeError: receiver.method is not a function") + ->Equals( + context.local(), + try_catch.Exception()->ToString(context.local()).ToLocalChecked()) + .FromJust()); + CHECK_EQ(42, context->Global() + ->Get(context.local(), v8_str("saved_result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_TypeError) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::FunctionTemplate> fun_templ = + v8::Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( + v8::Local<v8::FunctionTemplate> method_templ = v8::FunctionTemplate::New( isolate, FastApiCallback_SimpleSignature, v8_str("method_data"), v8::Signature::New(isolate, fun_templ)); - v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); + v8::Local<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); proto_templ->Set(v8_str("method"), method_templ); fun_templ->SetHiddenPrototype(true); - v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); + v8::Local<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate()); CHECK(!templ.IsEmpty()); LocalContext context; - v8::Handle<v8::Function> fun = fun_templ->GetFunction(); + v8::Local<v8::Function> fun = + fun_templ->GetFunction(context.local()).ToLocalChecked(); GenerateSomeGarbage(); - context->Global()->Set(v8_str("o"), fun->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), + fun->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); v8::TryCatch try_catch(isolate); CompileRun( "o.foo = 17;" @@ -11042,16 +12545,24 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_TypeError) { " }" "}"); CHECK(try_catch.HasCaught()); - CHECK(v8_str("TypeError: Illegal invocation") - ->Equals(try_catch.Exception()->ToString(isolate))); - CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value()); + CHECK( + v8_str("TypeError: Illegal invocation") + ->Equals( + context.local(), + try_catch.Exception()->ToString(context.local()).ToLocalChecked()) + .FromJust()); + CHECK_EQ(42, context->Global() + ->Get(context.local(), v8_str("saved_result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } static void ThrowingGetter(Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { ApiTestFuzzer::Fuzz(); - info.GetIsolate()->ThrowException(Handle<Value>()); + info.GetIsolate()->ThrowException(Local<Value>()); info.GetReturnValue().SetUndefined(); } @@ -11064,10 +12575,13 @@ THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) { Local<ObjectTemplate> instance_templ = templ->InstanceTemplate(); instance_templ->SetAccessor(v8_str("f"), ThrowingGetter); - Local<Object> instance = templ->GetFunction()->NewInstance(); + Local<Object> instance = templ->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); Local<Object> another = Object::New(context->GetIsolate()); - another->SetPrototype(instance); + CHECK(another->SetPrototype(context.local(), instance).FromJust()); Local<Object> with_js_getter = CompileRun( "o = {};\n" @@ -11077,49 +12591,53 @@ THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) { TryCatch try_catch(context->GetIsolate()); - Local<Value> result = instance->GetRealNamedProperty(v8_str("f")); + v8::MaybeLocal<Value> result = + instance->GetRealNamedProperty(context.local(), v8_str("f")); CHECK(try_catch.HasCaught()); try_catch.Reset(); CHECK(result.IsEmpty()); Maybe<PropertyAttribute> attr = - instance->GetRealNamedPropertyAttributes(v8_str("f")); + instance->GetRealNamedPropertyAttributes(context.local(), v8_str("f")); CHECK(!try_catch.HasCaught()); CHECK(Just(None) == attr); - result = another->GetRealNamedProperty(v8_str("f")); + result = another->GetRealNamedProperty(context.local(), v8_str("f")); CHECK(try_catch.HasCaught()); try_catch.Reset(); CHECK(result.IsEmpty()); - attr = another->GetRealNamedPropertyAttributes(v8_str("f")); + attr = another->GetRealNamedPropertyAttributes(context.local(), v8_str("f")); CHECK(!try_catch.HasCaught()); CHECK(Just(None) == attr); - result = another->GetRealNamedPropertyInPrototypeChain(v8_str("f")); + result = another->GetRealNamedPropertyInPrototypeChain(context.local(), + v8_str("f")); CHECK(try_catch.HasCaught()); try_catch.Reset(); CHECK(result.IsEmpty()); - attr = another->GetRealNamedPropertyAttributesInPrototypeChain(v8_str("f")); + attr = another->GetRealNamedPropertyAttributesInPrototypeChain( + context.local(), v8_str("f")); CHECK(!try_catch.HasCaught()); CHECK(Just(None) == attr); - result = another->Get(v8_str("f")); + result = another->Get(context.local(), v8_str("f")); CHECK(try_catch.HasCaught()); try_catch.Reset(); CHECK(result.IsEmpty()); - result = with_js_getter->GetRealNamedProperty(v8_str("f")); + result = with_js_getter->GetRealNamedProperty(context.local(), v8_str("f")); CHECK(try_catch.HasCaught()); try_catch.Reset(); CHECK(result.IsEmpty()); - attr = with_js_getter->GetRealNamedPropertyAttributes(v8_str("f")); + attr = with_js_getter->GetRealNamedPropertyAttributes(context.local(), + v8_str("f")); CHECK(!try_catch.HasCaught()); CHECK(Just(None) == attr); - result = with_js_getter->Get(v8_str("f")); + result = with_js_getter->Get(context.local(), v8_str("f")); CHECK(try_catch.HasCaught()); try_catch.Reset(); CHECK(result.IsEmpty()); @@ -11142,23 +12660,23 @@ static void ThrowingCallbackWithTryCatch( static int call_depth; -static void WithTryCatch(Handle<Message> message, Handle<Value> data) { +static void WithTryCatch(Local<Message> message, Local<Value> data) { TryCatch try_catch(CcTest::isolate()); } -static void ThrowFromJS(Handle<Message> message, Handle<Value> data) { +static void ThrowFromJS(Local<Message> message, Local<Value> data) { if (--call_depth) CompileRun("throw 'ThrowInJS';"); } -static void ThrowViaApi(Handle<Message> message, Handle<Value> data) { +static void ThrowViaApi(Local<Message> message, Local<Value> data) { if (--call_depth) CcTest::isolate()->ThrowException(v8_str("ThrowViaApi")); } -static void WebKitLike(Handle<Message> message, Handle<Value> data) { - Handle<String> errorMessageString = message->Get(); +static void WebKitLike(Local<Message> message, Local<Value> data) { + Local<String> errorMessageString = message->Get(); CHECK(!errorMessageString.IsEmpty()); message->GetStackTrace(); message->GetScriptOrigin().ResourceName(); @@ -11171,16 +12689,18 @@ THREADED_TEST(ExceptionsDoNotPropagatePastTryCatch) { HandleScope scope(isolate); Local<Function> func = - FunctionTemplate::New(isolate, - ThrowingCallbackWithTryCatch)->GetFunction(); - context->Global()->Set(v8_str("func"), func); + FunctionTemplate::New(isolate, ThrowingCallbackWithTryCatch) + ->GetFunction(context.local()) + .ToLocalChecked(); + CHECK( + context->Global()->Set(context.local(), v8_str("func"), func).FromJust()); MessageCallback callbacks[] = { NULL, WebKitLike, ThrowViaApi, ThrowFromJS, WithTryCatch }; for (unsigned i = 0; i < sizeof(callbacks)/sizeof(callbacks[0]); i++) { MessageCallback callback = callbacks[i]; if (callback != NULL) { - V8::AddMessageListener(callback); + isolate->AddMessageListener(callback); } // Some small number to control number of times message handler should // throw an exception. @@ -11190,7 +12710,7 @@ THREADED_TEST(ExceptionsDoNotPropagatePastTryCatch) { "try { func(); } catch(e) { thrown = true; }\n" "thrown\n"); if (callback != NULL) { - V8::RemoveMessageListeners(callback); + isolate->RemoveMessageListeners(callback); } } } @@ -11237,34 +12757,39 @@ THREADED_TEST(Overriding) { // so 'h' can be shadowed on the instance object. Local<ObjectTemplate> child_proto_templ = child_templ->PrototypeTemplate(); child_proto_templ->SetAccessor(v8_str("h"), ParentGetter, 0, - v8::Handle<Value>(), v8::DEFAULT, v8::ReadOnly); + v8::Local<Value>(), v8::DEFAULT, v8::ReadOnly); // Add 'i' as an accessor to the instance template with ReadOnly attributes // but the attribute does not have effect because it is duplicated with // NULL setter. child_instance_templ->SetAccessor(v8_str("i"), ChildGetter, 0, - v8::Handle<Value>(), v8::DEFAULT, v8::ReadOnly); - + v8::Local<Value>(), v8::DEFAULT, + v8::ReadOnly); // Instantiate the child template. - Local<v8::Object> instance = child_templ->GetFunction()->NewInstance(); + Local<v8::Object> instance = child_templ->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); // Check that the child function overrides the parent one. - context->Global()->Set(v8_str("o"), instance); - Local<Value> value = v8_compile("o.f")->Run(); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), instance) + .FromJust()); + Local<Value> value = v8_compile("o.f")->Run(context.local()).ToLocalChecked(); // Check that the 'g' that was added last is hit. - CHECK_EQ(42, value->Int32Value()); - value = v8_compile("o.g")->Run(); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(context.local()).FromJust()); + value = v8_compile("o.g")->Run(context.local()).ToLocalChecked(); + CHECK_EQ(42, value->Int32Value(context.local()).FromJust()); // Check that 'h' cannot be shadowed. - value = v8_compile("o.h = 3; o.h")->Run(); - CHECK_EQ(1, value->Int32Value()); + value = v8_compile("o.h = 3; o.h")->Run(context.local()).ToLocalChecked(); + CHECK_EQ(1, value->Int32Value(context.local()).FromJust()); // Check that 'i' cannot be shadowed or changed. - value = v8_compile("o.i = 3; o.i")->Run(); - CHECK_EQ(42, value->Int32Value()); + value = v8_compile("o.i = 3; o.i")->Run(context.local()).ToLocalChecked(); + CHECK_EQ(42, value->Int32Value(context.local()).FromJust()); } @@ -11285,11 +12810,14 @@ THREADED_TEST(IsConstructCall) { LocalContext context; - context->Global()->Set(v8_str("f"), templ->GetFunction()); - Local<Value> value = v8_compile("f()")->Run(); - CHECK(!value->BooleanValue()); - value = v8_compile("new f()")->Run(); - CHECK(value->BooleanValue()); + CHECK(context->Global() + ->Set(context.local(), v8_str("f"), + templ->GetFunction(context.local()).ToLocalChecked()) + .FromJust()); + Local<Value> value = v8_compile("f()")->Run(context.local()).ToLocalChecked(); + CHECK(!value->BooleanValue(context.local()).FromJust()); + value = v8_compile("new f()")->Run(context.local()).ToLocalChecked(); + CHECK(value->BooleanValue(context.local()).FromJust()); } @@ -11304,27 +12832,41 @@ THREADED_TEST(ObjectProtoToString) { Local<String> customized_tostring = v8_str("customized toString"); // Replace Object.prototype.toString - v8_compile("Object.prototype.toString = function() {" - " return 'customized toString';" - "}")->Run(); + v8_compile( + "Object.prototype.toString = function() {" + " return 'customized toString';" + "}") + ->Run(context.local()) + .ToLocalChecked(); // Normal ToString call should call replaced Object.prototype.toString - Local<v8::Object> instance = templ->GetFunction()->NewInstance(); - Local<String> value = instance->ToString(isolate); - CHECK(value->IsString() && value->Equals(customized_tostring)); + Local<v8::Object> instance = templ->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<String> value = instance->ToString(context.local()).ToLocalChecked(); + CHECK(value->IsString() && + value->Equals(context.local(), customized_tostring).FromJust()); // ObjectProtoToString should not call replace toString function. - value = instance->ObjectProtoToString(); - CHECK(value->IsString() && value->Equals(v8_str("[object MyClass]"))); + value = instance->ObjectProtoToString(context.local()).ToLocalChecked(); + CHECK(value->IsString() && + value->Equals(context.local(), v8_str("[object MyClass]")).FromJust()); // Check global - value = context->Global()->ObjectProtoToString(); - CHECK(value->IsString() && value->Equals(v8_str("[object global]"))); + value = + context->Global()->ObjectProtoToString(context.local()).ToLocalChecked(); + CHECK(value->IsString() && + value->Equals(context.local(), v8_str("[object global]")).FromJust()); // Check ordinary object - Local<Value> object = v8_compile("new Object()")->Run(); - value = object.As<v8::Object>()->ObjectProtoToString(); - CHECK(value->IsString() && value->Equals(v8_str("[object Object]"))); + Local<Value> object = + v8_compile("new Object()")->Run(context.local()).ToLocalChecked(); + value = object.As<v8::Object>() + ->ObjectProtoToString(context.local()) + .ToLocalChecked(); + CHECK(value->IsString() && + value->Equals(context.local(), v8_str("[object Object]")).FromJust()); } @@ -11346,33 +12888,48 @@ TEST(ObjectProtoToStringES6) { "}"); // Normal ToString call should call replaced Object.prototype.toString - Local<v8::Object> instance = templ->GetFunction()->NewInstance(); - Local<String> value = instance->ToString(isolate); - CHECK(value->IsString() && value->Equals(customized_tostring)); + Local<v8::Object> instance = templ->GetFunction(context.local()) + .ToLocalChecked() + ->NewInstance(context.local()) + .ToLocalChecked(); + Local<String> value = instance->ToString(context.local()).ToLocalChecked(); + CHECK(value->IsString() && + value->Equals(context.local(), customized_tostring).FromJust()); // ObjectProtoToString should not call replace toString function. - value = instance->ObjectProtoToString(); - CHECK(value->IsString() && value->Equals(v8_str("[object MyClass]"))); + value = instance->ObjectProtoToString(context.local()).ToLocalChecked(); + CHECK(value->IsString() && + value->Equals(context.local(), v8_str("[object MyClass]")).FromJust()); // Check global - value = context->Global()->ObjectProtoToString(); - CHECK(value->IsString() && value->Equals(v8_str("[object global]"))); + value = + context->Global()->ObjectProtoToString(context.local()).ToLocalChecked(); + CHECK(value->IsString() && + value->Equals(context.local(), v8_str("[object global]")).FromJust()); // Check ordinary object Local<Value> object = CompileRun("new Object()"); - value = object.As<v8::Object>()->ObjectProtoToString(); - CHECK(value->IsString() && value->Equals(v8_str("[object Object]"))); + value = object.As<v8::Object>() + ->ObjectProtoToString(context.local()) + .ToLocalChecked(); + CHECK(value->IsString() && + value->Equals(context.local(), v8_str("[object Object]")).FromJust()); // Check that ES6 semantics using @@toStringTag work Local<v8::Symbol> toStringTag = v8::Symbol::GetToStringTag(isolate); -#define TEST_TOSTRINGTAG(type, tag, expected) \ - do { \ - object = CompileRun("new " #type "()"); \ - object.As<v8::Object>()->Set(toStringTag, v8_str(#tag)); \ - value = object.As<v8::Object>()->ObjectProtoToString(); \ - CHECK(value->IsString() && \ - value->Equals(v8_str("[object " #expected "]"))); \ +#define TEST_TOSTRINGTAG(type, tag, expected) \ + do { \ + object = CompileRun("new " #type "()"); \ + CHECK(object.As<v8::Object>() \ + ->Set(context.local(), toStringTag, v8_str(#tag)) \ + .FromJust()); \ + value = object.As<v8::Object>() \ + ->ObjectProtoToString(context.local()) \ + .ToLocalChecked(); \ + CHECK(value->IsString() && \ + value->Equals(context.local(), v8_str("[object " #expected "]")) \ + .FromJust()); \ } while (0) TEST_TOSTRINGTAG(Array, Object, Object); @@ -11389,8 +12946,9 @@ TEST(ObjectProtoToStringES6) { #undef TEST_TOSTRINGTAG - Local<v8::RegExp> valueRegExp = v8::RegExp::New(v8_str("^$"), - v8::RegExp::kNone); + Local<v8::RegExp> valueRegExp = + v8::RegExp::New(context.local(), v8_str("^$"), v8::RegExp::kNone) + .ToLocalChecked(); Local<Value> valueNumber = v8_num(123); Local<v8::Symbol> valueSymbol = v8_symbol("TestSymbol"); Local<v8::Function> valueFunction = @@ -11399,13 +12957,18 @@ TEST(ObjectProtoToStringES6) { Local<v8::Primitive> valueNull = v8::Null(v8::Isolate::GetCurrent()); Local<v8::Primitive> valueUndef = v8::Undefined(v8::Isolate::GetCurrent()); -#define TEST_TOSTRINGTAG(type, tagValue, expected) \ - do { \ - object = CompileRun("new " #type "()"); \ - object.As<v8::Object>()->Set(toStringTag, tagValue); \ - value = object.As<v8::Object>()->ObjectProtoToString(); \ - CHECK(value->IsString() && \ - value->Equals(v8_str("[object " #expected "]"))); \ +#define TEST_TOSTRINGTAG(type, tagValue, expected) \ + do { \ + object = CompileRun("new " #type "()"); \ + CHECK(object.As<v8::Object>() \ + ->Set(context.local(), toStringTag, tagValue) \ + .FromJust()); \ + value = object.As<v8::Object>() \ + ->ObjectProtoToString(context.local()) \ + .ToLocalChecked(); \ + CHECK(value->IsString() && \ + value->Equals(context.local(), v8_str("[object " #expected "]")) \ + .FromJust()); \ } while (0) #define TEST_TOSTRINGTAG_TYPES(tagValue) \ @@ -11430,22 +12993,28 @@ TEST(ObjectProtoToStringES6) { // @@toStringTag getter throws Local<Value> obj = v8::Object::New(isolate); - obj.As<v8::Object>()->SetAccessor(toStringTag, ThrowingSymbolAccessorGetter); + obj.As<v8::Object>() + ->SetAccessor(context.local(), toStringTag, ThrowingSymbolAccessorGetter) + .FromJust(); { TryCatch try_catch(isolate); - value = obj.As<v8::Object>()->ObjectProtoToString(); - CHECK(value.IsEmpty()); + CHECK(obj.As<v8::Object>()->ObjectProtoToString(context.local()).IsEmpty()); CHECK(try_catch.HasCaught()); } // @@toStringTag getter does not throw obj = v8::Object::New(isolate); - obj.As<v8::Object>()->SetAccessor( - toStringTag, SymbolAccessorGetterReturnsDefault, 0, v8_str("Test")); + obj.As<v8::Object>() + ->SetAccessor(context.local(), toStringTag, + SymbolAccessorGetterReturnsDefault, 0, v8_str("Test")) + .FromJust(); { TryCatch try_catch(isolate); - value = obj.As<v8::Object>()->ObjectProtoToString(); - CHECK(value->IsString() && value->Equals(v8_str("[object Test]"))); + value = obj.As<v8::Object>() + ->ObjectProtoToString(context.local()) + .ToLocalChecked(); + CHECK(value->IsString() && + value->Equals(context.local(), v8_str("[object Test]")).FromJust()); CHECK(!try_catch.HasCaught()); } @@ -11453,8 +13022,11 @@ TEST(ObjectProtoToStringES6) { obj = CompileRun("obj = {}; obj[Symbol.toStringTag] = 'Test'; obj"); { TryCatch try_catch(isolate); - value = obj.As<v8::Object>()->ObjectProtoToString(); - CHECK(value->IsString() && value->Equals(v8_str("[object Test]"))); + value = obj.As<v8::Object>() + ->ObjectProtoToString(context.local()) + .ToLocalChecked(); + CHECK(value->IsString() && + value->Equals(context.local(), v8_str("[object Test]")).FromJust()); CHECK(!try_catch.HasCaught()); } @@ -11465,8 +13037,7 @@ TEST(ObjectProtoToStringES6) { "}); obj"); { TryCatch try_catch(isolate); - value = obj.As<v8::Object>()->ObjectProtoToString(); - CHECK(value.IsEmpty()); + CHECK(obj.As<v8::Object>()->ObjectProtoToString(context.local()).IsEmpty()); CHECK(try_catch.HasCaught()); } @@ -11477,8 +13048,11 @@ TEST(ObjectProtoToStringES6) { "}); obj"); { TryCatch try_catch(isolate); - value = obj.As<v8::Object>()->ObjectProtoToString(); - CHECK(value->IsString() && value->Equals(v8_str("[object Test]"))); + value = obj.As<v8::Object>() + ->ObjectProtoToString(context.local()) + .ToLocalChecked(); + CHECK(value->IsString() && + value->Equals(context.local(), v8_str("[object Test]")).FromJust()); CHECK(!try_catch.HasCaught()); } } @@ -11492,29 +13066,83 @@ THREADED_TEST(ObjectGetConstructorName) { "function Parent() {};" "function Child() {};" "Child.prototype = new Parent();" + "Child.prototype.constructor = Child;" "var outer = { inner: function() { } };" "var p = new Parent();" "var c = new Child();" "var x = new outer.inner();" - "var proto = Child.prototype;")->Run(); + "var proto = Child.prototype;") + ->Run(context.local()) + .ToLocalChecked(); - Local<v8::Value> p = context->Global()->Get(v8_str("p")); + Local<v8::Value> p = + context->Global()->Get(context.local(), v8_str("p")).ToLocalChecked(); CHECK(p->IsObject() && - p->ToObject(isolate)->GetConstructorName()->Equals(v8_str("Parent"))); + p->ToObject(context.local()) + .ToLocalChecked() + ->GetConstructorName() + ->Equals(context.local(), v8_str("Parent")) + .FromJust()); - Local<v8::Value> c = context->Global()->Get(v8_str("c")); + Local<v8::Value> c = + context->Global()->Get(context.local(), v8_str("c")).ToLocalChecked(); CHECK(c->IsObject() && - c->ToObject(isolate)->GetConstructorName()->Equals(v8_str("Child"))); + c->ToObject(context.local()) + .ToLocalChecked() + ->GetConstructorName() + ->Equals(context.local(), v8_str("Child")) + .FromJust()); - Local<v8::Value> x = context->Global()->Get(v8_str("x")); + Local<v8::Value> x = + context->Global()->Get(context.local(), v8_str("x")).ToLocalChecked(); CHECK(x->IsObject() && - x->ToObject(isolate)->GetConstructorName()->Equals( - v8_str("outer.inner"))); + x->ToObject(context.local()) + .ToLocalChecked() + ->GetConstructorName() + ->Equals(context.local(), v8_str("outer.inner")) + .FromJust()); - Local<v8::Value> child_prototype = context->Global()->Get(v8_str("proto")); + Local<v8::Value> child_prototype = + context->Global()->Get(context.local(), v8_str("proto")).ToLocalChecked(); CHECK(child_prototype->IsObject() && - child_prototype->ToObject(isolate)->GetConstructorName()->Equals( - v8_str("Parent"))); + child_prototype->ToObject(context.local()) + .ToLocalChecked() + ->GetConstructorName() + ->Equals(context.local(), v8_str("Parent")) + .FromJust()); +} + + +THREADED_TEST(SubclassGetConstructorName) { + v8::Isolate* isolate = CcTest::isolate(); + LocalContext context; + v8::HandleScope scope(isolate); + v8_compile( + "\"use strict\";" + "class Parent {}" + "class Child extends Parent {}" + "var p = new Parent();" + "var c = new Child();") + ->Run(context.local()) + .ToLocalChecked(); + + Local<v8::Value> p = + context->Global()->Get(context.local(), v8_str("p")).ToLocalChecked(); + CHECK(p->IsObject() && + p->ToObject(context.local()) + .ToLocalChecked() + ->GetConstructorName() + ->Equals(context.local(), v8_str("Parent")) + .FromJust()); + + Local<v8::Value> c = + context->Global()->Get(context.local(), v8_str("c")).ToLocalChecked(); + CHECK(c->IsObject() && + c->ToObject(context.local()) + .ToLocalChecked() + ->GetConstructorName() + ->Equals(context.local(), v8_str("Child")) + .FromJust()); } @@ -11689,10 +13317,10 @@ static void ThrowInJS(const v8::FunctionCallbackInfo<v8::Value>& args) { { v8::Locker nested_locker(isolate); v8::HandleScope scope(isolate); - v8::Handle<Value> exception; + v8::Local<Value> exception; { v8::TryCatch try_catch(isolate); - v8::Handle<Value> value = CompileRun(code); + v8::Local<Value> value = CompileRun(code); CHECK(value.IsEmpty()); CHECK(try_catch.HasCaught()); // Make sure to wrap the exception in a new handle because @@ -11713,7 +13341,7 @@ static void ThrowInJSNoCatch(const v8::FunctionCallbackInfo<v8::Value>& args) { { v8::Locker nested_locker(CcTest::isolate()); v8::HandleScope scope(args.GetIsolate()); - v8::Handle<Value> value = CompileRun(code); + v8::Local<Value> value = CompileRun(code); CHECK(value.IsEmpty()); args.GetReturnValue().Set(v8_str("foo")); } @@ -11730,8 +13358,8 @@ TEST(NestedLockers) { v8::HandleScope scope(env->GetIsolate()); Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate, ThrowInJS); - Local<Function> fun = fun_templ->GetFunction(); - env->Global()->Set(v8_str("throw_in_js"), fun); + Local<Function> fun = fun_templ->GetFunction(env.local()).ToLocalChecked(); + CHECK(env->Global()->Set(env.local(), v8_str("throw_in_js"), fun).FromJust()); Local<Script> script = v8_compile("(function () {" " try {" " throw_in_js();" @@ -11740,7 +13368,10 @@ TEST(NestedLockers) { " return e * 13;" " }" "})();"); - CHECK_EQ(91, script->Run()->Int32Value()); + CHECK_EQ(91, script->Run(env.local()) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); } @@ -11752,8 +13383,8 @@ TEST(NestedLockersNoTryCatch) { v8::HandleScope scope(env->GetIsolate()); Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(env->GetIsolate(), ThrowInJSNoCatch); - Local<Function> fun = fun_templ->GetFunction(); - env->Global()->Set(v8_str("throw_in_js"), fun); + Local<Function> fun = fun_templ->GetFunction(env.local()).ToLocalChecked(); + CHECK(env->Global()->Set(env.local(), v8_str("throw_in_js"), fun).FromJust()); Local<Script> script = v8_compile("(function () {" " try {" " throw_in_js();" @@ -11762,7 +13393,10 @@ TEST(NestedLockersNoTryCatch) { " return e * 13;" " }" "})();"); - CHECK_EQ(91, script->Run()->Int32Value()); + CHECK_EQ(91, script->Run(env.local()) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); } @@ -11788,13 +13422,18 @@ THREADED_TEST(LockUnlockLock) { LocalContext env; Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(CcTest::isolate(), UnlockForAMoment); - Local<Function> fun = fun_templ->GetFunction(); - env->Global()->Set(v8_str("unlock_for_a_moment"), fun); + Local<Function> fun = fun_templ->GetFunction(env.local()).ToLocalChecked(); + CHECK(env->Global() + ->Set(env.local(), v8_str("unlock_for_a_moment"), fun) + .FromJust()); Local<Script> script = v8_compile("(function () {" " unlock_for_a_moment();" " return 42;" "})();"); - CHECK_EQ(42, script->Run()->Int32Value()); + CHECK_EQ(42, script->Run(env.local()) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); } { v8::Locker locker(CcTest::isolate()); @@ -11802,13 +13441,18 @@ THREADED_TEST(LockUnlockLock) { LocalContext env; Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(CcTest::isolate(), UnlockForAMoment); - Local<Function> fun = fun_templ->GetFunction(); - env->Global()->Set(v8_str("unlock_for_a_moment"), fun); + Local<Function> fun = fun_templ->GetFunction(env.local()).ToLocalChecked(); + CHECK(env->Global() + ->Set(env.local(), v8_str("unlock_for_a_moment"), fun) + .FromJust()); Local<Script> script = v8_compile("(function () {" " unlock_for_a_moment();" " return 42;" "})();"); - CHECK_EQ(42, script->Run()->Int32Value()); + CHECK_EQ(42, script->Run(env.local()) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); } } @@ -11824,8 +13468,7 @@ static int GetGlobalObjectsCount() { count++; } } - // Subtract one to compensate for the code stub context that is always present - return count - 1; + return count; } @@ -11860,14 +13503,14 @@ TEST(DontLeakGlobalObjects) { { v8::HandleScope scope(CcTest::isolate()); LocalContext context; - v8_compile("Date")->Run(); + v8_compile("Date")->Run(context.local()).ToLocalChecked(); } CcTest::isolate()->ContextDisposedNotification(); CheckSurvivingGlobalObjectsCount(0); { v8::HandleScope scope(CcTest::isolate()); LocalContext context; - v8_compile("/aaa/")->Run(); + v8_compile("/aaa/")->Run(context.local()).ToLocalChecked(); } CcTest::isolate()->ContextDisposedNotification(); CheckSurvivingGlobalObjectsCount(0); @@ -11876,7 +13519,7 @@ TEST(DontLeakGlobalObjects) { const char* extension_list[] = { "v8/gc" }; v8::ExtensionConfiguration extensions(1, extension_list); LocalContext context(&extensions); - v8_compile("gc();")->Run(); + v8_compile("gc();")->Run(context.local()).ToLocalChecked(); } CcTest::isolate()->ContextDisposedNotification(); CheckSurvivingGlobalObjectsCount(0); @@ -11928,7 +13571,9 @@ TEST(WeakCallbackApi) { { v8::HandleScope scope(isolate); v8::Local<v8::Object> obj = v8::Object::New(isolate); - obj->Set(v8_str("key"), v8::Integer::New(isolate, 231)); + CHECK( + obj->Set(context.local(), v8_str("key"), v8::Integer::New(isolate, 231)) + .FromJust()); v8::Persistent<v8::Object>* handle = new v8::Persistent<v8::Object>(isolate, obj); handle->SetWeak<v8::Persistent<v8::Object>>( @@ -12077,7 +13722,7 @@ THREADED_TEST(CheckForCrossContextObjectLiterals) { } -static v8::Handle<Value> NestedScope(v8::Local<Context> env) { +static v8::Local<Value> NestedScope(v8::Local<Context> env) { v8::EscapableHandleScope inner(env->GetIsolate()); env->Enter(); v8::Local<Value> three = v8_num(3); @@ -12092,8 +13737,8 @@ THREADED_TEST(NestedHandleScopeAndContexts) { v8::HandleScope outer(isolate); v8::Local<Context> env = Context::New(isolate); env->Enter(); - v8::Handle<Value> value = NestedScope(env); - v8::Handle<String> str(value->ToString(isolate)); + v8::Local<Value> value = NestedScope(env); + v8::Local<String> str(value->ToString(env).ToLocalChecked()); CHECK(!str.IsEmpty()); env->Exit(); } @@ -12340,7 +13985,9 @@ void SetFunctionEntryHookTest::RunLoopInNewEnv(v8::Isolate* isolate) { Local<ObjectTemplate> t = ObjectTemplate::New(isolate); t->Set(v8_str("asdf"), v8::FunctionTemplate::New(isolate, RuntimeCallback)); - env->Global()->Set(v8_str("obj"), t->NewInstance()); + CHECK(env->Global() + ->Set(env, v8_str("obj"), t->NewInstance(env).ToLocalChecked()) + .FromJust()); const char* script = "function bar() {\n" @@ -12353,16 +14000,15 @@ void SetFunctionEntryHookTest::RunLoopInNewEnv(v8::Isolate* isolate) { "// Invoke on the runtime function.\n" "obj.asdf()"; CompileRun(script); - bar_func_ = i::Handle<i::JSFunction>::cast( - v8::Utils::OpenHandle(*env->Global()->Get(v8_str("bar")))); - DCHECK(!bar_func_.is_null()); + bar_func_ = i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle( + *env->Global()->Get(env, v8_str("bar")).ToLocalChecked())); + CHECK(!bar_func_.is_null()); - foo_func_ = - i::Handle<i::JSFunction>::cast( - v8::Utils::OpenHandle(*env->Global()->Get(v8_str("foo")))); - DCHECK(!foo_func_.is_null()); + foo_func_ = i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle( + *env->Global()->Get(env, v8_str("foo")).ToLocalChecked())); + CHECK(!foo_func_.is_null()); - v8::Handle<v8::Value> value = CompileRun("bar();"); + v8::Local<v8::Value> value = CompileRun("bar();"); CHECK(value->IsNumber()); CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value()); @@ -12621,10 +14267,18 @@ UNINITIALIZED_TEST(SetJitCodeEventHandler) { CompileRun(script); // Keep a strong reference to the code object in the handle scope. - i::Handle<i::Code> bar_code(i::Handle<i::JSFunction>::cast( - v8::Utils::OpenHandle(*env->Global()->Get(v8_str("bar"))))->code()); - i::Handle<i::Code> foo_code(i::Handle<i::JSFunction>::cast( - v8::Utils::OpenHandle(*env->Global()->Get(v8_str("foo"))))->code()); + i::Handle<i::Code> bar_code( + i::Handle<i::JSFunction>::cast( + v8::Utils::OpenHandle(*env->Global() + ->Get(env.local(), v8_str("bar")) + .ToLocalChecked())) + ->code()); + i::Handle<i::Code> foo_code( + i::Handle<i::JSFunction>::cast( + v8::Utils::OpenHandle(*env->Global() + ->Get(env.local(), v8_str("foo")) + .ToLocalChecked())) + ->code()); // Clear the compilation cache to get more wastage. reinterpret_cast<i::Isolate*>(isolate)->compilation_cache()->Clear(); @@ -12727,8 +14381,10 @@ THREADED_TEST(Regress54) { local->SetInternalFieldCount(1); templ.Reset(isolate, inner.Escape(local)); } - v8::Handle<v8::Object> result = - v8::Local<v8::ObjectTemplate>::New(isolate, templ)->NewInstance(); + v8::Local<v8::Object> result = + v8::Local<v8::ObjectTemplate>::New(isolate, templ) + ->NewInstance(context.local()) + .ToLocalChecked(); CHECK_EQ(1, result->InternalFieldCount()); } @@ -12739,32 +14395,32 @@ TEST(CatchStackOverflow) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); v8::TryCatch try_catch(context->GetIsolate()); - v8::Handle<v8::Value> result = CompileRun( - "function f() {" - " return f();" - "}" - "" - "f();"); + v8::Local<v8::Value> result = CompileRun( + "function f() {" + " return f();" + "}" + "" + "f();"); CHECK(result.IsEmpty()); } -static void CheckTryCatchSourceInfo(v8::Handle<v8::Script> script, +static void CheckTryCatchSourceInfo(v8::Local<v8::Script> script, const char* resource_name, int line_offset) { v8::HandleScope scope(CcTest::isolate()); v8::TryCatch try_catch(CcTest::isolate()); - v8::Handle<v8::Value> result = script->Run(); - CHECK(result.IsEmpty()); + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); + CHECK(script->Run(context).IsEmpty()); CHECK(try_catch.HasCaught()); - v8::Handle<v8::Message> message = try_catch.Message(); + v8::Local<v8::Message> message = try_catch.Message(); CHECK(!message.IsEmpty()); - CHECK_EQ(10 + line_offset, message->GetLineNumber()); + CHECK_EQ(10 + line_offset, message->GetLineNumber(context).FromJust()); CHECK_EQ(91, message->GetStartPosition()); CHECK_EQ(92, message->GetEndPosition()); - CHECK_EQ(2, message->GetStartColumn()); - CHECK_EQ(3, message->GetEndColumn()); - v8::String::Utf8Value line(message->GetSourceLine()); + CHECK_EQ(2, message->GetStartColumn(context).FromJust()); + CHECK_EQ(3, message->GetEndColumn(context).FromJust()); + v8::String::Utf8Value line(message->GetSourceLine(context).ToLocalChecked()); CHECK_EQ(0, strcmp(" throw 'nirk';", *line)); v8::String::Utf8Value name(message->GetScriptOrigin().ResourceName()); CHECK_EQ(0, strcmp(resource_name, *name)); @@ -12790,22 +14446,22 @@ THREADED_TEST(TryCatchSourceInfo) { "Foo();\n"); const char* resource_name; - v8::Handle<v8::Script> script; + v8::Local<v8::Script> script; resource_name = "test.js"; script = CompileWithOrigin(source, resource_name); CheckTryCatchSourceInfo(script, resource_name, 0); resource_name = "test1.js"; - v8::ScriptOrigin origin1( - v8::String::NewFromUtf8(context->GetIsolate(), resource_name)); - script = v8::Script::Compile(source, &origin1); + v8::ScriptOrigin origin1(v8_str(resource_name)); + script = + v8::Script::Compile(context.local(), source, &origin1).ToLocalChecked(); CheckTryCatchSourceInfo(script, resource_name, 0); resource_name = "test2.js"; - v8::ScriptOrigin origin2( - v8::String::NewFromUtf8(context->GetIsolate(), resource_name), - v8::Integer::New(context->GetIsolate(), 7)); - script = v8::Script::Compile(source, &origin2); + v8::ScriptOrigin origin2(v8_str(resource_name), + v8::Integer::New(context->GetIsolate(), 7)); + script = + v8::Script::Compile(context.local(), source, &origin2).ToLocalChecked(); CheckTryCatchSourceInfo(script, resource_name, 7); } @@ -12814,28 +14470,35 @@ THREADED_TEST(TryCatchSourceInfoForEOSError) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); v8::TryCatch try_catch(context->GetIsolate()); - v8::Script::Compile(v8_str("!\n")); + CHECK(v8::Script::Compile(context.local(), v8_str("!\n")).IsEmpty()); CHECK(try_catch.HasCaught()); - v8::Handle<v8::Message> message = try_catch.Message(); - CHECK_EQ(1, message->GetLineNumber()); - CHECK_EQ(0, message->GetStartColumn()); + v8::Local<v8::Message> message = try_catch.Message(); + CHECK_EQ(1, message->GetLineNumber(context.local()).FromJust()); + CHECK_EQ(0, message->GetStartColumn(context.local()).FromJust()); } THREADED_TEST(CompilationCache) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::String> source0 = - v8::String::NewFromUtf8(context->GetIsolate(), "1234"); - v8::Handle<v8::String> source1 = - v8::String::NewFromUtf8(context->GetIsolate(), "1234"); - v8::Handle<v8::Script> script0 = CompileWithOrigin(source0, "test.js"); - v8::Handle<v8::Script> script1 = CompileWithOrigin(source1, "test.js"); - v8::Handle<v8::Script> script2 = - v8::Script::Compile(source0); // different origin - CHECK_EQ(1234, script0->Run()->Int32Value()); - CHECK_EQ(1234, script1->Run()->Int32Value()); - CHECK_EQ(1234, script2->Run()->Int32Value()); + v8::Local<v8::String> source0 = v8_str("1234"); + v8::Local<v8::String> source1 = v8_str("1234"); + v8::Local<v8::Script> script0 = CompileWithOrigin(source0, "test.js"); + v8::Local<v8::Script> script1 = CompileWithOrigin(source1, "test.js"); + v8::Local<v8::Script> script2 = v8::Script::Compile(context.local(), source0) + .ToLocalChecked(); // different origin + CHECK_EQ(1234, script0->Run(context.local()) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(1234, script1->Run(context.local()) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(1234, script2->Run(context.local()) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } @@ -12853,8 +14516,11 @@ THREADED_TEST(CallbackFunctionName) { Local<ObjectTemplate> t = ObjectTemplate::New(isolate); t->Set(v8_str("asdf"), v8::FunctionTemplate::New(isolate, FunctionNameCallback)); - context->Global()->Set(v8_str("obj"), t->NewInstance()); - v8::Handle<v8::Value> value = CompileRun("obj.asdf.name"); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj"), + t->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); + v8::Local<v8::Value> value = CompileRun("obj.asdf.name"); CHECK(value->IsString()); v8::String::Utf8Value name(value); CHECK_EQ(0, strcmp("asdf", *name)); @@ -12864,32 +14530,37 @@ THREADED_TEST(CallbackFunctionName) { THREADED_TEST(DateAccess) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::Value> date = - v8::Date::New(context->GetIsolate(), 1224744689038.0); + v8::Local<v8::Value> date = + v8::Date::New(context.local(), 1224744689038.0).ToLocalChecked(); CHECK(date->IsDate()); CHECK_EQ(1224744689038.0, date.As<v8::Date>()->ValueOf()); } -void CheckProperties(v8::Isolate* isolate, v8::Handle<v8::Value> val, +void CheckProperties(v8::Isolate* isolate, v8::Local<v8::Value> val, unsigned elmc, const char* elmv[]) { - v8::Handle<v8::Object> obj = val.As<v8::Object>(); - v8::Handle<v8::Array> props = obj->GetPropertyNames(); + v8::Local<v8::Context> context = isolate->GetCurrentContext(); + v8::Local<v8::Object> obj = val.As<v8::Object>(); + v8::Local<v8::Array> props = obj->GetPropertyNames(context).ToLocalChecked(); CHECK_EQ(elmc, props->Length()); for (unsigned i = 0; i < elmc; i++) { - v8::String::Utf8Value elm(props->Get(v8::Integer::New(isolate, i))); + v8::String::Utf8Value elm( + props->Get(context, v8::Integer::New(isolate, i)).ToLocalChecked()); CHECK_EQ(0, strcmp(elmv[i], *elm)); } } -void CheckOwnProperties(v8::Isolate* isolate, v8::Handle<v8::Value> val, +void CheckOwnProperties(v8::Isolate* isolate, v8::Local<v8::Value> val, unsigned elmc, const char* elmv[]) { - v8::Handle<v8::Object> obj = val.As<v8::Object>(); - v8::Handle<v8::Array> props = obj->GetOwnPropertyNames(); + v8::Local<v8::Context> context = isolate->GetCurrentContext(); + v8::Local<v8::Object> obj = val.As<v8::Object>(); + v8::Local<v8::Array> props = + obj->GetOwnPropertyNames(context).ToLocalChecked(); CHECK_EQ(elmc, props->Length()); for (unsigned i = 0; i < elmc; i++) { - v8::String::Utf8Value elm(props->Get(v8::Integer::New(isolate, i))); + v8::String::Utf8Value elm( + props->Get(context, v8::Integer::New(isolate, i)).ToLocalChecked()); CHECK_EQ(0, strcmp(elmv[i], *elm)); } } @@ -12899,7 +14570,7 @@ THREADED_TEST(PropertyEnumeration) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::Value> obj = CompileRun( + v8::Local<v8::Value> obj = CompileRun( "var result = [];" "result[0] = {};" "result[1] = {a: 1, b: 2};" @@ -12908,34 +14579,50 @@ THREADED_TEST(PropertyEnumeration) { "var x = { __proto__: proto, w: 0, z: 1 };" "result[3] = x;" "result;"); - v8::Handle<v8::Array> elms = obj.As<v8::Array>(); + v8::Local<v8::Array> elms = obj.As<v8::Array>(); CHECK_EQ(4u, elms->Length()); int elmc0 = 0; const char** elmv0 = NULL; CheckProperties( - isolate, elms->Get(v8::Integer::New(isolate, 0)), elmc0, elmv0); + isolate, + elms->Get(context.local(), v8::Integer::New(isolate, 0)).ToLocalChecked(), + elmc0, elmv0); CheckOwnProperties( - isolate, elms->Get(v8::Integer::New(isolate, 0)), elmc0, elmv0); + isolate, + elms->Get(context.local(), v8::Integer::New(isolate, 0)).ToLocalChecked(), + elmc0, elmv0); int elmc1 = 2; const char* elmv1[] = {"a", "b"}; CheckProperties( - isolate, elms->Get(v8::Integer::New(isolate, 1)), elmc1, elmv1); + isolate, + elms->Get(context.local(), v8::Integer::New(isolate, 1)).ToLocalChecked(), + elmc1, elmv1); CheckOwnProperties( - isolate, elms->Get(v8::Integer::New(isolate, 1)), elmc1, elmv1); + isolate, + elms->Get(context.local(), v8::Integer::New(isolate, 1)).ToLocalChecked(), + elmc1, elmv1); int elmc2 = 3; const char* elmv2[] = {"0", "1", "2"}; CheckProperties( - isolate, elms->Get(v8::Integer::New(isolate, 2)), elmc2, elmv2); + isolate, + elms->Get(context.local(), v8::Integer::New(isolate, 2)).ToLocalChecked(), + elmc2, elmv2); CheckOwnProperties( - isolate, elms->Get(v8::Integer::New(isolate, 2)), elmc2, elmv2); + isolate, + elms->Get(context.local(), v8::Integer::New(isolate, 2)).ToLocalChecked(), + elmc2, elmv2); int elmc3 = 4; const char* elmv3[] = {"w", "z", "x", "y"}; CheckProperties( - isolate, elms->Get(v8::Integer::New(isolate, 3)), elmc3, elmv3); + isolate, + elms->Get(context.local(), v8::Integer::New(isolate, 3)).ToLocalChecked(), + elmc3, elmv3); int elmc4 = 2; const char* elmv4[] = {"w", "z"}; CheckOwnProperties( - isolate, elms->Get(v8::Integer::New(isolate, 3)), elmc4, elmv4); + isolate, + elms->Get(context.local(), v8::Integer::New(isolate, 3)).ToLocalChecked(), + elmc4, elmv4); } @@ -12943,7 +14630,7 @@ THREADED_TEST(PropertyEnumeration2) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::Value> obj = CompileRun( + v8::Local<v8::Value> obj = CompileRun( "var result = [];" "result[0] = {};" "result[1] = {a: 1, b: 2};" @@ -12952,15 +14639,19 @@ THREADED_TEST(PropertyEnumeration2) { "var x = { __proto__: proto, w: 0, z: 1 };" "result[3] = x;" "result;"); - v8::Handle<v8::Array> elms = obj.As<v8::Array>(); + v8::Local<v8::Array> elms = obj.As<v8::Array>(); CHECK_EQ(4u, elms->Length()); int elmc0 = 0; const char** elmv0 = NULL; - CheckProperties(isolate, - elms->Get(v8::Integer::New(isolate, 0)), elmc0, elmv0); - - v8::Handle<v8::Value> val = elms->Get(v8::Integer::New(isolate, 0)); - v8::Handle<v8::Array> props = val.As<v8::Object>()->GetPropertyNames(); + CheckProperties( + isolate, + elms->Get(context.local(), v8::Integer::New(isolate, 0)).ToLocalChecked(), + elmc0, elmv0); + + v8::Local<v8::Value> val = + elms->Get(context.local(), v8::Integer::New(isolate, 0)).ToLocalChecked(); + v8::Local<v8::Array> props = + val.As<v8::Object>()->GetPropertyNames(context.local()).ToLocalChecked(); CHECK_EQ(0u, props->Length()); for (uint32_t i = 0; i < props->Length(); i++) { printf("p[%u]\n", i); @@ -12991,14 +14682,20 @@ THREADED_TEST(AccessChecksReenabledCorrectly) { } } - Local<v8::Object> instance_1 = templ->NewInstance(); - context->Global()->Set(v8_str("obj_1"), instance_1); + Local<v8::Object> instance_1 = + templ->NewInstance(context.local()).ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj_1"), instance_1) + .FromJust()); Local<Value> value_1 = CompileRun("obj_1.a"); CHECK(value_1.IsEmpty()); - Local<v8::Object> instance_2 = templ->NewInstance(); - context->Global()->Set(v8_str("obj_2"), instance_2); + Local<v8::Object> instance_2 = + templ->NewInstance(context.local()).ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj_2"), instance_2) + .FromJust()); Local<Value> value_2 = CompileRun("obj_2.a"); CHECK(value_2.IsEmpty()); @@ -13015,8 +14712,9 @@ TEST(PreCompileSerialization) { i::FLAG_min_preparse_length = 0; const char* script = "function foo(a) { return a+1; }"; v8::ScriptCompiler::Source source(v8_str(script)); - v8::ScriptCompiler::Compile(isolate, &source, - v8::ScriptCompiler::kProduceParserCache); + v8::ScriptCompiler::Compile(env.local(), &source, + v8::ScriptCompiler::kProduceParserCache) + .ToLocalChecked(); // Serialize. const v8::ScriptCompiler::CachedData* cd = source.GetCachedData(); i::byte* serialized_data = i::NewArray<i::byte>(cd->length); @@ -13044,15 +14742,19 @@ THREADED_TEST(DictionaryICLoadedFunction) { // Test LoadIC. for (int i = 0; i < 2; i++) { LocalContext context; - context->Global()->Set(v8_str("tmp"), v8::True(CcTest::isolate())); - context->Global()->Delete(v8_str("tmp")); + CHECK(context->Global() + ->Set(context.local(), v8_str("tmp"), v8::True(CcTest::isolate())) + .FromJust()); + context->Global()->Delete(context.local(), v8_str("tmp")).FromJust(); CompileRun("for (var j = 0; j < 10; j++) new RegExp('');"); } // Test CallIC. for (int i = 0; i < 2; i++) { LocalContext context; - context->Global()->Set(v8_str("tmp"), v8::True(CcTest::isolate())); - context->Global()->Delete(v8_str("tmp")); + CHECK(context->Global() + ->Set(context.local(), v8_str("tmp"), v8::True(CcTest::isolate())) + .FromJust()); + context->Global()->Delete(context.local(), v8_str("tmp")).FromJust(); CompileRun("for (var j = 0; j < 10; j++) RegExp('')"); } } @@ -13080,10 +14782,12 @@ THREADED_TEST(CrossContextNew) { // Call the constructor function from context0 and check that the // result has the 'x' property. context1->Enter(); - context1->Global()->Set(v8_str("other"), context0->Global()); + CHECK(context1->Global() + ->Set(context1, v8_str("other"), context0->Global()) + .FromJust()); Local<Value> value = CompileRun("var instance = new other.C(); instance.x"); CHECK(value->IsInt32()); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(context1).FromJust()); context1->Exit(); } @@ -13104,22 +14808,47 @@ TEST(ObjectClone) { Local<Value> val = CompileRun(sample); CHECK(val->IsObject()); Local<v8::Object> obj = val.As<v8::Object>(); - obj->Set(v8_str("gamma"), v8_str("cloneme")); + obj->Set(env.local(), v8_str("gamma"), v8_str("cloneme")).FromJust(); - CHECK(v8_str("hello")->Equals(obj->Get(v8_str("alpha")))); - CHECK(v8::Integer::New(isolate, 123)->Equals(obj->Get(v8_str("beta")))); - CHECK(v8_str("cloneme")->Equals(obj->Get(v8_str("gamma")))); + CHECK(v8_str("hello") + ->Equals(env.local(), + obj->Get(env.local(), v8_str("alpha")).ToLocalChecked()) + .FromJust()); + CHECK(v8::Integer::New(isolate, 123) + ->Equals(env.local(), + obj->Get(env.local(), v8_str("beta")).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("cloneme") + ->Equals(env.local(), + obj->Get(env.local(), v8_str("gamma")).ToLocalChecked()) + .FromJust()); // Clone it. Local<v8::Object> clone = obj->Clone(); - CHECK(v8_str("hello")->Equals(clone->Get(v8_str("alpha")))); - CHECK(v8::Integer::New(isolate, 123)->Equals(clone->Get(v8_str("beta")))); - CHECK(v8_str("cloneme")->Equals(clone->Get(v8_str("gamma")))); + CHECK(v8_str("hello") + ->Equals(env.local(), + clone->Get(env.local(), v8_str("alpha")).ToLocalChecked()) + .FromJust()); + CHECK(v8::Integer::New(isolate, 123) + ->Equals(env.local(), + clone->Get(env.local(), v8_str("beta")).ToLocalChecked()) + .FromJust()); + CHECK(v8_str("cloneme") + ->Equals(env.local(), + clone->Get(env.local(), v8_str("gamma")).ToLocalChecked()) + .FromJust()); // Set a property on the clone, verify each object. - clone->Set(v8_str("beta"), v8::Integer::New(isolate, 456)); - CHECK(v8::Integer::New(isolate, 123)->Equals(obj->Get(v8_str("beta")))); - CHECK(v8::Integer::New(isolate, 456)->Equals(clone->Get(v8_str("beta")))); + CHECK(clone->Set(env.local(), v8_str("beta"), v8::Integer::New(isolate, 456)) + .FromJust()); + CHECK(v8::Integer::New(isolate, 123) + ->Equals(env.local(), + obj->Get(env.local(), v8_str("beta")).ToLocalChecked()) + .FromJust()); + CHECK(v8::Integer::New(isolate, 456) + ->Equals(env.local(), + clone->Get(env.local(), v8_str("beta")).ToLocalChecked()) + .FromJust()); } @@ -13194,8 +14923,8 @@ THREADED_TEST(MorphCompositeStringTest) { v8::Utils::ToLocal(factory->NewExternalStringFromOneByte( &one_byte_resource).ToHandleChecked())); - env->Global()->Set(v8_str("lhs"), lhs); - env->Global()->Set(v8_str("rhs"), rhs); + CHECK(env->Global()->Set(env.local(), v8_str("lhs"), lhs).FromJust()); + CHECK(env->Global()->Set(env.local(), v8_str("rhs"), rhs).FromJust()); CompileRun( "var cons = lhs + rhs;" @@ -13211,7 +14940,8 @@ THREADED_TEST(MorphCompositeStringTest) { &uc16_resource); // This should UTF-8 without flattening, since everything is ASCII. - Handle<String> cons = v8_compile("cons")->Run().As<String>(); + Local<String> cons = + v8_compile("cons")->Run(env.local()).ToLocalChecked().As<String>(); CHECK_EQ(128, cons->Utf8Length()); int nchars = -1; CHECK_EQ(129, cons->WriteUtf8(utf_buffer, -1, &nchars)); @@ -13234,12 +14964,22 @@ THREADED_TEST(MorphCompositeStringTest) { const char* expected_slice_on_cons = "ow is the time for all good men to come to the aid of the party" "Now is the time for all good men to come to the aid of the part"; - CHECK(String::NewFromUtf8(env->GetIsolate(), expected_cons) - ->Equals(env->Global()->Get(v8_str("cons")))); - CHECK(String::NewFromUtf8(env->GetIsolate(), expected_slice) - ->Equals(env->Global()->Get(v8_str("slice")))); - CHECK(String::NewFromUtf8(env->GetIsolate(), expected_slice_on_cons) - ->Equals(env->Global()->Get(v8_str("slice_on_cons")))); + CHECK(v8_str(expected_cons) + ->Equals(env.local(), env->Global() + ->Get(env.local(), v8_str("cons")) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str(expected_slice) + ->Equals(env.local(), env->Global() + ->Get(env.local(), v8_str("slice")) + .ToLocalChecked()) + .FromJust()); + CHECK(v8_str(expected_slice_on_cons) + ->Equals(env.local(), + env->Global() + ->Get(env.local(), v8_str("slice_on_cons")) + .ToLocalChecked()) + .FromJust()); } i::DeleteArray(two_byte_string); } @@ -13262,8 +15002,9 @@ TEST(CompileExternalTwoByteSource) { uint16_t* two_byte_string = AsciiToTwoByteString(one_byte_sources[i]); TestResource* uc16_resource = new TestResource(two_byte_string); v8::Local<v8::String> source = - v8::String::NewExternal(context->GetIsolate(), uc16_resource); - v8::Script::Compile(source); + v8::String::NewExternalTwoByte(context->GetIsolate(), uc16_resource) + .ToLocalChecked(); + v8::Script::Compile(context.local(), source).FromMaybe(Local<Script>()); } } @@ -13293,7 +15034,7 @@ class RegExpInterruptionThread : public v8::base::Thread { } // Wait a bit before terminating. v8::base::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(50)); - v8::V8::TerminateExecution(isolate_); + isolate_->TerminateExecution(); } private: @@ -13301,11 +15042,12 @@ class RegExpInterruptionThread : public v8::base::Thread { }; -void RunBeforeGC(v8::GCType type, v8::GCCallbackFlags flags) { +void RunBeforeGC(v8::Isolate* isolate, v8::GCType type, + v8::GCCallbackFlags flags) { if (v8::base::NoBarrier_Load(®exp_interruption_data.loop_count) != 2) { return; } - v8::HandleScope scope(CcTest::isolate()); + v8::HandleScope scope(isolate); v8::Local<v8::String> string = v8::Local<v8::String>::New( CcTest::isolate(), regexp_interruption_data.string); string->MakeExternal(regexp_interruption_data.string_resource); @@ -13317,22 +15059,22 @@ void RunBeforeGC(v8::GCType type, v8::GCCallbackFlags flags) { // * turn the subject string from one-byte internal to two-byte external string // * force termination TEST(RegExpInterruption) { - v8::HandleScope scope(CcTest::isolate()); LocalContext env; + v8::HandleScope scope(env->GetIsolate()); - RegExpInterruptionThread timeout_thread(CcTest::isolate()); + RegExpInterruptionThread timeout_thread(env->GetIsolate()); - v8::V8::AddGCPrologueCallback(RunBeforeGC); + env->GetIsolate()->AddGCPrologueCallback(RunBeforeGC); static const char* one_byte_content = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; i::uc16* uc16_content = AsciiToTwoByteString(one_byte_content); v8::Local<v8::String> string = v8_str(one_byte_content); - CcTest::global()->Set(v8_str("a"), string); - regexp_interruption_data.string.Reset(CcTest::isolate(), string); + env->Global()->Set(env.local(), v8_str("a"), string).FromJust(); + regexp_interruption_data.string.Reset(env->GetIsolate(), string); regexp_interruption_data.string_resource = new UC16VectorResource( i::Vector<const i::uc16>(uc16_content, i::StrLength(one_byte_content))); - v8::TryCatch try_catch(CcTest::isolate()); + v8::TryCatch try_catch(env->GetIsolate()); timeout_thread.Start(); CompileRun("/((a*)*)*b/.exec(a)"); @@ -13352,155 +15094,27 @@ TEST(RegExpInterruption) { TEST(ReadOnlyPropertyInGlobalProto) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); LocalContext context(0, templ); - v8::Handle<v8::Object> global = context->Global(); - v8::Handle<v8::Object> global_proto = - v8::Handle<v8::Object>::Cast(global->Get(v8_str("__proto__"))); - global_proto->ForceSet(v8_str("x"), v8::Integer::New(isolate, 0), - v8::ReadOnly); - global_proto->ForceSet(v8_str("y"), v8::Integer::New(isolate, 0), - v8::ReadOnly); + v8::Local<v8::Object> global = context->Global(); + v8::Local<v8::Object> global_proto = v8::Local<v8::Object>::Cast( + global->Get(context.local(), v8_str("__proto__")).ToLocalChecked()); + global_proto->DefineOwnProperty(context.local(), v8_str("x"), + v8::Integer::New(isolate, 0), v8::ReadOnly) + .FromJust(); + global_proto->DefineOwnProperty(context.local(), v8_str("y"), + v8::Integer::New(isolate, 0), v8::ReadOnly) + .FromJust(); // Check without 'eval' or 'with'. - v8::Handle<v8::Value> res = + v8::Local<v8::Value> res = CompileRun("function f() { x = 42; return x; }; f()"); - CHECK(v8::Integer::New(isolate, 0)->Equals(res)); + CHECK(v8::Integer::New(isolate, 0)->Equals(context.local(), res).FromJust()); // Check with 'eval'. res = CompileRun("function f() { eval('1'); y = 43; return y; }; f()"); - CHECK(v8::Integer::New(isolate, 0)->Equals(res)); + CHECK(v8::Integer::New(isolate, 0)->Equals(context.local(), res).FromJust()); // Check with 'with'. res = CompileRun("function f() { with (this) { y = 44 }; return y; }; f()"); - CHECK(v8::Integer::New(isolate, 0)->Equals(res)); -} - -static int force_set_set_count = 0; -static int force_set_get_count = 0; -bool pass_on_get = false; - -static void ForceSetGetter(v8::Local<v8::String> name, - const v8::PropertyCallbackInfo<v8::Value>& info) { - force_set_get_count++; - if (pass_on_get) { - return; - } - info.GetReturnValue().Set(3); -} - -static void ForceSetSetter(v8::Local<v8::String> name, - v8::Local<v8::Value> value, - const v8::PropertyCallbackInfo<void>& info) { - force_set_set_count++; -} - -static void ForceSetInterceptGetter( - v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { - CHECK(name->IsString()); - ForceSetGetter(Local<String>::Cast(name), info); -} - -static void ForceSetInterceptSetter( - v8::Local<v8::Name> name, v8::Local<v8::Value> value, - const v8::PropertyCallbackInfo<v8::Value>& info) { - force_set_set_count++; - info.GetReturnValue().SetUndefined(); -} - - -TEST(ForceSet) { - force_set_get_count = 0; - force_set_set_count = 0; - pass_on_get = false; - - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); - v8::Handle<v8::String> access_property = - v8::String::NewFromUtf8(isolate, "a"); - templ->SetAccessor(access_property, ForceSetGetter, ForceSetSetter); - LocalContext context(NULL, templ); - v8::Handle<v8::Object> global = context->Global(); - - // Ordinary properties - v8::Handle<v8::String> simple_property = - v8::String::NewFromUtf8(isolate, "p"); - global->ForceSet(simple_property, v8::Int32::New(isolate, 4), v8::ReadOnly); - CHECK_EQ(4, global->Get(simple_property)->Int32Value()); - // This should fail because the property is read-only - global->Set(simple_property, v8::Int32::New(isolate, 5)); - CHECK_EQ(4, global->Get(simple_property)->Int32Value()); - // This should succeed even though the property is read-only - global->ForceSet(simple_property, v8::Int32::New(isolate, 6)); - CHECK_EQ(6, global->Get(simple_property)->Int32Value()); - - // Accessors - CHECK_EQ(0, force_set_set_count); - CHECK_EQ(0, force_set_get_count); - CHECK_EQ(3, global->Get(access_property)->Int32Value()); - // CHECK_EQ the property shouldn't override it, just call the setter - // which in this case does nothing. - global->Set(access_property, v8::Int32::New(isolate, 7)); - CHECK_EQ(3, global->Get(access_property)->Int32Value()); - CHECK_EQ(1, force_set_set_count); - CHECK_EQ(2, force_set_get_count); - // ForceSet doesn't call the accessors for now. - // TODO(verwaest): Update once blink doesn't rely on ForceSet to delete api - // accessors. - global->ForceSet(access_property, v8::Int32::New(isolate, 8)); - CHECK_EQ(8, global->Get(access_property)->Int32Value()); - CHECK_EQ(1, force_set_set_count); - CHECK_EQ(2, force_set_get_count); -} - - -TEST(ForceSetWithInterceptor) { - v8::Isolate* isolate = CcTest::isolate(); - v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); - templ->SetHandler(v8::NamedPropertyHandlerConfiguration( - ForceSetInterceptGetter, ForceSetInterceptSetter)); - pass_on_get = true; - LocalContext context(NULL, templ); - v8::Handle<v8::Object> global = context->Global(); - - force_set_get_count = 0; - force_set_set_count = 0; - pass_on_get = false; - - v8::Handle<v8::String> some_property = - v8::String::NewFromUtf8(isolate, "a"); - CHECK_EQ(0, force_set_set_count); - CHECK_EQ(0, force_set_get_count); - CHECK_EQ(3, global->Get(some_property)->Int32Value()); - // Setting the property shouldn't override it, just call the setter - // which in this case does nothing. - global->Set(some_property, v8::Int32::New(isolate, 7)); - CHECK_EQ(3, global->Get(some_property)->Int32Value()); - CHECK_EQ(1, force_set_set_count); - CHECK_EQ(2, force_set_get_count); - // Getting the property when the interceptor returns an empty handle - // should yield undefined, since the property isn't present on the - // object itself yet. - pass_on_get = true; - CHECK(global->Get(some_property)->IsUndefined()); - CHECK_EQ(1, force_set_set_count); - CHECK_EQ(3, force_set_get_count); - // Forcing the property to be set should cause the value to be - // set locally without calling the interceptor. - global->ForceSet(some_property, v8::Int32::New(isolate, 8)); - CHECK_EQ(8, global->Get(some_property)->Int32Value()); - CHECK_EQ(1, force_set_set_count); - CHECK_EQ(4, force_set_get_count); - // Reenabling the interceptor should cause it to take precedence over - // the property - pass_on_get = false; - CHECK_EQ(3, global->Get(some_property)->Int32Value()); - CHECK_EQ(1, force_set_set_count); - CHECK_EQ(5, force_set_get_count); - // The interceptor should also work for other properties - CHECK_EQ(3, global->Get(v8::String::NewFromUtf8(isolate, "b")) - ->Int32Value()); - CHECK_EQ(1, force_set_set_count); - CHECK_EQ(6, force_set_get_count); + CHECK(v8::Integer::New(isolate, 0)->Equals(context.local(), res).FromJust()); } @@ -13515,10 +15129,10 @@ TEST(CreateDataProperty) { "Object.defineProperty(a, 'foo', {value: 23});" "Object.defineProperty(a, 'bar', {value: 23, configurable: true});"); - v8::Local<v8::Object> obj = - v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a"))); - v8::Local<v8::Array> arr = - v8::Local<v8::Array>::Cast(env->Global()->Get(v8_str("b"))); + v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast( + env->Global()->Get(env.local(), v8_str("a")).ToLocalChecked()); + v8::Local<v8::Array> arr = v8::Local<v8::Array>::Cast( + env->Global()->Get(env.local(), v8_str("b")).ToLocalChecked()); { // Can't change a non-configurable properties. v8::TryCatch try_catch(isolate); @@ -13618,10 +15232,10 @@ TEST(DefineOwnProperty) { "Object.defineProperty(a, 'foo', {value: 23});" "Object.defineProperty(a, 'bar', {value: 23, configurable: true});"); - v8::Local<v8::Object> obj = - v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a"))); - v8::Local<v8::Array> arr = - v8::Local<v8::Array>::Cast(env->Global()->Get(v8_str("b"))); + v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast( + env->Global()->Get(env.local(), v8_str("a")).ToLocalChecked()); + v8::Local<v8::Array> arr = v8::Local<v8::Array>::Cast( + env->Global()->Get(env.local(), v8_str("b")).ToLocalChecked()); { // Can't change a non-configurable properties. v8::TryCatch try_catch(isolate); @@ -13745,9 +15359,9 @@ THREADED_TEST(InitGlobalVarInProtoChain) { v8::HandleScope scope(context->GetIsolate()); // Introduce a variable in the prototype chain. CompileRun("__proto__.x = 42"); - v8::Handle<v8::Value> result = CompileRun("var x = 43; x"); + v8::Local<v8::Value> result = CompileRun("var x = 43; x"); CHECK(!result->IsUndefined()); - CHECK_EQ(43, result->Int32Value()); + CHECK_EQ(43, result->Int32Value(context.local()).FromJust()); } @@ -13760,16 +15374,16 @@ THREADED_TEST(ReplaceConstantFunction) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::Object> obj = v8::Object::New(isolate); - v8::Handle<v8::FunctionTemplate> func_templ = + v8::Local<v8::Object> obj = v8::Object::New(isolate); + v8::Local<v8::FunctionTemplate> func_templ = v8::FunctionTemplate::New(isolate); - v8::Handle<v8::String> foo_string = - v8::String::NewFromUtf8(isolate, "foo"); - obj->Set(foo_string, func_templ->GetFunction()); - v8::Handle<v8::Object> obj_clone = obj->Clone(); - obj_clone->Set(foo_string, - v8::String::NewFromUtf8(isolate, "Hello")); - CHECK(!obj->Get(foo_string)->IsUndefined()); + v8::Local<v8::String> foo_string = v8_str("foo"); + obj->Set(context.local(), foo_string, + func_templ->GetFunction(context.local()).ToLocalChecked()) + .FromJust(); + v8::Local<v8::Object> obj_clone = obj->Clone(); + obj_clone->Set(context.local(), foo_string, v8_str("Hello")).FromJust(); + CHECK(!obj->Get(context.local(), foo_string).ToLocalChecked()->IsUndefined()); } @@ -13784,20 +15398,21 @@ static void CheckElementValue(i::Isolate* isolate, template <class ExternalArrayClass, class ElementType> -static void ObjectWithExternalArrayTestHelper(Handle<Context> context, - v8::Handle<Object> obj, +static void ObjectWithExternalArrayTestHelper(Local<Context> context, + v8::Local<Object> obj, int element_count, i::ExternalArrayType array_type, int64_t low, int64_t high) { - i::Handle<i::JSObject> jsobj = v8::Utils::OpenHandle(*obj); + i::Handle<i::JSReceiver> jsobj = v8::Utils::OpenHandle(*obj); i::Isolate* isolate = jsobj->GetIsolate(); - obj->Set(v8_str("field"), - v8::Int32::New(reinterpret_cast<v8::Isolate*>(isolate), 1503)); - context->Global()->Set(v8_str("ext_array"), obj); - v8::Handle<v8::Value> result = CompileRun("ext_array.field"); - CHECK_EQ(1503, result->Int32Value()); + obj->Set(context, v8_str("field"), + v8::Int32::New(reinterpret_cast<v8::Isolate*>(isolate), 1503)) + .FromJust(); + CHECK(context->Global()->Set(context, v8_str("ext_array"), obj).FromJust()); + v8::Local<v8::Value> result = CompileRun("ext_array.field"); + CHECK_EQ(1503, result->Int32Value(context).FromJust()); result = CompileRun("ext_array[1]"); - CHECK_EQ(1, result->Int32Value()); + CHECK_EQ(1, result->Int32Value(context).FromJust()); // Check assigned smis result = CompileRun("for (var i = 0; i < 8; i++) {" @@ -13809,14 +15424,14 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, "}" "sum;"); - CHECK_EQ(28, result->Int32Value()); + CHECK_EQ(28, result->Int32Value(context).FromJust()); // Check pass through of assigned smis result = CompileRun("var sum = 0;" "for (var i = 0; i < 8; i++) {" " sum += ext_array[i] = ext_array[i] = -i;" "}" "sum;"); - CHECK_EQ(-28, result->Int32Value()); + CHECK_EQ(-28, result->Int32Value(context).FromJust()); // Check assigned smis in reverse order @@ -13828,7 +15443,7 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, " sum += ext_array[i];" "}" "sum;"); - CHECK_EQ(28, result->Int32Value()); + CHECK_EQ(28, result->Int32Value(context).FromJust()); // Check pass through of assigned HeapNumbers result = CompileRun("var sum = 0;" @@ -13836,7 +15451,7 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, " sum += ext_array[i] = ext_array[i] = (-i * 0.5);" "}" "sum;"); - CHECK_EQ(-28, result->Int32Value()); + CHECK_EQ(-28, result->Int32Value(context).FromJust()); // Check assigned HeapNumbers result = CompileRun("for (var i = 0; i < 16; i+=2) {" @@ -13847,7 +15462,7 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, " sum += ext_array[i];" "}" "sum;"); - CHECK_EQ(28, result->Int32Value()); + CHECK_EQ(28, result->Int32Value(context).FromJust()); // Check assigned HeapNumbers in reverse order result = CompileRun("for (var i = 14; i >= 0; i-=2) {" @@ -13858,7 +15473,7 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, " sum += ext_array[i];" "}" "sum;"); - CHECK_EQ(28, result->Int32Value()); + CHECK_EQ(28, result->Int32Value(context).FromJust()); i::ScopedVector<char> test_buf(1024); @@ -13877,13 +15492,13 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, boundary_program, low); result = CompileRun(test_buf.start()); - CHECK_EQ(low, result->IntegerValue()); + CHECK_EQ(low, result->IntegerValue(context).FromJust()); i::SNPrintF(test_buf, boundary_program, high); result = CompileRun(test_buf.start()); - CHECK_EQ(high, result->IntegerValue()); + CHECK_EQ(high, result->IntegerValue(context).FromJust()); // Check misprediction of type in IC. result = CompileRun("var tmp_array = ext_array;" @@ -13898,7 +15513,7 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, "sum;"); // Force GC to trigger verification. CcTest::heap()->CollectAllGarbage(); - CHECK_EQ(28, result->Int32Value()); + CHECK_EQ(28, result->Int32Value(context).FromJust()); // Make sure out-of-range loads do not throw. i::SNPrintF(test_buf, @@ -13911,7 +15526,7 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, "caught_exception;", element_count); result = CompileRun(test_buf.start()); - CHECK_EQ(false, result->BooleanValue()); + CHECK_EQ(false, result->BooleanValue(context).FromJust()); // Make sure out-of-range stores do not throw. i::SNPrintF(test_buf, @@ -13924,14 +15539,14 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, "caught_exception;", element_count); result = CompileRun(test_buf.start()); - CHECK_EQ(false, result->BooleanValue()); + CHECK_EQ(false, result->BooleanValue(context).FromJust()); // Check other boundary conditions, values and operations. result = CompileRun("for (var i = 0; i < 8; i++) {" " ext_array[7] = undefined;" "}" "ext_array[7];"); - CHECK_EQ(0, result->Int32Value()); + CHECK_EQ(0, result->Int32Value(context).FromJust()); if (array_type == i::kExternalFloat64Array || array_type == i::kExternalFloat32Array) { CHECK(std::isnan( @@ -13944,7 +15559,7 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, " ext_array[6] = '2.3';" "}" "ext_array[6];"); - CHECK_EQ(2, result->Int32Value()); + CHECK_EQ(2, result->Int32Value(context).FromJust()); CHECK_EQ(2, static_cast<int>( i::Object::GetElement( @@ -13961,7 +15576,7 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, " ext_array[i] = NaN;" "}" "ext_array[5];"); - CHECK_EQ(0, result->Int32Value()); + CHECK_EQ(0, result->Int32Value(context).FromJust()); CheckElementValue(isolate, 0, jsobj, 5); result = CompileRun("for (var i = 0; i < 8; i++) {" @@ -13973,7 +15588,7 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, "ext_array[5];"); int expected_value = (array_type == i::kExternalUint8ClampedArray) ? 255 : 0; - CHECK_EQ(expected_value, result->Int32Value()); + CHECK_EQ(expected_value, result->Int32Value(context).FromJust()); CheckElementValue(isolate, expected_value, jsobj, 5); result = CompileRun("for (var i = 0; i < 8; i++) {" @@ -13983,7 +15598,7 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, " ext_array[i] = -Infinity;" "}" "ext_array[5];"); - CHECK_EQ(0, result->Int32Value()); + CHECK_EQ(0, result->Int32Value(context).FromJust()); CheckElementValue(isolate, 0, jsobj, 5); // Check truncation behavior of integral arrays. @@ -14016,11 +15631,11 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, unsigned_data : (is_pixel_data ? pixel_data : signed_data))); result = CompileRun(test_buf.start()); - CHECK_EQ(true, result->BooleanValue()); + CHECK_EQ(true, result->BooleanValue(context).FromJust()); } - i::Handle<ExternalArrayClass> array( - ExternalArrayClass::cast(jsobj->elements())); + i::Handle<ExternalArrayClass> array(ExternalArrayClass::cast( + i::Handle<i::JSObject>::cast(jsobj)->elements())); for (int i = 0; i < element_count; i++) { array->set(i, static_cast<ElementType>(i)); } @@ -14038,7 +15653,7 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, " sum=ee_op_test_complex_func(sum);" "}" "sum;"); - CHECK_EQ(16000000, result->Int32Value()); + CHECK_EQ(16000000, result->Int32Value(context).FromJust()); // Test count operations result = CompileRun("function ee_op_test_count_func(sum) {" @@ -14053,34 +15668,46 @@ static void ObjectWithExternalArrayTestHelper(Handle<Context> context, " sum=ee_op_test_count_func(sum);" "}" "sum;"); - CHECK_EQ(16000000, result->Int32Value()); + CHECK_EQ(16000000, result->Int32Value(context).FromJust()); result = CompileRun("ext_array[3] = 33;" "delete ext_array[3];" "ext_array[3];"); - CHECK_EQ(33, result->Int32Value()); + CHECK_EQ(33, result->Int32Value(context).FromJust()); result = CompileRun("ext_array[0] = 10; ext_array[1] = 11;" "ext_array[2] = 12; ext_array[3] = 13;" "ext_array.__defineGetter__('2'," "function() { return 120; });" "ext_array[2];"); - CHECK_EQ(12, result->Int32Value()); + CHECK_EQ(12, result->Int32Value(context).FromJust()); result = CompileRun("var js_array = new Array(40);" "js_array[0] = 77;" "js_array;"); - CHECK_EQ(77, v8::Object::Cast(*result)->Get(v8_str("0"))->Int32Value()); + CHECK_EQ(77, v8::Object::Cast(*result) + ->Get(context, v8_str("0")) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); result = CompileRun("ext_array[1] = 23;" "ext_array.__proto__ = [];" "js_array.__proto__ = ext_array;" "js_array.concat(ext_array);"); - CHECK_EQ(77, v8::Object::Cast(*result)->Get(v8_str("0"))->Int32Value()); - CHECK_EQ(23, v8::Object::Cast(*result)->Get(v8_str("1"))->Int32Value()); + CHECK_EQ(77, v8::Object::Cast(*result) + ->Get(context, v8_str("0")) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); + CHECK_EQ(23, v8::Object::Cast(*result) + ->Get(context, v8_str("1")) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); result = CompileRun("ext_array[1] = 23;"); - CHECK_EQ(23, result->Int32Value()); + CHECK_EQ(23, result->Int32Value(context).FromJust()); } @@ -14111,7 +15738,7 @@ static void FixedTypedArrayTestHelper(i::ExternalArrayType array_type, CHECK_EQ(static_cast<int64_t>(static_cast<ElementType>(i)), static_cast<int64_t>(fixed_array->get_scalar(i))); } - v8::Handle<v8::Object> obj = v8::Utils::ToLocal(jsobj); + v8::Local<v8::Object> obj = v8::Utils::ToLocal(jsobj); ObjectWithExternalArrayTestHelper<FixedTypedArrayClass, ElementType>( context.local(), obj, kElementCount, array_type, @@ -14196,7 +15823,7 @@ void TypedArrayTestHelper(i::ExternalArrayType array_type, int64_t low, CHECK_EQ(kElementCount, static_cast<int>(ta->Length())); CHECK_EQ(2 * sizeof(ElementType), ta->ByteOffset()); CHECK_EQ(kElementCount * sizeof(ElementType), ta->ByteLength()); - CHECK(ab->Equals(ta->Buffer())); + CHECK(ab->Equals(env.local(), ta->Buffer()).FromJust()); ElementType* data = backing_store.start() + 2; for (int i = 0; i < kElementCount; i++) { @@ -14280,7 +15907,7 @@ THREADED_TEST(DataView) { CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv); CHECK_EQ(2u, dv->ByteOffset()); CHECK_EQ(kSize, static_cast<int>(dv->ByteLength())); - CHECK(ab->Equals(dv->Buffer())); + CHECK(ab->Equals(env.local(), dv->Buffer()).FromJust()); } @@ -14420,22 +16047,22 @@ THREADED_TEST(SharedDataView) { CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv); CHECK_EQ(2u, dv->ByteOffset()); CHECK_EQ(kSize, static_cast<int>(dv->ByteLength())); - CHECK(ab->Equals(dv->Buffer())); + CHECK(ab->Equals(env.local(), dv->Buffer()).FromJust()); } -#define IS_ARRAY_BUFFER_VIEW_TEST(View) \ - THREADED_TEST(Is##View) { \ - LocalContext env; \ - v8::Isolate* isolate = env->GetIsolate(); \ - v8::HandleScope handle_scope(isolate); \ - \ - Handle<Value> result = CompileRun( \ - "var ab = new ArrayBuffer(128);" \ - "new " #View "(ab)"); \ - CHECK(result->IsArrayBufferView()); \ - CHECK(result->Is##View()); \ - CheckInternalFieldsAreZero<v8::ArrayBufferView>(result.As<v8::View>()); \ +#define IS_ARRAY_BUFFER_VIEW_TEST(View) \ + THREADED_TEST(Is##View) { \ + LocalContext env; \ + v8::Isolate* isolate = env->GetIsolate(); \ + v8::HandleScope handle_scope(isolate); \ + \ + Local<Value> result = CompileRun( \ + "var ab = new ArrayBuffer(128);" \ + "new " #View "(ab)"); \ + CHECK(result->IsArrayBufferView()); \ + CHECK(result->Is##View()); \ + CheckInternalFieldsAreZero<v8::ArrayBufferView>(result.As<v8::View>()); \ } IS_ARRAY_BUFFER_VIEW_TEST(Uint8Array) @@ -14457,20 +16084,45 @@ THREADED_TEST(ScriptContextDependence) { LocalContext c1; v8::HandleScope scope(c1->GetIsolate()); const char *source = "foo"; - v8::Handle<v8::Script> dep = v8_compile(source); - v8::ScriptCompiler::Source script_source(v8::String::NewFromUtf8( - c1->GetIsolate(), source)); - v8::Handle<v8::UnboundScript> indep = - v8::ScriptCompiler::CompileUnbound(c1->GetIsolate(), &script_source); - c1->Global()->Set(v8::String::NewFromUtf8(c1->GetIsolate(), "foo"), - v8::Integer::New(c1->GetIsolate(), 100)); - CHECK_EQ(dep->Run()->Int32Value(), 100); - CHECK_EQ(indep->BindToCurrentContext()->Run()->Int32Value(), 100); + v8::Local<v8::Script> dep = v8_compile(source); + v8::ScriptCompiler::Source script_source( + v8::String::NewFromUtf8(c1->GetIsolate(), source, + v8::NewStringType::kNormal) + .ToLocalChecked()); + v8::Local<v8::UnboundScript> indep = + v8::ScriptCompiler::CompileUnboundScript(c1->GetIsolate(), &script_source) + .ToLocalChecked(); + c1->Global() + ->Set(c1.local(), v8::String::NewFromUtf8(c1->GetIsolate(), "foo", + v8::NewStringType::kNormal) + .ToLocalChecked(), + v8::Integer::New(c1->GetIsolate(), 100)) + .FromJust(); + CHECK_EQ( + dep->Run(c1.local()).ToLocalChecked()->Int32Value(c1.local()).FromJust(), + 100); + CHECK_EQ(indep->BindToCurrentContext() + ->Run(c1.local()) + .ToLocalChecked() + ->Int32Value(c1.local()) + .FromJust(), + 100); LocalContext c2; - c2->Global()->Set(v8::String::NewFromUtf8(c2->GetIsolate(), "foo"), - v8::Integer::New(c2->GetIsolate(), 101)); - CHECK_EQ(dep->Run()->Int32Value(), 100); - CHECK_EQ(indep->BindToCurrentContext()->Run()->Int32Value(), 101); + c2->Global() + ->Set(c2.local(), v8::String::NewFromUtf8(c2->GetIsolate(), "foo", + v8::NewStringType::kNormal) + .ToLocalChecked(), + v8::Integer::New(c2->GetIsolate(), 101)) + .FromJust(); + CHECK_EQ( + dep->Run(c2.local()).ToLocalChecked()->Int32Value(c2.local()).FromJust(), + 100); + CHECK_EQ(indep->BindToCurrentContext() + ->Run(c2.local()) + .ToLocalChecked() + ->Int32Value(c2.local()) + .FromJust(), + 101); } @@ -14479,25 +16131,27 @@ THREADED_TEST(StackTrace) { v8::HandleScope scope(context->GetIsolate()); v8::TryCatch try_catch(context->GetIsolate()); const char *source = "function foo() { FAIL.FAIL; }; foo();"; - v8::Handle<v8::String> src = - v8::String::NewFromUtf8(context->GetIsolate(), source); - v8::Handle<v8::String> origin = - v8::String::NewFromUtf8(context->GetIsolate(), "stack-trace-test"); + v8::Local<v8::String> src = v8_str(source); + v8::Local<v8::String> origin = v8_str("stack-trace-test"); v8::ScriptCompiler::Source script_source(src, v8::ScriptOrigin(origin)); - v8::ScriptCompiler::CompileUnbound(context->GetIsolate(), &script_source) - ->BindToCurrentContext() - ->Run(); + CHECK(v8::ScriptCompiler::CompileUnboundScript(context->GetIsolate(), + &script_source) + .ToLocalChecked() + ->BindToCurrentContext() + ->Run(context.local()) + .IsEmpty()); CHECK(try_catch.HasCaught()); - v8::String::Utf8Value stack(try_catch.StackTrace()); + v8::String::Utf8Value stack( + try_catch.StackTrace(context.local()).ToLocalChecked()); CHECK(strstr(*stack, "at foo (stack-trace-test") != NULL); } // Checks that a StackFrame has certain expected values. void checkStackFrame(const char* expected_script_name, - const char* expected_func_name, int expected_line_number, - int expected_column, bool is_eval, bool is_constructor, - v8::Handle<v8::StackFrame> frame) { + const char* expected_func_name, int expected_line_number, + int expected_column, bool is_eval, bool is_constructor, + v8::Local<v8::StackFrame> frame) { v8::HandleScope scope(CcTest::isolate()); v8::String::Utf8Value func_name(frame->GetFunctionName()); v8::String::Utf8Value script_name(frame->GetScriptName()); @@ -14520,12 +16174,18 @@ void AnalyzeStackInNativeCode(const v8::FunctionCallbackInfo<v8::Value>& args) { const char* origin = "capture-stack-trace-test"; const int kOverviewTest = 1; const int kDetailedTest = 2; + const int kFunctionName = 3; + const int kDisplayName = 4; + const int kFunctionNameAndDisplayName = 5; + const int kDisplayNameIsNotString = 6; + const int kFunctionNameIsNotString = 7; - DCHECK(args.Length() == 1); + CHECK(args.Length() == 1); - int testGroup = args[0]->Int32Value(); + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); + int testGroup = args[0]->Int32Value(context).FromJust(); if (testGroup == kOverviewTest) { - v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( args.GetIsolate(), 10, v8::StackTrace::kOverview); CHECK_EQ(4, stackTrace->GetFrameCount()); checkStackFrame(origin, "bar", 2, 10, false, false, @@ -14539,7 +16199,7 @@ void AnalyzeStackInNativeCode(const v8::FunctionCallbackInfo<v8::Value>& args) { CHECK(stackTrace->AsArray()->IsArray()); } else if (testGroup == kDetailedTest) { - v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( args.GetIsolate(), 10, v8::StackTrace::kDetailed); CHECK_EQ(4, stackTrace->GetFrameCount()); checkStackFrame(origin, "bat", 4, 22, false, false, @@ -14553,6 +16213,35 @@ void AnalyzeStackInNativeCode(const v8::FunctionCallbackInfo<v8::Value>& args) { checkStackFrame(origin, "", 10, 1, false, false, stackTrace->GetFrame(3)); CHECK(stackTrace->AsArray()->IsArray()); + } else if (testGroup == kFunctionName) { + v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + args.GetIsolate(), 5, v8::StackTrace::kOverview); + CHECK_EQ(3, stackTrace->GetFrameCount()); + checkStackFrame(origin, "function.name", 2, 24, false, false, + stackTrace->GetFrame(0)); + } else if (testGroup == kDisplayName) { + v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + args.GetIsolate(), 5, v8::StackTrace::kOverview); + CHECK_EQ(3, stackTrace->GetFrameCount()); + checkStackFrame(origin, "function.displayName", 2, 24, false, false, + stackTrace->GetFrame(0)); + } else if (testGroup == kFunctionNameAndDisplayName) { + v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + args.GetIsolate(), 5, v8::StackTrace::kOverview); + CHECK_EQ(3, stackTrace->GetFrameCount()); + checkStackFrame(origin, "function.displayName", 2, 24, false, false, + stackTrace->GetFrame(0)); + } else if (testGroup == kDisplayNameIsNotString) { + v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + args.GetIsolate(), 5, v8::StackTrace::kOverview); + CHECK_EQ(3, stackTrace->GetFrameCount()); + checkStackFrame(origin, "function.name", 2, 24, false, false, + stackTrace->GetFrame(0)); + } else if (testGroup == kFunctionNameIsNotString) { + v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + args.GetIsolate(), 5, v8::StackTrace::kOverview); + CHECK_EQ(3, stackTrace->GetFrameCount()); + checkStackFrame(origin, "f", 2, 24, false, false, stackTrace->GetFrame(0)); } } @@ -14563,8 +16252,7 @@ void AnalyzeStackInNativeCode(const v8::FunctionCallbackInfo<v8::Value>& args) { TEST(CaptureStackTrace) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::String> origin = - v8::String::NewFromUtf8(isolate, "capture-stack-trace-test"); + v8::Local<v8::String> origin = v8_str("capture-stack-trace-test"); Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->Set(v8_str("AnalyzeStackInNativeCode"), v8::FunctionTemplate::New(isolate, AnalyzeStackInNativeCode)); @@ -14581,14 +16269,15 @@ TEST(CaptureStackTrace) { " bar();\n" "}\n" "var x;eval('new foo();');"; - v8::Handle<v8::String> overview_src = - v8::String::NewFromUtf8(isolate, overview_source); + v8::Local<v8::String> overview_src = v8_str(overview_source); v8::ScriptCompiler::Source script_source(overview_src, v8::ScriptOrigin(origin)); - v8::Handle<Value> overview_result( - v8::ScriptCompiler::CompileUnbound(isolate, &script_source) + v8::Local<Value> overview_result( + v8::ScriptCompiler::CompileUnboundScript(isolate, &script_source) + .ToLocalChecked() ->BindToCurrentContext() - ->Run()); + ->Run(context.local()) + .ToLocalChecked()); CHECK(!overview_result.IsEmpty()); CHECK(overview_result->IsObject()); @@ -14601,27 +16290,58 @@ TEST(CaptureStackTrace) { " bat();\n" "}\n" "eval('new baz();');"; - v8::Handle<v8::String> detailed_src = - v8::String::NewFromUtf8(isolate, detailed_source); + v8::Local<v8::String> detailed_src = v8_str(detailed_source); // Make the script using a non-zero line and column offset. - v8::Handle<v8::Integer> line_offset = v8::Integer::New(isolate, 3); - v8::Handle<v8::Integer> column_offset = v8::Integer::New(isolate, 5); + v8::Local<v8::Integer> line_offset = v8::Integer::New(isolate, 3); + v8::Local<v8::Integer> column_offset = v8::Integer::New(isolate, 5); v8::ScriptOrigin detailed_origin(origin, line_offset, column_offset); v8::ScriptCompiler::Source script_source2(detailed_src, detailed_origin); - v8::Handle<v8::UnboundScript> detailed_script( - v8::ScriptCompiler::CompileUnbound(isolate, &script_source2)); - v8::Handle<Value> detailed_result( - detailed_script->BindToCurrentContext()->Run()); + v8::Local<v8::UnboundScript> detailed_script( + v8::ScriptCompiler::CompileUnboundScript(isolate, &script_source2) + .ToLocalChecked()); + v8::Local<Value> detailed_result(detailed_script->BindToCurrentContext() + ->Run(context.local()) + .ToLocalChecked()); CHECK(!detailed_result.IsEmpty()); CHECK(detailed_result->IsObject()); + + // Test using function.name and function.displayName in stack trace + const char* function_name_source = + "function bar(function_name, display_name, testGroup) {\n" + " var f = function() { AnalyzeStackInNativeCode(testGroup); };\n" + " if (function_name) {\n" + " Object.defineProperty(f, 'name', { value: function_name });\n" + " }\n" + " if (display_name) {\n" + " f.displayName = display_name;" + " }\n" + " f()\n" + "}\n" + "bar('function.name', undefined, 3);\n" + "bar(undefined, 'function.displayName', 4);\n" + "bar('function.name', 'function.displayName', 5);\n" + "bar('function.name', 239, 6);\n" + "bar(239, undefined, 7);\n"; + v8::Local<v8::String> function_name_src = + v8::String::NewFromUtf8(isolate, function_name_source, + v8::NewStringType::kNormal) + .ToLocalChecked(); + v8::ScriptCompiler::Source script_source3(function_name_src, + v8::ScriptOrigin(origin)); + v8::Local<Value> function_name_result( + v8::ScriptCompiler::CompileUnboundScript(isolate, &script_source3) + .ToLocalChecked() + ->BindToCurrentContext() + ->Run(context.local()) + .ToLocalChecked()); + CHECK(!function_name_result.IsEmpty()); } static void StackTraceForUncaughtExceptionListener( - v8::Handle<v8::Message> message, - v8::Handle<Value>) { + v8::Local<v8::Message> message, v8::Local<Value>) { report_count++; - v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace(); + v8::Local<v8::StackTrace> stack_trace = message->GetStackTrace(); CHECK_EQ(2, stack_trace->GetFrameCount()); checkStackFrame("origin", "foo", 2, 3, false, false, stack_trace->GetFrame(0)); @@ -14633,9 +16353,10 @@ static void StackTraceForUncaughtExceptionListener( TEST(CaptureStackTraceForUncaughtException) { report_count = 0; LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::V8::AddMessageListener(StackTraceForUncaughtExceptionListener); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + isolate->AddMessageListener(StackTraceForUncaughtExceptionListener); + isolate->SetCaptureStackTraceForUncaughtExceptions(true); CompileRunWithOrigin( "function foo() {\n" @@ -14646,11 +16367,12 @@ TEST(CaptureStackTraceForUncaughtException) { "};", "origin"); v8::Local<v8::Object> global = env->Global(); - Local<Value> trouble = global->Get(v8_str("bar")); + Local<Value> trouble = + global->Get(env.local(), v8_str("bar")).ToLocalChecked(); CHECK(trouble->IsFunction()); - Function::Cast(*trouble)->Call(global, 0, NULL); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(false); - v8::V8::RemoveMessageListeners(StackTraceForUncaughtExceptionListener); + CHECK(Function::Cast(*trouble)->Call(env.local(), global, 0, NULL).IsEmpty()); + isolate->SetCaptureStackTraceForUncaughtExceptions(false); + isolate->RemoveMessageListeners(StackTraceForUncaughtExceptionListener); CHECK_EQ(1, report_count); } @@ -14658,7 +16380,8 @@ TEST(CaptureStackTraceForUncaughtException) { TEST(GetStackTraceForUncaughtExceptionFromSimpleStackTrace) { report_count = 0; LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // Create an Error object first. CompileRunWithOrigin( @@ -14671,27 +16394,28 @@ TEST(GetStackTraceForUncaughtExceptionFromSimpleStackTrace) { "var e;", "origin"); v8::Local<v8::Object> global = env->Global(); - Local<Value> trouble = global->Get(v8_str("bar")); + Local<Value> trouble = + global->Get(env.local(), v8_str("bar")).ToLocalChecked(); CHECK(trouble->IsFunction()); - Function::Cast(*trouble)->Call(global, 0, NULL); + Function::Cast(*trouble)->Call(env.local(), global, 0, NULL).ToLocalChecked(); // Enable capturing detailed stack trace late, and throw the exception. // The detailed stack trace should be extracted from the simple stack. - v8::V8::AddMessageListener(StackTraceForUncaughtExceptionListener); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); + isolate->AddMessageListener(StackTraceForUncaughtExceptionListener); + isolate->SetCaptureStackTraceForUncaughtExceptions(true); CompileRunWithOrigin("throw e", "origin"); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(false); - v8::V8::RemoveMessageListeners(StackTraceForUncaughtExceptionListener); + isolate->SetCaptureStackTraceForUncaughtExceptions(false); + isolate->RemoveMessageListeners(StackTraceForUncaughtExceptionListener); CHECK_EQ(1, report_count); } TEST(CaptureStackTraceForUncaughtExceptionAndSetters) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(true, - 1024, - v8::StackTrace::kDetailed); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + isolate->SetCaptureStackTraceForUncaughtExceptions(true, 1024, + v8::StackTrace::kDetailed); CompileRun( "var setters = ['column', 'lineNumber', 'scriptName',\n" @@ -14702,13 +16426,13 @@ TEST(CaptureStackTraceForUncaughtExceptionAndSetters) { " Object.prototype.__defineSetter__(prop, function() { throw prop; });\n" "}\n"); CompileRun("throw 'exception';"); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(false); + isolate->SetCaptureStackTraceForUncaughtExceptions(false); } -static void StackTraceFunctionNameListener(v8::Handle<v8::Message> message, - v8::Handle<Value>) { - v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace(); +static void StackTraceFunctionNameListener(v8::Local<v8::Message> message, + v8::Local<Value>) { + v8::Local<v8::StackTrace> stack_trace = message->GetStackTrace(); CHECK_EQ(5, stack_trace->GetFrameCount()); checkStackFrame("origin", "foo:0", 4, 7, false, false, stack_trace->GetFrame(0)); @@ -14724,7 +16448,8 @@ static void StackTraceFunctionNameListener(v8::Handle<v8::Message> message, TEST(GetStackTraceContainsFunctionsWithFunctionName) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); CompileRunWithOrigin( "function gen(name, counter) {\n" @@ -14746,18 +16471,18 @@ TEST(GetStackTraceContainsFunctionsWithFunctionName) { "};", "origin"); - v8::V8::AddMessageListener(StackTraceFunctionNameListener); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); + isolate->AddMessageListener(StackTraceFunctionNameListener); + isolate->SetCaptureStackTraceForUncaughtExceptions(true); CompileRunWithOrigin("gen('foo', 3)();", "origin"); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(false); - v8::V8::RemoveMessageListeners(StackTraceFunctionNameListener); + isolate->SetCaptureStackTraceForUncaughtExceptions(false); + isolate->RemoveMessageListeners(StackTraceFunctionNameListener); } -static void RethrowStackTraceHandler(v8::Handle<v8::Message> message, - v8::Handle<v8::Value> data) { +static void RethrowStackTraceHandler(v8::Local<v8::Message> message, + v8::Local<v8::Value> data) { // Use the frame where JavaScript is called from. - v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace(); + v8::Local<v8::StackTrace> stack_trace = message->GetStackTrace(); CHECK(!stack_trace.IsEmpty()); int frame_count = stack_trace->GetFrameCount(); CHECK_EQ(3, frame_count); @@ -14772,7 +16497,8 @@ static void RethrowStackTraceHandler(v8::Handle<v8::Message> message, // is first thrown (not where it is rethrown). TEST(RethrowStackTrace) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // We make sure that // - the stack trace of the ReferenceError in g() is reported. // - the stack trace is not overwritten when e1 is rethrown by t(). @@ -14790,17 +16516,17 @@ TEST(RethrowStackTrace) { " t(e1); \n" " } \n" "} \n"; - v8::V8::AddMessageListener(RethrowStackTraceHandler); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); + isolate->AddMessageListener(RethrowStackTraceHandler); + isolate->SetCaptureStackTraceForUncaughtExceptions(true); CompileRun(source); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(false); - v8::V8::RemoveMessageListeners(RethrowStackTraceHandler); + isolate->SetCaptureStackTraceForUncaughtExceptions(false); + isolate->RemoveMessageListeners(RethrowStackTraceHandler); } -static void RethrowPrimitiveStackTraceHandler(v8::Handle<v8::Message> message, - v8::Handle<v8::Value> data) { - v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace(); +static void RethrowPrimitiveStackTraceHandler(v8::Local<v8::Message> message, + v8::Local<v8::Value> data) { + v8::Local<v8::StackTrace> stack_trace = message->GetStackTrace(); CHECK(!stack_trace.IsEmpty()); int frame_count = stack_trace->GetFrameCount(); CHECK_EQ(2, frame_count); @@ -14814,7 +16540,8 @@ static void RethrowPrimitiveStackTraceHandler(v8::Handle<v8::Message> message, // Test that we do not recognize identity for primitive exceptions. TEST(RethrowPrimitiveStackTrace) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); // We do not capture stack trace for non Error objects on creation time. // Instead, we capture the stack trace on last throw. const char* source = @@ -14826,18 +16553,18 @@ TEST(RethrowPrimitiveStackTrace) { "} catch (e1) { \n" " t(e1) \n" "} \n"; - v8::V8::AddMessageListener(RethrowPrimitiveStackTraceHandler); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); + isolate->AddMessageListener(RethrowPrimitiveStackTraceHandler); + isolate->SetCaptureStackTraceForUncaughtExceptions(true); CompileRun(source); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(false); - v8::V8::RemoveMessageListeners(RethrowPrimitiveStackTraceHandler); + isolate->SetCaptureStackTraceForUncaughtExceptions(false); + isolate->RemoveMessageListeners(RethrowPrimitiveStackTraceHandler); } -static void RethrowExistingStackTraceHandler(v8::Handle<v8::Message> message, - v8::Handle<v8::Value> data) { +static void RethrowExistingStackTraceHandler(v8::Local<v8::Message> message, + v8::Local<v8::Value> data) { // Use the frame where JavaScript is called from. - v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace(); + v8::Local<v8::StackTrace> stack_trace = message->GetStackTrace(); CHECK(!stack_trace.IsEmpty()); CHECK_EQ(1, stack_trace->GetFrameCount()); CHECK_EQ(1, stack_trace->GetFrame(0)->GetLineNumber()); @@ -14848,22 +16575,23 @@ static void RethrowExistingStackTraceHandler(v8::Handle<v8::Message> message, // not where it is thrown. TEST(RethrowExistingStackTrace) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); const char* source = "var e = new Error(); \n" "throw e; \n"; - v8::V8::AddMessageListener(RethrowExistingStackTraceHandler); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); + isolate->AddMessageListener(RethrowExistingStackTraceHandler); + isolate->SetCaptureStackTraceForUncaughtExceptions(true); CompileRun(source); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(false); - v8::V8::RemoveMessageListeners(RethrowExistingStackTraceHandler); + isolate->SetCaptureStackTraceForUncaughtExceptions(false); + isolate->RemoveMessageListeners(RethrowExistingStackTraceHandler); } -static void RethrowBogusErrorStackTraceHandler(v8::Handle<v8::Message> message, - v8::Handle<v8::Value> data) { +static void RethrowBogusErrorStackTraceHandler(v8::Local<v8::Message> message, + v8::Local<v8::Value> data) { // Use the frame where JavaScript is called from. - v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace(); + v8::Local<v8::StackTrace> stack_trace = message->GetStackTrace(); CHECK(!stack_trace.IsEmpty()); CHECK_EQ(1, stack_trace->GetFrameCount()); CHECK_EQ(2, stack_trace->GetFrame(0)->GetLineNumber()); @@ -14873,15 +16601,16 @@ static void RethrowBogusErrorStackTraceHandler(v8::Handle<v8::Message> message, // Test that the stack trace is captured where the bogus Error object is thrown. TEST(RethrowBogusErrorStackTrace) { LocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); const char* source = "var e = {__proto__: new Error()} \n" "throw e; \n"; - v8::V8::AddMessageListener(RethrowBogusErrorStackTraceHandler); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); + isolate->AddMessageListener(RethrowBogusErrorStackTraceHandler); + isolate->SetCaptureStackTraceForUncaughtExceptions(true); CompileRun(source); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(false); - v8::V8::RemoveMessageListeners(RethrowBogusErrorStackTraceHandler); + isolate->SetCaptureStackTraceForUncaughtExceptions(false); + isolate->RemoveMessageListeners(RethrowBogusErrorStackTraceHandler); } @@ -14895,21 +16624,28 @@ int promise_reject_column_number = -1; int promise_reject_frame_count = -1; void PromiseRejectCallback(v8::PromiseRejectMessage reject_message) { + v8::Local<v8::Object> global = CcTest::global(); + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); if (reject_message.GetEvent() == v8::kPromiseRejectWithNoHandler) { promise_reject_counter++; - CcTest::global()->Set(v8_str("rejected"), reject_message.GetPromise()); - CcTest::global()->Set(v8_str("value"), reject_message.GetValue()); - v8::Handle<v8::Message> message = - v8::Exception::CreateMessage(reject_message.GetValue()); - v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace(); + global->Set(context, v8_str("rejected"), reject_message.GetPromise()) + .FromJust(); + global->Set(context, v8_str("value"), reject_message.GetValue()).FromJust(); + v8::Local<v8::Message> message = v8::Exception::CreateMessage( + CcTest::isolate(), reject_message.GetValue()); + v8::Local<v8::StackTrace> stack_trace = message->GetStackTrace(); - promise_reject_msg_line_number = message->GetLineNumber(); - promise_reject_msg_column_number = message->GetStartColumn() + 1; + promise_reject_msg_line_number = message->GetLineNumber(context).FromJust(); + promise_reject_msg_column_number = + message->GetStartColumn(context).FromJust() + 1; if (!stack_trace.IsEmpty()) { promise_reject_frame_count = stack_trace->GetFrameCount(); if (promise_reject_frame_count > 0) { - CHECK(stack_trace->GetFrame(0)->GetScriptName()->Equals(v8_str("pro"))); + CHECK(stack_trace->GetFrame(0) + ->GetScriptName() + ->Equals(context, v8_str("pro")) + .FromJust()); promise_reject_line_number = stack_trace->GetFrame(0)->GetLineNumber(); promise_reject_column_number = stack_trace->GetFrame(0)->GetColumn(); } else { @@ -14919,19 +16655,25 @@ void PromiseRejectCallback(v8::PromiseRejectMessage reject_message) { } } else { promise_revoke_counter++; - CcTest::global()->Set(v8_str("revoked"), reject_message.GetPromise()); + global->Set(context, v8_str("revoked"), reject_message.GetPromise()) + .FromJust(); CHECK(reject_message.GetValue().IsEmpty()); } } -v8::Handle<v8::Promise> GetPromise(const char* name) { - return v8::Handle<v8::Promise>::Cast(CcTest::global()->Get(v8_str(name))); +v8::Local<v8::Promise> GetPromise(const char* name) { + return v8::Local<v8::Promise>::Cast( + CcTest::global() + ->Get(CcTest::isolate()->GetCurrentContext(), v8_str(name)) + .ToLocalChecked()); } -v8::Handle<v8::Value> RejectValue() { - return CcTest::global()->Get(v8_str("value")); +v8::Local<v8::Value> RejectValue() { + return CcTest::global() + ->Get(CcTest::isolate()->GetCurrentContext(), v8_str("value")) + .ToLocalChecked(); } @@ -14943,9 +16685,12 @@ void ResetPromiseStates() { promise_reject_line_number = -1; promise_reject_column_number = -1; promise_reject_frame_count = -1; - CcTest::global()->Set(v8_str("rejected"), v8_str("")); - CcTest::global()->Set(v8_str("value"), v8_str("")); - CcTest::global()->Set(v8_str("revoked"), v8_str("")); + + v8::Local<v8::Object> global = CcTest::global(); + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); + global->Set(context, v8_str("rejected"), v8_str("")).FromJust(); + global->Set(context, v8_str("value"), v8_str("")).FromJust(); + global->Set(context, v8_str("revoked"), v8_str("")).FromJust(); } @@ -14984,8 +16729,9 @@ TEST(PromiseRejectCallback) { CHECK_EQ(1, promise_reject_counter); CHECK_EQ(0, promise_revoke_counter); CHECK_EQ(v8::kPromiseRejectWithNoHandler, reject_event); - CHECK(GetPromise("rejected")->Equals(GetPromise("p1"))); - CHECK(RejectValue()->Equals(v8_str("ppp"))); + CHECK( + GetPromise("rejected")->Equals(env.local(), GetPromise("p1")).FromJust()); + CHECK(RejectValue()->Equals(env.local(), v8_str("ppp")).FromJust()); // Reject p0 again. Callback is not triggered again. CompileRun("reject();"); @@ -15001,9 +16747,11 @@ TEST(PromiseRejectCallback) { CHECK(!GetPromise("p2")->HasHandler()); CHECK_EQ(2, promise_reject_counter); CHECK_EQ(1, promise_revoke_counter); - CHECK(GetPromise("rejected")->Equals(GetPromise("p2"))); - CHECK(RejectValue()->Equals(v8_str("ppp"))); - CHECK(GetPromise("revoked")->Equals(GetPromise("p1"))); + CHECK( + GetPromise("rejected")->Equals(env.local(), GetPromise("p2")).FromJust()); + CHECK(RejectValue()->Equals(env.local(), v8_str("ppp")).FromJust()); + CHECK( + GetPromise("revoked")->Equals(env.local(), GetPromise("p1")).FromJust()); ResetPromiseStates(); @@ -15049,9 +16797,11 @@ TEST(PromiseRejectCallback) { CHECK(GetPromise("q_")->HasHandler()); CHECK_EQ(2, promise_reject_counter); CHECK_EQ(1, promise_revoke_counter); - CHECK(GetPromise("rejected")->Equals(GetPromise("q2"))); - CHECK(GetPromise("revoked")->Equals(GetPromise("q_"))); - CHECK(RejectValue()->Equals(v8_str("qqq"))); + CHECK( + GetPromise("rejected")->Equals(env.local(), GetPromise("q2")).FromJust()); + CHECK( + GetPromise("revoked")->Equals(env.local(), GetPromise("q_")).FromJust()); + CHECK(RejectValue()->Equals(env.local(), v8_str("qqq")).FromJust()); // Add a reject handler to the resolved q1, which rejects by throwing. CompileRun( @@ -15066,8 +16816,9 @@ TEST(PromiseRejectCallback) { CHECK(!GetPromise("q3")->HasHandler()); CHECK_EQ(3, promise_reject_counter); CHECK_EQ(1, promise_revoke_counter); - CHECK(GetPromise("rejected")->Equals(GetPromise("q3"))); - CHECK(RejectValue()->Equals(v8_str("qqqq"))); + CHECK( + GetPromise("rejected")->Equals(env.local(), GetPromise("q3")).FromJust()); + CHECK(RejectValue()->Equals(env.local(), v8_str("qqqq")).FromJust()); ResetPromiseStates(); @@ -15097,8 +16848,9 @@ TEST(PromiseRejectCallback) { CHECK(!GetPromise("r3")->HasHandler()); CHECK_EQ(1, promise_reject_counter); CHECK_EQ(0, promise_revoke_counter); - CHECK(GetPromise("rejected")->Equals(GetPromise("r2"))); - CHECK(RejectValue()->Equals(v8_str("rrr"))); + CHECK( + GetPromise("rejected")->Equals(env.local(), GetPromise("r2")).FromJust()); + CHECK(RejectValue()->Equals(env.local(), v8_str("rrr")).FromJust()); // Add reject handler to r2. CompileRun("var r4 = r2.catch(function() {});"); @@ -15109,8 +16861,9 @@ TEST(PromiseRejectCallback) { CHECK(!GetPromise("r4")->HasHandler()); CHECK_EQ(1, promise_reject_counter); CHECK_EQ(1, promise_revoke_counter); - CHECK(GetPromise("revoked")->Equals(GetPromise("r2"))); - CHECK(RejectValue()->Equals(v8_str("rrr"))); + CHECK( + GetPromise("revoked")->Equals(env.local(), GetPromise("r2")).FromJust()); + CHECK(RejectValue()->Equals(env.local(), v8_str("rrr")).FromJust()); // Add reject handlers to r4. CompileRun("var r5 = r4.then(function() {}, function() {});"); @@ -15150,10 +16903,10 @@ TEST(PromiseRejectCallback) { CHECK(!GetPromise("s3")->HasHandler()); CHECK_EQ(3, promise_reject_counter); CHECK_EQ(0, promise_revoke_counter); - CHECK(RejectValue()->Equals(v8_str("sss"))); + CHECK(RejectValue()->Equals(env.local(), v8_str("sss")).FromJust()); // Test stack frames. - V8::SetCaptureStackTraceForUncaughtExceptions(true); + env->GetIsolate()->SetCaptureStackTraceForUncaughtExceptions(true); ResetPromiseStates(); @@ -15269,15 +17022,15 @@ TEST(PromiseRejectCallback) { void AnalyzeStackOfEvalWithSourceURL( const v8::FunctionCallbackInfo<v8::Value>& args) { v8::HandleScope scope(args.GetIsolate()); - v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( args.GetIsolate(), 10, v8::StackTrace::kDetailed); CHECK_EQ(5, stackTrace->GetFrameCount()); - v8::Handle<v8::String> url = v8_str("eval_url"); + v8::Local<v8::String> url = v8_str("eval_url"); for (int i = 0; i < 3; i++) { - v8::Handle<v8::String> name = + v8::Local<v8::String> name = stackTrace->GetFrame(i)->GetScriptNameOrSourceURL(); CHECK(!name.IsEmpty()); - CHECK(url->Equals(name)); + CHECK(url->Equals(args.GetIsolate()->GetCurrentContext(), name).FromJust()); } } @@ -15307,8 +17060,6 @@ TEST(SourceURLInStackTrace) { i::ScopedVector<char> code(1024); i::SNPrintF(code, source, "//# sourceURL=eval_url"); CHECK(CompileRun(code.start())->IsUndefined()); - i::SNPrintF(code, source, "//@ sourceURL=eval_url"); - CHECK(CompileRun(code.start())->IsUndefined()); } @@ -15317,7 +17068,7 @@ static int scriptIdInStack[2]; void AnalyzeScriptIdInStack( const v8::FunctionCallbackInfo<v8::Value>& args) { v8::HandleScope scope(args.GetIsolate()); - v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( args.GetIsolate(), 10, v8::StackTrace::kScriptId); CHECK_EQ(2, stackTrace->GetFrameCount()); for (int i = 0; i < 2; i++) { @@ -15334,14 +17085,13 @@ TEST(ScriptIdInStackTrace) { v8::FunctionTemplate::New(isolate, AnalyzeScriptIdInStack)); LocalContext context(0, templ); - v8::Handle<v8::String> scriptSource = v8::String::NewFromUtf8( - isolate, - "function foo() {\n" - " AnalyzeScriptIdInStack();" - "}\n" - "foo();\n"); + v8::Local<v8::String> scriptSource = v8_str( + "function foo() {\n" + " AnalyzeScriptIdInStack();" + "}\n" + "foo();\n"); v8::Local<v8::Script> script = CompileWithOrigin(scriptSource, "test"); - script->Run(); + script->Run(context.local()).ToLocalChecked(); for (int i = 0; i < 2; i++) { CHECK(scriptIdInStack[i] != v8::Message::kNoScriptIdInfo); CHECK_EQ(scriptIdInStack[i], script->GetUnboundScript()->GetId()); @@ -15352,15 +17102,15 @@ TEST(ScriptIdInStackTrace) { void AnalyzeStackOfInlineScriptWithSourceURL( const v8::FunctionCallbackInfo<v8::Value>& args) { v8::HandleScope scope(args.GetIsolate()); - v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( args.GetIsolate(), 10, v8::StackTrace::kDetailed); CHECK_EQ(4, stackTrace->GetFrameCount()); - v8::Handle<v8::String> url = v8_str("source_url"); + v8::Local<v8::String> url = v8_str("source_url"); for (int i = 0; i < 3; i++) { - v8::Handle<v8::String> name = + v8::Local<v8::String> name = stackTrace->GetFrame(i)->GetScriptNameOrSourceURL(); CHECK(!name.IsEmpty()); - CHECK(url->Equals(name)); + CHECK(url->Equals(args.GetIsolate()->GetCurrentContext(), name).FromJust()); } } @@ -15390,23 +17140,21 @@ TEST(InlineScriptWithSourceURLInStackTrace) { i::ScopedVector<char> code(1024); i::SNPrintF(code, source, "//# sourceURL=source_url"); CHECK(CompileRunWithOrigin(code.start(), "url", 0, 1)->IsUndefined()); - i::SNPrintF(code, source, "//@ sourceURL=source_url"); - CHECK(CompileRunWithOrigin(code.start(), "url", 0, 1)->IsUndefined()); } void AnalyzeStackOfDynamicScriptWithSourceURL( const v8::FunctionCallbackInfo<v8::Value>& args) { v8::HandleScope scope(args.GetIsolate()); - v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( + v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace( args.GetIsolate(), 10, v8::StackTrace::kDetailed); CHECK_EQ(4, stackTrace->GetFrameCount()); - v8::Handle<v8::String> url = v8_str("source_url"); + v8::Local<v8::String> url = v8_str("source_url"); for (int i = 0; i < 3; i++) { - v8::Handle<v8::String> name = + v8::Local<v8::String> name = stackTrace->GetFrame(i)->GetScriptNameOrSourceURL(); CHECK(!name.IsEmpty()); - CHECK(url->Equals(name)); + CHECK(url->Equals(args.GetIsolate()->GetCurrentContext(), name).FromJust()); } } @@ -15436,8 +17184,6 @@ TEST(DynamicWithSourceURLInStackTrace) { i::ScopedVector<char> code(1024); i::SNPrintF(code, source, "//# sourceURL=source_url"); CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined()); - i::SNPrintF(code, source, "//@ sourceURL=source_url"); - CHECK(CompileRunWithOrigin(code.start(), "url", 0, 0)->IsUndefined()); } @@ -15459,7 +17205,8 @@ TEST(DynamicWithSourceURLInStackTraceString) { v8::TryCatch try_catch(context->GetIsolate()); CompileRunWithOrigin(code.start(), "", 0, 0); CHECK(try_catch.HasCaught()); - v8::String::Utf8Value stack(try_catch.StackTrace()); + v8::String::Utf8Value stack( + try_catch.StackTrace(context.local()).ToLocalChecked()); CHECK(strstr(*stack, "at foo (source_url:3:5)") != NULL); } @@ -15482,8 +17229,7 @@ TEST(EvalWithSourceURLInMessageScriptResourceNameOrSourceURL) { CHECK(try_catch.HasCaught()); Local<v8::Message> message = try_catch.Message(); - Handle<Value> sourceURL = - message->GetScriptOrigin().ResourceName(); + Local<Value> sourceURL = message->GetScriptOrigin().ResourceName(); CHECK_EQ(0, strcmp(*v8::String::Utf8Value(sourceURL), "source_url")); } @@ -15506,8 +17252,7 @@ TEST(RecursionWithSourceURLInMessageScriptResourceNameOrSourceURL) { CHECK(try_catch.HasCaught()); Local<v8::Message> message = try_catch.Message(); - Handle<Value> sourceURL = - message->GetScriptOrigin().ResourceName(); + Local<Value> sourceURL = message->GetScriptOrigin().ResourceName(); CHECK_EQ(0, strcmp(*v8::String::Utf8Value(sourceURL), "source_url")); } @@ -15597,8 +17342,10 @@ TEST(SetStackLimit) { v8::HandleScope scope(env->GetIsolate()); Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(env->GetIsolate(), GetStackLimitCallback); - Local<Function> fun = fun_templ->GetFunction(); - env->Global()->Set(v8_str("get_stack_limit"), fun); + Local<Function> fun = fun_templ->GetFunction(env.local()).ToLocalChecked(); + CHECK(env->Global() + ->Set(env.local(), v8_str("get_stack_limit"), fun) + .FromJust()); CompileRun("get_stack_limit();"); CHECK(stack_limit == set_limit); @@ -15619,8 +17366,10 @@ TEST(SetStackLimitInThread) { LocalContext env; Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(CcTest::isolate(), GetStackLimitCallback); - Local<Function> fun = fun_templ->GetFunction(); - env->Global()->Set(v8_str("get_stack_limit"), fun); + Local<Function> fun = fun_templ->GetFunction(env.local()).ToLocalChecked(); + CHECK(env->Global() + ->Set(env.local(), v8_str("get_stack_limit"), fun) + .FromJust()); CompileRun("get_stack_limit();"); CHECK(stack_limit == set_limit); @@ -15653,7 +17402,7 @@ class VisitorImpl : public v8::ExternalResourceVisitor { } } virtual ~VisitorImpl() {} - virtual void VisitExternalString(v8::Handle<v8::String> string) { + virtual void VisitExternalString(v8::Local<v8::String> string) { if (!string->IsExternal()) { CHECK(string->IsExternalOneByte()); return; @@ -15685,7 +17434,9 @@ TEST(ExternalizeOldSpaceTwoByteCons) { LocalContext env; v8::HandleScope scope(isolate); v8::Local<v8::String> cons = - CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString(isolate); + CompileRun("'Romeo Montague ' + 'Juliet Capulet'") + ->ToString(env.local()) + .ToLocalChecked(); CHECK(v8::Utils::OpenHandle(*cons)->IsConsString()); CcTest::heap()->CollectAllAvailableGarbage(); CHECK(CcTest::heap()->old_space()->Contains(*v8::Utils::OpenHandle(*cons))); @@ -15707,7 +17458,9 @@ TEST(ExternalizeOldSpaceOneByteCons) { LocalContext env; v8::HandleScope scope(isolate); v8::Local<v8::String> cons = - CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString(isolate); + CompileRun("'Romeo Montague ' + 'Juliet Capulet'") + ->ToString(env.local()) + .ToLocalChecked(); CHECK(v8::Utils::OpenHandle(*cons)->IsConsString()); CcTest::heap()->CollectAllAvailableGarbage(); CHECK(CcTest::heap()->old_space()->Contains(*v8::Utils::OpenHandle(*cons))); @@ -15733,21 +17486,26 @@ TEST(VisitExternalStrings) { TestResource* resource[4]; resource[0] = new TestResource(two_byte_string); v8::Local<v8::String> string0 = - v8::String::NewExternal(env->GetIsolate(), resource[0]); + v8::String::NewExternalTwoByte(env->GetIsolate(), resource[0]) + .ToLocalChecked(); resource[1] = new TestResource(two_byte_string, NULL, false); v8::Local<v8::String> string1 = - v8::String::NewExternal(env->GetIsolate(), resource[1]); + v8::String::NewExternalTwoByte(env->GetIsolate(), resource[1]) + .ToLocalChecked(); // Externalized symbol. resource[2] = new TestResource(two_byte_string, NULL, false); - v8::Local<v8::String> string2 = v8::String::NewFromUtf8( - env->GetIsolate(), string, v8::String::kInternalizedString); + v8::Local<v8::String> string2 = + v8::String::NewFromUtf8(env->GetIsolate(), string, + v8::NewStringType::kInternalized) + .ToLocalChecked(); CHECK(string2->MakeExternal(resource[2])); // Symbolized External. resource[3] = new TestResource(AsciiToTwoByteString("Some other string")); v8::Local<v8::String> string3 = - v8::String::NewExternal(env->GetIsolate(), resource[3]); + v8::String::NewExternalTwoByte(env->GetIsolate(), resource[3]) + .ToLocalChecked(); CcTest::heap()->CollectAllAvailableGarbage(); // Tenure string. // Turn into a symbol. i::Handle<i::String> string3_i = v8::Utils::OpenHandle(*string3); @@ -15762,7 +17520,7 @@ TEST(VisitExternalStrings) { CHECK(string3->IsExternal()); VisitorImpl visitor(resource); - v8::V8::VisitExternalResources(&visitor); + isolate->VisitExternalResources(&visitor); visitor.CheckVisitedResources(); } @@ -15777,7 +17535,8 @@ TEST(ExternalStringCollectedAtTearDown) { const char* s = "One string to test them all, one string to find them."; TestOneByteResource* inscription = new TestOneByteResource(i::StrDup(s), &destroyed); - v8::Local<v8::String> ring = v8::String::NewExternal(isolate, inscription); + v8::Local<v8::String> ring = + v8::String::NewExternalOneByte(isolate, inscription).ToLocalChecked(); // Ring is still alive. Orcs are roaming freely across our lands. CHECK_EQ(0, destroyed); USE(ring); @@ -15801,7 +17560,8 @@ TEST(ExternalInternalizedStringCollectedAtTearDown) { const char* s = "One string to test them all"; TestOneByteResource* inscription = new TestOneByteResource(i::StrDup(s), &destroyed); - v8::Local<v8::String> ring = CompileRun("ring")->ToString(isolate); + v8::Local<v8::String> ring = + CompileRun("ring")->ToString(env.local()).ToLocalChecked(); CHECK(v8::Utils::OpenHandle(*ring)->IsInternalizedString()); ring->MakeExternal(inscription); // Ring is still alive. Orcs are roaming freely across our lands. @@ -15917,8 +17677,8 @@ THREADED_TEST(QuietSignalingNaNs) { double test_value = test_values[i]; // Check that Number::New preserves non-NaNs and quiets SNaNs. - v8::Handle<v8::Value> number = v8::Number::New(isolate, test_value); - double stored_number = number->NumberValue(); + v8::Local<v8::Value> number = v8::Number::New(isolate, test_value); + double stored_number = number->NumberValue(context.local()).FromJust(); if (!std::isnan(test_value)) { CHECK_EQ(test_value, stored_number); } else { @@ -15937,10 +17697,10 @@ THREADED_TEST(QuietSignalingNaNs) { // Check that Date::New preserves non-NaNs in the date range and // quiets SNaNs. - v8::Handle<v8::Value> date = - v8::Date::New(isolate, test_value); + v8::Local<v8::Value> date = + v8::Date::New(context.local(), test_value).ToLocalChecked(); double expected_stored_date = DoubleToDateTime(test_value); - double stored_date = date->NumberValue(); + double stored_date = date->NumberValue(context.local()).FromJust(); if (!std::isnan(expected_stored_date)) { CHECK_EQ(expected_stored_date, stored_date); } else { @@ -15964,7 +17724,8 @@ static void SpaghettiIncident( const v8::FunctionCallbackInfo<v8::Value>& args) { v8::HandleScope scope(args.GetIsolate()); v8::TryCatch tc(args.GetIsolate()); - v8::Handle<v8::String> str(args[0]->ToString(args.GetIsolate())); + v8::MaybeLocal<v8::String> str( + args[0]->ToString(args.GetIsolate()->GetCurrentContext())); USE(str); if (tc.HasCaught()) tc.ReThrow(); @@ -15977,9 +17738,12 @@ THREADED_TEST(SpaghettiStackReThrow) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); LocalContext context; - context->Global()->Set( - v8::String::NewFromUtf8(isolate, "s"), - v8::FunctionTemplate::New(isolate, SpaghettiIncident)->GetFunction()); + context->Global() + ->Set(context.local(), v8_str("s"), + v8::FunctionTemplate::New(isolate, SpaghettiIncident) + ->GetFunction(context.local()) + .ToLocalChecked()) + .FromJust(); v8::TryCatch try_catch(isolate); CompileRun( "var i = 0;" @@ -16020,7 +17784,7 @@ TEST(Regress528) { v8::Local<Context> context = Context::New(isolate); context->Enter(); - Local<v8::String> obj = v8::String::NewFromUtf8(isolate, ""); + Local<v8::String> obj = v8_str(""); context->SetEmbedderData(0, obj); CompileRun(source_simple); context->Exit(); @@ -16069,9 +17833,9 @@ TEST(Regress528) { v8::TryCatch try_catch(isolate); CompileRun(source_exception); CHECK(try_catch.HasCaught()); - v8::Handle<v8::Message> message = try_catch.Message(); + v8::Local<v8::Message> message = try_catch.Message(); CHECK(!message.IsEmpty()); - CHECK_EQ(1, message->GetLineNumber()); + CHECK_EQ(1, message->GetLineNumber(context).FromJust()); context->Exit(); } isolate->ContextDisposedNotification(); @@ -16093,24 +17857,26 @@ THREADED_TEST(ScriptOrigin) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); v8::ScriptOrigin origin = v8::ScriptOrigin( - v8::String::NewFromUtf8(env->GetIsolate(), "test"), - v8::Integer::New(env->GetIsolate(), 1), + v8_str("test"), v8::Integer::New(env->GetIsolate(), 1), v8::Integer::New(env->GetIsolate(), 1), v8::True(env->GetIsolate()), - v8::Handle<v8::Integer>(), v8::True(env->GetIsolate()), - v8::String::NewFromUtf8(env->GetIsolate(), "http://sourceMapUrl"), - v8::True(env->GetIsolate())); - v8::Handle<v8::String> script = v8::String::NewFromUtf8( - env->GetIsolate(), "function f() {}\n\nfunction g() {}"); - v8::Script::Compile(script, &origin)->Run(); + v8::Local<v8::Integer>(), v8::True(env->GetIsolate()), + v8_str("http://sourceMapUrl"), v8::True(env->GetIsolate())); + v8::Local<v8::String> script = v8_str("function f() {}\n\nfunction g() {}"); + v8::Script::Compile(env.local(), script, &origin) + .ToLocalChecked() + ->Run(env.local()) + .ToLocalChecked(); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global()->Get(env.local(), v8_str("f")).ToLocalChecked()); v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); + env->Global()->Get(env.local(), v8_str("g")).ToLocalChecked()); v8::ScriptOrigin script_origin_f = f->GetScriptOrigin(); CHECK_EQ(0, strcmp("test", *v8::String::Utf8Value(script_origin_f.ResourceName()))); - CHECK_EQ(1, script_origin_f.ResourceLineOffset()->Int32Value()); + CHECK_EQ( + 1, + script_origin_f.ResourceLineOffset()->Int32Value(env.local()).FromJust()); CHECK(script_origin_f.Options().IsSharedCrossOrigin()); CHECK(script_origin_f.Options().IsEmbedderDebugScript()); CHECK(script_origin_f.Options().IsOpaque()); @@ -16122,7 +17888,9 @@ THREADED_TEST(ScriptOrigin) { v8::ScriptOrigin script_origin_g = g->GetScriptOrigin(); CHECK_EQ(0, strcmp("test", *v8::String::Utf8Value(script_origin_g.ResourceName()))); - CHECK_EQ(1, script_origin_g.ResourceLineOffset()->Int32Value()); + CHECK_EQ( + 1, + script_origin_g.ResourceLineOffset()->Int32Value(env.local()).FromJust()); CHECK(script_origin_g.Options().IsSharedCrossOrigin()); CHECK(script_origin_g.Options().IsEmbedderDebugScript()); CHECK(script_origin_g.Options().IsOpaque()); @@ -16134,19 +17902,98 @@ THREADED_TEST(ScriptOrigin) { THREADED_TEST(FunctionGetInferredName) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); - v8::Handle<v8::String> script = v8::String::NewFromUtf8( - env->GetIsolate(), - "var foo = { bar : { baz : function() {}}}; var f = foo.bar.baz;"); - v8::Script::Compile(script, &origin)->Run(); + v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("test")); + v8::Local<v8::String> script = + v8_str("var foo = { bar : { baz : function() {}}}; var f = foo.bar.baz;"); + v8::Script::Compile(env.local(), script, &origin) + .ToLocalChecked() + ->Run(env.local()) + .ToLocalChecked(); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global()->Get(env.local(), v8_str("f")).ToLocalChecked()); CHECK_EQ(0, strcmp("foo.bar.baz", *v8::String::Utf8Value(f->GetInferredName()))); } +THREADED_TEST(FunctionGetDebugName) { + LocalContext env; + v8::HandleScope scope(env->GetIsolate()); + const char* code = + "var error = false;" + "function a() { this.x = 1; };" + "a.displayName = 'display_a';" + "var b = (function() {" + " var f = function() { this.x = 2; };" + " f.displayName = 'display_b';" + " return f;" + "})();" + "var c = function() {};" + "c.__defineGetter__('displayName', function() {" + " error = true;" + " throw new Error();" + "});" + "function d() {};" + "d.__defineGetter__('displayName', function() {" + " error = true;" + " return 'wrong_display_name';" + "});" + "function e() {};" + "e.displayName = 'wrong_display_name';" + "e.__defineSetter__('displayName', function() {" + " error = true;" + " throw new Error();" + "});" + "function f() {};" + "f.displayName = { 'foo': 6, toString: function() {" + " error = true;" + " return 'wrong_display_name';" + "}};" + "var g = function() {" + " arguments.callee.displayName = 'set_in_runtime';" + "}; g();" + "var h = function() {};" + "h.displayName = 'displayName';" + "Object.defineProperty(h, 'name', { value: 'function.name' });" + "var i = function() {};" + "i.displayName = 239;" + "Object.defineProperty(i, 'name', { value: 'function.name' });" + "var j = function() {};" + "Object.defineProperty(j, 'name', { value: 'function.name' });" + "var foo = { bar : { baz : function() {}}}; var k = foo.bar.baz;"; + v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("test")); + v8::Script::Compile(env.local(), v8_str(code), &origin) + .ToLocalChecked() + ->Run(env.local()) + .ToLocalChecked(); + v8::Local<v8::Value> error = + env->Global()->Get(env.local(), v8_str("error")).ToLocalChecked(); + CHECK_EQ(false, error->BooleanValue(env.local()).FromJust()); + const char* functions[] = {"a", "display_a", + "b", "display_b", + "c", "c", + "d", "d", + "e", "e", + "f", "f", + "g", "set_in_runtime", + "h", "displayName", + "i", "function.name", + "j", "function.name", + "k", "foo.bar.baz"}; + for (size_t i = 0; i < sizeof(functions) / sizeof(functions[0]) / 2; ++i) { + v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( + env->Global() + ->Get(env.local(), + v8::String::NewFromUtf8(env->GetIsolate(), functions[i * 2], + v8::NewStringType::kNormal) + .ToLocalChecked()) + .ToLocalChecked()); + CHECK_EQ(0, strcmp(functions[i * 2 + 1], + *v8::String::Utf8Value(f->GetDebugName()))); + } +} + + THREADED_TEST(FunctionGetDisplayName) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); @@ -16182,27 +18029,28 @@ THREADED_TEST(FunctionGetDisplayName) { "var g = function() {" " arguments.callee.displayName = 'set_in_runtime';" "}; g();"; - v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), code), &origin) - ->Run(); + v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("test")); + v8::Script::Compile(env.local(), v8_str(code), &origin) + .ToLocalChecked() + ->Run(env.local()) + .ToLocalChecked(); v8::Local<v8::Value> error = - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "error")); + env->Global()->Get(env.local(), v8_str("error")).ToLocalChecked(); v8::Local<v8::Function> a = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "a"))); + env->Global()->Get(env.local(), v8_str("a")).ToLocalChecked()); v8::Local<v8::Function> b = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "b"))); + env->Global()->Get(env.local(), v8_str("b")).ToLocalChecked()); v8::Local<v8::Function> c = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "c"))); + env->Global()->Get(env.local(), v8_str("c")).ToLocalChecked()); v8::Local<v8::Function> d = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "d"))); + env->Global()->Get(env.local(), v8_str("d")).ToLocalChecked()); v8::Local<v8::Function> e = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "e"))); + env->Global()->Get(env.local(), v8_str("e")).ToLocalChecked()); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global()->Get(env.local(), v8_str("f")).ToLocalChecked()); v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); - CHECK_EQ(false, error->BooleanValue()); + env->Global()->Get(env.local(), v8_str("g")).ToLocalChecked()); + CHECK_EQ(false, error->BooleanValue(env.local()).FromJust()); CHECK_EQ(0, strcmp("display_a", *v8::String::Utf8Value(a->GetDisplayName()))); CHECK_EQ(0, strcmp("display_b", *v8::String::Utf8Value(b->GetDisplayName()))); CHECK(c->GetDisplayName()->IsUndefined()); @@ -16217,15 +18065,16 @@ THREADED_TEST(FunctionGetDisplayName) { THREADED_TEST(ScriptLineNumber) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); - v8::Handle<v8::String> script = v8::String::NewFromUtf8( - env->GetIsolate(), "function f() {}\n\nfunction g() {}"); - v8::Script::Compile(script, &origin)->Run(); + v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("test")); + v8::Local<v8::String> script = v8_str("function f() {}\n\nfunction g() {}"); + v8::Script::Compile(env.local(), script, &origin) + .ToLocalChecked() + ->Run(env.local()) + .ToLocalChecked(); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global()->Get(env.local(), v8_str("f")).ToLocalChecked()); v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); + env->Global()->Get(env.local(), v8_str("g")).ToLocalChecked()); CHECK_EQ(0, f->GetScriptLineNumber()); CHECK_EQ(2, g->GetScriptLineNumber()); } @@ -16236,16 +18085,18 @@ THREADED_TEST(ScriptColumnNumber) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::NewFromUtf8(isolate, "test"), - v8::Integer::New(isolate, 3), + v8::ScriptOrigin(v8_str("test"), v8::Integer::New(isolate, 3), v8::Integer::New(isolate, 2)); - v8::Handle<v8::String> script = v8::String::NewFromUtf8( - isolate, "function foo() {}\n\n function bar() {}"); - v8::Script::Compile(script, &origin)->Run(); + v8::Local<v8::String> script = + v8_str("function foo() {}\n\n function bar() {}"); + v8::Script::Compile(env.local(), script, &origin) + .ToLocalChecked() + ->Run(env.local()) + .ToLocalChecked(); v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(isolate, "foo"))); + env->Global()->Get(env.local(), v8_str("foo")).ToLocalChecked()); v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(isolate, "bar"))); + env->Global()->Get(env.local(), v8_str("bar")).ToLocalChecked()); CHECK_EQ(14, foo->GetScriptColumnNumber()); CHECK_EQ(17, bar->GetScriptColumnNumber()); } @@ -16274,17 +18125,17 @@ THREADED_TEST(FunctionGetScriptId) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::NewFromUtf8(isolate, "test"), - v8::Integer::New(isolate, 3), + v8::ScriptOrigin(v8_str("test"), v8::Integer::New(isolate, 3), v8::Integer::New(isolate, 2)); - v8::Handle<v8::String> scriptSource = v8::String::NewFromUtf8( - isolate, "function foo() {}\n\n function bar() {}"); - v8::Local<v8::Script> script(v8::Script::Compile(scriptSource, &origin)); - script->Run(); + v8::Local<v8::String> scriptSource = + v8_str("function foo() {}\n\n function bar() {}"); + v8::Local<v8::Script> script( + v8::Script::Compile(env.local(), scriptSource, &origin).ToLocalChecked()); + script->Run(env.local()).ToLocalChecked(); v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(isolate, "foo"))); + env->Global()->Get(env.local(), v8_str("foo")).ToLocalChecked()); v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(isolate, "bar"))); + env->Global()->Get(env.local(), v8_str("bar")).ToLocalChecked()); CHECK_EQ(script->GetUnboundScript()->GetId(), foo->ScriptId()); CHECK_EQ(script->GetUnboundScript()->GetId(), bar->ScriptId()); } @@ -16293,24 +18144,27 @@ THREADED_TEST(FunctionGetScriptId) { THREADED_TEST(FunctionGetBoundFunction) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::NewFromUtf8( - env->GetIsolate(), "test")); - v8::Handle<v8::String> script = v8::String::NewFromUtf8( - env->GetIsolate(), + v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("test")); + v8::Local<v8::String> script = v8_str( "var a = new Object();\n" "a.x = 1;\n" "function f () { return this.x };\n" "var g = f.bind(a);\n" "var b = g();"); - v8::Script::Compile(script, &origin)->Run(); + v8::Script::Compile(env.local(), script, &origin) + .ToLocalChecked() + ->Run(env.local()) + .ToLocalChecked(); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global()->Get(env.local(), v8_str("f")).ToLocalChecked()); v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); + env->Global()->Get(env.local(), v8_str("g")).ToLocalChecked()); CHECK(g->GetBoundFunction()->IsFunction()); Local<v8::Function> original_function = Local<v8::Function>::Cast( g->GetBoundFunction()); - CHECK(f->GetName()->Equals(original_function->GetName())); + CHECK(f->GetName() + ->Equals(env.local(), original_function->GetName()) + .FromJust()); CHECK_EQ(f->GetScriptLineNumber(), original_function->GetScriptLineNumber()); CHECK_EQ(f->GetScriptColumnNumber(), original_function->GetScriptColumnNumber()); @@ -16332,7 +18186,9 @@ static void SetterWhichSetsYOnThisTo23( const v8::PropertyCallbackInfo<void>& info) { CHECK(v8::Utils::OpenHandle(*info.This())->IsJSObject()); CHECK(v8::Utils::OpenHandle(*info.Holder())->IsJSObject()); - Local<Object>::Cast(info.This())->Set(v8_str("y"), v8_num(23)); + Local<Object>::Cast(info.This()) + ->Set(info.GetIsolate()->GetCurrentContext(), v8_str("y"), v8_num(23)) + .FromJust(); } @@ -16340,7 +18196,10 @@ void FooGetInterceptor(Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { CHECK(v8::Utils::OpenHandle(*info.This())->IsJSObject()); CHECK(v8::Utils::OpenHandle(*info.Holder())->IsJSObject()); - if (!name->Equals(v8_str("foo"))) return; + if (!name->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("foo")) + .FromJust()) { + return; + } info.GetReturnValue().Set(v8_num(42)); } @@ -16349,8 +18208,13 @@ void FooSetInterceptor(Local<Name> name, Local<Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) { CHECK(v8::Utils::OpenHandle(*info.This())->IsJSObject()); CHECK(v8::Utils::OpenHandle(*info.Holder())->IsJSObject()); - if (!name->Equals(v8_str("foo"))) return; - Local<Object>::Cast(info.This())->Set(v8_str("y"), v8_num(23)); + if (!name->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("foo")) + .FromJust()) { + return; + } + Local<Object>::Cast(info.This()) + ->Set(info.GetIsolate()->GetCurrentContext(), v8_str("y"), v8_num(23)) + .FromJust(); info.GetReturnValue().Set(v8_num(23)); } @@ -16362,7 +18226,10 @@ TEST(SetterOnConstructorPrototype) { templ->SetAccessor(v8_str("x"), GetterWhichReturns42, SetterWhichSetsYOnThisTo23); LocalContext context; - context->Global()->Set(v8_str("P"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("P"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun("function C1() {" " this.x = 23;" "};" @@ -16376,16 +18243,30 @@ TEST(SetterOnConstructorPrototype) { v8::Local<v8::Script> script; script = v8_compile("new C1();"); for (int i = 0; i < 10; i++) { - v8::Handle<v8::Object> c1 = v8::Handle<v8::Object>::Cast(script->Run()); - CHECK_EQ(42, c1->Get(v8_str("x"))->Int32Value()); - CHECK_EQ(23, c1->Get(v8_str("y"))->Int32Value()); + v8::Local<v8::Object> c1 = v8::Local<v8::Object>::Cast( + script->Run(context.local()).ToLocalChecked()); + CHECK_EQ(42, c1->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(23, c1->Get(context.local(), v8_str("y")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } -script = v8_compile("new C2();"); + script = v8_compile("new C2();"); for (int i = 0; i < 10; i++) { - v8::Handle<v8::Object> c2 = v8::Handle<v8::Object>::Cast(script->Run()); - CHECK_EQ(42, c2->Get(v8_str("x"))->Int32Value()); - CHECK_EQ(23, c2->Get(v8_str("y"))->Int32Value()); + v8::Local<v8::Object> c2 = v8::Local<v8::Object>::Cast( + script->Run(context.local()).ToLocalChecked()); + CHECK_EQ(42, c2->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(23, c2->Get(context.local(), v8_str("y")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } } @@ -16399,8 +18280,11 @@ static void NamedPropertyGetterWhichReturns42( static void NamedPropertySetterWhichSetsYOnThisTo23( Local<Name> name, Local<Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) { - if (name->Equals(v8_str("x"))) { - Local<Object>::Cast(info.This())->Set(v8_str("y"), v8_num(23)); + if (name->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("x")) + .FromJust()) { + Local<Object>::Cast(info.This()) + ->Set(info.GetIsolate()->GetCurrentContext(), v8_str("y"), v8_num(23)) + .FromJust(); } } @@ -16413,7 +18297,10 @@ THREADED_TEST(InterceptorOnConstructorPrototype) { NamedPropertyGetterWhichReturns42, NamedPropertySetterWhichSetsYOnThisTo23)); LocalContext context; - context->Global()->Set(v8_str("P"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("P"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun("function C1() {" " this.x = 23;" "};" @@ -16427,16 +18314,30 @@ THREADED_TEST(InterceptorOnConstructorPrototype) { v8::Local<v8::Script> script; script = v8_compile("new C1();"); for (int i = 0; i < 10; i++) { - v8::Handle<v8::Object> c1 = v8::Handle<v8::Object>::Cast(script->Run()); - CHECK_EQ(23, c1->Get(v8_str("x"))->Int32Value()); - CHECK_EQ(42, c1->Get(v8_str("y"))->Int32Value()); + v8::Local<v8::Object> c1 = v8::Local<v8::Object>::Cast( + script->Run(context.local()).ToLocalChecked()); + CHECK_EQ(23, c1->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(42, c1->Get(context.local(), v8_str("y")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } script = v8_compile("new C2();"); for (int i = 0; i < 10; i++) { - v8::Handle<v8::Object> c2 = v8::Handle<v8::Object>::Cast(script->Run()); - CHECK_EQ(23, c2->Get(v8_str("x"))->Int32Value()); - CHECK_EQ(42, c2->Get(v8_str("y"))->Int32Value()); + v8::Local<v8::Object> c2 = v8::Local<v8::Object>::Cast( + script->Run(context.local()).ToLocalChecked()); + CHECK_EQ(23, c2->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(42, c2->Get(context.local(), v8_str("y")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } } @@ -16454,8 +18355,10 @@ TEST(Regress618) { // Use a simple object as prototype. v8::Local<v8::Object> prototype = v8::Object::New(isolate); - prototype->Set(v8_str("y"), v8_num(42)); - context->Global()->Set(v8_str("P"), prototype); + prototype->Set(context.local(), v8_str("y"), v8_num(42)).FromJust(); + CHECK(context->Global() + ->Set(context.local(), v8_str("P"), prototype) + .FromJust()); // This compile will add the code to the compilation cache. CompileRun(source); @@ -16464,25 +18367,42 @@ TEST(Regress618) { // Allow enough iterations for the inobject slack tracking logic // to finalize instance size and install the fast construct stub. for (int i = 0; i < 256; i++) { - v8::Handle<v8::Object> c1 = v8::Handle<v8::Object>::Cast(script->Run()); - CHECK_EQ(23, c1->Get(v8_str("x"))->Int32Value()); - CHECK_EQ(42, c1->Get(v8_str("y"))->Int32Value()); + v8::Local<v8::Object> c1 = v8::Local<v8::Object>::Cast( + script->Run(context.local()).ToLocalChecked()); + CHECK_EQ(23, c1->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(42, c1->Get(context.local(), v8_str("y")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } // Use an API object with accessors as prototype. Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), GetterWhichReturns42, SetterWhichSetsYOnThisTo23); - context->Global()->Set(v8_str("P"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("P"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); // This compile will get the code from the compilation cache. CompileRun(source); script = v8_compile("new C1();"); for (int i = 0; i < 10; i++) { - v8::Handle<v8::Object> c1 = v8::Handle<v8::Object>::Cast(script->Run()); - CHECK_EQ(42, c1->Get(v8_str("x"))->Int32Value()); - CHECK_EQ(23, c1->Get(v8_str("y"))->Int32Value()); + v8::Local<v8::Object> c1 = v8::Local<v8::Object>::Cast( + script->Run(context.local()).ToLocalChecked()); + CHECK_EQ(42, c1->Get(context.local(), v8_str("x")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(23, c1->Get(context.local(), v8_str("y")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } } @@ -16494,12 +18414,6 @@ int epilogue_call_count_second = 0; int prologue_call_count_alloc = 0; int epilogue_call_count_alloc = 0; -void PrologueCallback(v8::GCType, v8::GCCallbackFlags flags) { - CHECK_EQ(flags, v8::kNoGCCallbackFlags); - ++prologue_call_count; -} - - void PrologueCallback(v8::Isolate* isolate, v8::GCType, v8::GCCallbackFlags flags) { @@ -16508,13 +18422,6 @@ void PrologueCallback(v8::Isolate* isolate, ++prologue_call_count; } - -void EpilogueCallback(v8::GCType, v8::GCCallbackFlags flags) { - CHECK_EQ(flags, v8::kNoGCCallbackFlags); - ++epilogue_call_count; -} - - void EpilogueCallback(v8::Isolate* isolate, v8::GCType, v8::GCCallbackFlags flags) { @@ -16524,12 +18431,6 @@ void EpilogueCallback(v8::Isolate* isolate, } -void PrologueCallbackSecond(v8::GCType, v8::GCCallbackFlags flags) { - CHECK_EQ(flags, v8::kNoGCCallbackFlags); - ++prologue_call_count_second; -} - - void PrologueCallbackSecond(v8::Isolate* isolate, v8::GCType, v8::GCCallbackFlags flags) { @@ -16539,12 +18440,6 @@ void PrologueCallbackSecond(v8::Isolate* isolate, } -void EpilogueCallbackSecond(v8::GCType, v8::GCCallbackFlags flags) { - CHECK_EQ(flags, v8::kNoGCCallbackFlags); - ++epilogue_call_count_second; -} - - void EpilogueCallbackSecond(v8::Isolate* isolate, v8::GCType, v8::GCCallbackFlags flags) { @@ -16597,29 +18492,31 @@ void EpilogueCallbackAlloc(v8::Isolate* isolate, TEST(GCCallbacksOld) { LocalContext context; - v8::V8::AddGCPrologueCallback(PrologueCallback); - v8::V8::AddGCEpilogueCallback(EpilogueCallback); + gc_callbacks_isolate = context->GetIsolate(); + + context->GetIsolate()->AddGCPrologueCallback(PrologueCallback); + context->GetIsolate()->AddGCEpilogueCallback(EpilogueCallback); CHECK_EQ(0, prologue_call_count); CHECK_EQ(0, epilogue_call_count); CcTest::heap()->CollectAllGarbage(); CHECK_EQ(1, prologue_call_count); CHECK_EQ(1, epilogue_call_count); - v8::V8::AddGCPrologueCallback(PrologueCallbackSecond); - v8::V8::AddGCEpilogueCallback(EpilogueCallbackSecond); + context->GetIsolate()->AddGCPrologueCallback(PrologueCallbackSecond); + context->GetIsolate()->AddGCEpilogueCallback(EpilogueCallbackSecond); CcTest::heap()->CollectAllGarbage(); CHECK_EQ(2, prologue_call_count); CHECK_EQ(2, epilogue_call_count); CHECK_EQ(1, prologue_call_count_second); CHECK_EQ(1, epilogue_call_count_second); - v8::V8::RemoveGCPrologueCallback(PrologueCallback); - v8::V8::RemoveGCEpilogueCallback(EpilogueCallback); + context->GetIsolate()->RemoveGCPrologueCallback(PrologueCallback); + context->GetIsolate()->RemoveGCEpilogueCallback(EpilogueCallback); CcTest::heap()->CollectAllGarbage(); CHECK_EQ(2, prologue_call_count); CHECK_EQ(2, epilogue_call_count); CHECK_EQ(2, prologue_call_count_second); CHECK_EQ(2, epilogue_call_count_second); - v8::V8::RemoveGCPrologueCallback(PrologueCallbackSecond); - v8::V8::RemoveGCEpilogueCallback(EpilogueCallbackSecond); + context->GetIsolate()->RemoveGCPrologueCallback(PrologueCallbackSecond); + context->GetIsolate()->RemoveGCEpilogueCallback(EpilogueCallbackSecond); CcTest::heap()->CollectAllGarbage(); CHECK_EQ(2, prologue_call_count); CHECK_EQ(2, epilogue_call_count); @@ -16726,17 +18623,17 @@ THREADED_TEST(TwoByteStringInOneByteCons) { // Atom RegExp. Local<Value> reresult = CompileRun("str2.match(/abel/g).length;"); - CHECK_EQ(6, reresult->Int32Value()); + CHECK_EQ(6, reresult->Int32Value(context.local()).FromJust()); // Nonatom RegExp. reresult = CompileRun("str2.match(/abe./g).length;"); - CHECK_EQ(6, reresult->Int32Value()); + CHECK_EQ(6, reresult->Int32Value(context.local()).FromJust()); reresult = CompileRun("str2.search(/bel/g);"); - CHECK_EQ(1, reresult->Int32Value()); + CHECK_EQ(1, reresult->Int32Value(context.local()).FromJust()); reresult = CompileRun("str2.search(/be./g);"); - CHECK_EQ(1, reresult->Int32Value()); + CHECK_EQ(1, reresult->Int32Value(context.local()).FromJust()); ExpectTrue("/bel/g.test(str2);"); @@ -16759,7 +18656,8 @@ THREADED_TEST(TwoByteStringInOneByteCons) { ExpectObject("str2.lastIndexOf('dab');", lastindexof); reresult = CompileRun("str2.charCodeAt(2);"); - CHECK_EQ(static_cast<int32_t>('e'), reresult->Int32Value()); + CHECK_EQ(static_cast<int32_t>('e'), + reresult->Int32Value(context.local()).FromJust()); } @@ -16781,27 +18679,31 @@ TEST(ContainsOnlyOneByte) { } string_contents[length-1] = 0; // Simple case. - Handle<String> string = - String::NewExternal(isolate, - new TestResource(string_contents, NULL, false)); + Local<String> string = + String::NewExternalTwoByte(isolate, + new TestResource(string_contents, NULL, false)) + .ToLocalChecked(); CHECK(!string->IsOneByte() && string->ContainsOnlyOneByte()); // Counter example. - string = String::NewFromTwoByte(isolate, string_contents); + string = String::NewFromTwoByte(isolate, string_contents, + v8::NewStringType::kNormal) + .ToLocalChecked(); CHECK(string->IsOneByte() && string->ContainsOnlyOneByte()); // Test left right and balanced cons strings. - Handle<String> base = String::NewFromUtf8(isolate, "a"); - Handle<String> left = base; - Handle<String> right = base; + Local<String> base = v8_str("a"); + Local<String> left = base; + Local<String> right = base; for (int i = 0; i < 1000; i++) { left = String::Concat(base, left); right = String::Concat(right, base); } - Handle<String> balanced = String::Concat(left, base); + Local<String> balanced = String::Concat(left, base); balanced = String::Concat(balanced, right); - Handle<String> cons_strings[] = {left, balanced, right}; - Handle<String> two_byte = - String::NewExternal(isolate, - new TestResource(string_contents, NULL, false)); + Local<String> cons_strings[] = {left, balanced, right}; + Local<String> two_byte = + String::NewExternalTwoByte(isolate, + new TestResource(string_contents, NULL, false)) + .ToLocalChecked(); USE(two_byte); USE(cons_strings); for (size_t i = 0; i < arraysize(cons_strings); i++) { // Base assumptions. @@ -16822,9 +18724,10 @@ TEST(ContainsOnlyOneByte) { for (int i = 0; i < size; i++) { int shift = 8 + (i % 7); string_contents[alignment + i] = 1 << shift; - string = String::NewExternal( - isolate, - new TestResource(string_contents + alignment, NULL, false)); + string = String::NewExternalTwoByte( + isolate, + new TestResource(string_contents + alignment, NULL, false)) + .ToLocalChecked(); CHECK_EQ(size, string->Length()); CHECK(!string->ContainsOnlyOneByte()); string_contents[alignment + i] = 0x41; @@ -16850,26 +18753,31 @@ TEST(GCInFailedAccessCheckCallback) { // invocation. Then force the callback to be called from va v8::V8::Initialize(); - v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); - v8::Isolate* isolate = CcTest::isolate(); + + isolate->SetFailedAccessCheckCallbackFunction(&FailedAccessCheckCallbackGC); + v8::HandleScope scope(isolate); // Create an ObjectTemplate for global objects and install access // check callbacks that will block access. - v8::Handle<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallback(AccessAlwaysBlocked); // Create a context and set an x property on it's global object. LocalContext context0(NULL, global_template); - context0->Global()->Set(v8_str("x"), v8_num(42)); - v8::Handle<v8::Object> global0 = context0->Global(); + CHECK(context0->Global() + ->Set(context0.local(), v8_str("x"), v8_num(42)) + .FromJust()); + v8::Local<v8::Object> global0 = context0->Global(); // Create a context with a different security token so that the // failed access check callback will be called on each access. LocalContext context1(NULL, global_template); - context1->Global()->Set(v8_str("other"), global0); + CHECK(context1->Global() + ->Set(context1.local(), v8_str("other"), global0) + .FromJust()); v8::TryCatch try_catch(isolate); @@ -16909,11 +18817,16 @@ TEST(GCInFailedAccessCheckCallback) { try_catch.Reset(); // Delete element. - CHECK_EQ(false, global0->Delete(0)); + CHECK(global0->Delete(context1.local(), 0).IsNothing()); + CHECK(try_catch.HasCaught()); + try_catch.Reset(); // DefineAccessor. - CHECK_EQ(false, - global0->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("x"))); + CHECK(global0->SetAccessor(context1.local(), v8_str("x"), GetXValue, NULL, + v8_str("x")) + .IsNothing()); + CHECK(try_catch.HasCaught()); + try_catch.Reset(); // Define JavaScript accessor. CHECK(CompileRun( @@ -16936,13 +18849,23 @@ TEST(GCInFailedAccessCheckCallback) { CHECK(try_catch.HasCaught()); try_catch.Reset(); - CHECK_EQ(false, global0->HasRealIndexedProperty(0)); - CHECK_EQ(false, global0->HasRealNamedProperty(v8_str("x"))); - CHECK_EQ(false, global0->HasRealNamedCallbackProperty(v8_str("x"))); + CHECK(global0->HasRealIndexedProperty(context1.local(), 0).IsNothing()); + CHECK(try_catch.HasCaught()); + try_catch.Reset(); + + CHECK( + global0->HasRealNamedProperty(context1.local(), v8_str("x")).IsNothing()); + CHECK(try_catch.HasCaught()); + try_catch.Reset(); + + CHECK(global0->HasRealNamedCallbackProperty(context1.local(), v8_str("x")) + .IsNothing()); + CHECK(try_catch.HasCaught()); + try_catch.Reset(); // Reset the failed access check callback so it does not influence // the other tests. - v8::V8::SetFailedAccessCheckCallbackFunction(NULL); + isolate->SetFailedAccessCheckCallbackFunction(NULL); } @@ -16955,7 +18878,7 @@ TEST(IsolateNewDispose) { CHECK(current_isolate != isolate); CHECK(current_isolate == CcTest::isolate()); - v8::V8::SetFatalErrorHandler(StoringErrorCallback); + isolate->SetFatalErrorHandler(StoringErrorCallback); last_location = last_message = NULL; isolate->Dispose(); CHECK(!last_location); @@ -16973,7 +18896,7 @@ UNINITIALIZED_TEST(DisposeIsolateWhenInUse) { LocalContext context(isolate); // Run something in this isolate. ExpectTrue("true"); - v8::V8::SetFatalErrorHandler(StoringErrorCallback); + isolate->SetFatalErrorHandler(StoringErrorCallback); last_location = last_message = NULL; // Still entered, should fail. isolate->Dispose(); @@ -17137,7 +19060,7 @@ TEST(RunTwoIsolatesOnSingleThread) { context1.Reset(); isolate1->Exit(); - v8::V8::SetFatalErrorHandler(StoringErrorCallback); + isolate2->SetFatalErrorHandler(StoringErrorCallback); last_location = last_message = NULL; isolate1->Dispose(); @@ -17171,7 +19094,7 @@ static int CalcFibonacci(v8::Isolate* isolate, int limit) { "fib(%d)", limit); Local<Value> value = CompileRun(code.start()); CHECK(value->IsNumber()); - return static_cast<int>(value->NumberValue()); + return static_cast<int>(value->NumberValue(context.local()).FromJust()); } class IsolateThread : public v8::base::Thread { @@ -17230,7 +19153,7 @@ TEST(IsolateDifferentContexts) { v8::Context::Scope context_scope(context); Local<Value> v = CompileRun("2"); CHECK(v->IsNumber()); - CHECK_EQ(2, static_cast<int>(v->NumberValue())); + CHECK_EQ(2, static_cast<int>(v->NumberValue(context).FromJust())); } { v8::Isolate::Scope isolate_scope(isolate); @@ -17239,7 +19162,7 @@ TEST(IsolateDifferentContexts) { v8::Context::Scope context_scope(context); Local<Value> v = CompileRun("22"); CHECK(v->IsNumber()); - CHECK_EQ(22, static_cast<int>(v->NumberValue())); + CHECK_EQ(22, static_cast<int>(v->NumberValue(context).FromJust())); } isolate->Dispose(); } @@ -17281,7 +19204,7 @@ class InitDefaultIsolateThread : public v8::base::Thread { break; case SetFatalHandler: - v8::V8::SetFatalErrorHandler(NULL); + isolate->SetFatalErrorHandler(NULL); break; case SetCounterFunction: @@ -17462,11 +19385,12 @@ class Visitor42 : public v8::PersistentHandleVisitor { CHECK_EQ(42, value->WrapperClassId()); v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::Value> handle = v8::Local<v8::Value>::New(isolate, *value); - v8::Handle<v8::Value> object = - v8::Local<v8::Object>::New(isolate, *object_); + v8::Local<v8::Value> handle = v8::Local<v8::Value>::New(isolate, *value); + v8::Local<v8::Value> object = v8::Local<v8::Object>::New(isolate, *object_); CHECK(handle->IsObject()); - CHECK(Handle<Object>::Cast(handle)->Equals(object)); + CHECK(Local<Object>::Cast(handle) + ->Equals(isolate->GetCurrentContext(), object) + .FromJust()); ++counter_; } @@ -17485,7 +19409,7 @@ TEST(PersistentHandleVisitor) { CHECK_EQ(42, object.WrapperClassId()); Visitor42 visitor(&object); - v8::V8::VisitHandlesWithClassIds(isolate, &visitor); + isolate->VisitHandlesWithClassIds(&visitor); CHECK_EQ(1, visitor.counter_); object.Reset(); @@ -17522,7 +19446,7 @@ TEST(PersistentHandleInNewSpaceVisitor) { CHECK_EQ(42, object2.WrapperClassId()); Visitor42 visitor(&object2); - v8::V8::VisitHandlesForPartialDependence(isolate, &visitor); + isolate->VisitHandlesForPartialDependence(&visitor); CHECK_EQ(1, visitor.counter_); object1.Reset(); @@ -17531,38 +19455,53 @@ TEST(PersistentHandleInNewSpaceVisitor) { TEST(RegExp) { + i::FLAG_harmony_regexps = true; + i::FLAG_harmony_unicode_regexps = true; LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::RegExp> re = v8::RegExp::New(v8_str("foo"), v8::RegExp::kNone); + v8::Local<v8::RegExp> re = + v8::RegExp::New(context.local(), v8_str("foo"), v8::RegExp::kNone) + .ToLocalChecked(); CHECK(re->IsRegExp()); - CHECK(re->GetSource()->Equals(v8_str("foo"))); + CHECK(re->GetSource()->Equals(context.local(), v8_str("foo")).FromJust()); CHECK_EQ(v8::RegExp::kNone, re->GetFlags()); - re = v8::RegExp::New(v8_str("bar"), + re = v8::RegExp::New(context.local(), v8_str("bar"), static_cast<v8::RegExp::Flags>(v8::RegExp::kIgnoreCase | - v8::RegExp::kGlobal)); + v8::RegExp::kGlobal)) + .ToLocalChecked(); CHECK(re->IsRegExp()); - CHECK(re->GetSource()->Equals(v8_str("bar"))); + CHECK(re->GetSource()->Equals(context.local(), v8_str("bar")).FromJust()); CHECK_EQ(v8::RegExp::kIgnoreCase | v8::RegExp::kGlobal, static_cast<int>(re->GetFlags())); - re = v8::RegExp::New(v8_str("baz"), + re = v8::RegExp::New(context.local(), v8_str("baz"), static_cast<v8::RegExp::Flags>(v8::RegExp::kIgnoreCase | - v8::RegExp::kMultiline)); + v8::RegExp::kMultiline)) + .ToLocalChecked(); CHECK(re->IsRegExp()); - CHECK(re->GetSource()->Equals(v8_str("baz"))); + CHECK(re->GetSource()->Equals(context.local(), v8_str("baz")).FromJust()); CHECK_EQ(v8::RegExp::kIgnoreCase | v8::RegExp::kMultiline, static_cast<int>(re->GetFlags())); + re = v8::RegExp::New(context.local(), v8_str("baz"), + static_cast<v8::RegExp::Flags>(v8::RegExp::kUnicode | + v8::RegExp::kSticky)) + .ToLocalChecked(); + CHECK(re->IsRegExp()); + CHECK(re->GetSource()->Equals(context.local(), v8_str("baz")).FromJust()); + CHECK_EQ(v8::RegExp::kUnicode | v8::RegExp::kSticky, + static_cast<int>(re->GetFlags())); + re = CompileRun("/quux/").As<v8::RegExp>(); CHECK(re->IsRegExp()); - CHECK(re->GetSource()->Equals(v8_str("quux"))); + CHECK(re->GetSource()->Equals(context.local(), v8_str("quux")).FromJust()); CHECK_EQ(v8::RegExp::kNone, re->GetFlags()); re = CompileRun("/quux/gm").As<v8::RegExp>(); CHECK(re->IsRegExp()); - CHECK(re->GetSource()->Equals(v8_str("quux"))); + CHECK(re->GetSource()->Equals(context.local(), v8_str("quux")).FromJust()); CHECK_EQ(v8::RegExp::kGlobal | v8::RegExp::kMultiline, static_cast<int>(re->GetFlags())); @@ -17570,32 +19509,39 @@ TEST(RegExp) { // still works. CompileRun("RegExp = function() {}"); - re = v8::RegExp::New(v8_str("foobar"), v8::RegExp::kNone); + re = v8::RegExp::New(context.local(), v8_str("foobar"), v8::RegExp::kNone) + .ToLocalChecked(); CHECK(re->IsRegExp()); - CHECK(re->GetSource()->Equals(v8_str("foobar"))); + CHECK(re->GetSource()->Equals(context.local(), v8_str("foobar")).FromJust()); CHECK_EQ(v8::RegExp::kNone, re->GetFlags()); - re = v8::RegExp::New(v8_str("foobarbaz"), + re = v8::RegExp::New(context.local(), v8_str("foobarbaz"), static_cast<v8::RegExp::Flags>(v8::RegExp::kIgnoreCase | - v8::RegExp::kMultiline)); + v8::RegExp::kMultiline)) + .ToLocalChecked(); CHECK(re->IsRegExp()); - CHECK(re->GetSource()->Equals(v8_str("foobarbaz"))); + CHECK( + re->GetSource()->Equals(context.local(), v8_str("foobarbaz")).FromJust()); CHECK_EQ(v8::RegExp::kIgnoreCase | v8::RegExp::kMultiline, static_cast<int>(re->GetFlags())); - context->Global()->Set(v8_str("re"), re); + CHECK(context->Global()->Set(context.local(), v8_str("re"), re).FromJust()); ExpectTrue("re.test('FoobarbaZ')"); // RegExps are objects on which you can set properties. - re->Set(v8_str("property"), v8::Integer::New(context->GetIsolate(), 32)); - v8::Handle<v8::Value> value(CompileRun("re.property")); - CHECK_EQ(32, value->Int32Value()); + re->Set(context.local(), v8_str("property"), + v8::Integer::New(context->GetIsolate(), 32)) + .FromJust(); + v8::Local<v8::Value> value(CompileRun("re.property")); + CHECK_EQ(32, value->Int32Value(context.local()).FromJust()); v8::TryCatch try_catch(context->GetIsolate()); - re = v8::RegExp::New(v8_str("foo["), v8::RegExp::kNone); - CHECK(re.IsEmpty()); + CHECK(v8::RegExp::New(context.local(), v8_str("foo["), v8::RegExp::kNone) + .IsEmpty()); CHECK(try_catch.HasCaught()); - context->Global()->Set(v8_str("ex"), try_catch.Exception()); + CHECK(context->Global() + ->Set(context.local(), v8_str("ex"), try_catch.Exception()) + .FromJust()); ExpectTrue("ex instanceof SyntaxError"); } @@ -17604,18 +19550,18 @@ THREADED_TEST(Equals) { LocalContext localContext; v8::HandleScope handleScope(localContext->GetIsolate()); - v8::Handle<v8::Object> globalProxy = localContext->Global(); - v8::Handle<Value> global = globalProxy->GetPrototype(); + v8::Local<v8::Object> globalProxy = localContext->Global(); + v8::Local<Value> global = globalProxy->GetPrototype(); CHECK(global->StrictEquals(global)); CHECK(!global->StrictEquals(globalProxy)); CHECK(!globalProxy->StrictEquals(global)); CHECK(globalProxy->StrictEquals(globalProxy)); - CHECK(global->Equals(global)); - CHECK(!global->Equals(globalProxy)); - CHECK(!globalProxy->Equals(global)); - CHECK(globalProxy->Equals(globalProxy)); + CHECK(global->Equals(localContext.local(), global).FromJust()); + CHECK(!global->Equals(localContext.local(), globalProxy).FromJust()); + CHECK(!globalProxy->Equals(localContext.local(), global).FromJust()); + CHECK(globalProxy->Equals(localContext.local(), globalProxy).FromJust()); } @@ -17626,8 +19572,10 @@ static void Getter(v8::Local<v8::Name> property, static void Enumerator(const v8::PropertyCallbackInfo<v8::Array>& info) { - v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate()); - result->Set(0, v8_str("universalAnswer")); + v8::Local<v8::Array> result = v8::Array::New(info.GetIsolate()); + result->Set(info.GetIsolate()->GetCurrentContext(), 0, + v8_str("universalAnswer")) + .FromJust(); info.GetReturnValue().Set(result); } @@ -17638,53 +19586,68 @@ TEST(NamedEnumeratorAndForIn) { v8::HandleScope handle_scope(isolate); v8::Context::Scope context_scope(context.local()); - v8::Handle<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(isolate); tmpl->SetHandler(v8::NamedPropertyHandlerConfiguration(Getter, NULL, NULL, NULL, Enumerator)); - context->Global()->Set(v8_str("o"), tmpl->NewInstance()); - v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( - "var result = []; for (var k in o) result.push(k); result")); + CHECK(context->Global() + ->Set(context.local(), v8_str("o"), + tmpl->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); + v8::Local<v8::Array> result = v8::Local<v8::Array>::Cast( + CompileRun("var result = []; for (var k in o) result.push(k); result")); CHECK_EQ(1u, result->Length()); - CHECK(v8_str("universalAnswer")->Equals(result->Get(0))); + CHECK(v8_str("universalAnswer") + ->Equals(context.local(), + result->Get(context.local(), 0).ToLocalChecked()) + .FromJust()); } TEST(DefinePropertyPostDetach) { LocalContext context; v8::HandleScope scope(context->GetIsolate()); - v8::Handle<v8::Object> proxy = context->Global(); - v8::Handle<v8::Function> define_property = - CompileRun("(function() {" - " Object.defineProperty(" - " this," - " 1," - " { configurable: true, enumerable: true, value: 3 });" - "})").As<Function>(); + v8::Local<v8::Object> proxy = context->Global(); + v8::Local<v8::Function> define_property = + CompileRun( + "(function() {" + " Object.defineProperty(" + " this," + " 1," + " { configurable: true, enumerable: true, value: 3 });" + "})") + .As<Function>(); context->DetachGlobal(); - define_property->Call(proxy, 0, NULL); + CHECK(define_property->Call(context.local(), proxy, 0, NULL).IsEmpty()); } -static void InstallContextId(v8::Handle<Context> context, int id) { +static void InstallContextId(v8::Local<Context> context, int id) { Context::Scope scope(context); - CompileRun("Object.prototype").As<Object>()-> - Set(v8_str("context_id"), v8::Integer::New(context->GetIsolate(), id)); + CHECK(CompileRun("Object.prototype") + .As<Object>() + ->Set(context, v8_str("context_id"), + v8::Integer::New(context->GetIsolate(), id)) + .FromJust()); } -static void CheckContextId(v8::Handle<Object> object, int expected) { - CHECK_EQ(expected, object->Get(v8_str("context_id"))->Int32Value()); +static void CheckContextId(v8::Local<Object> object, int expected) { + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); + CHECK_EQ(expected, object->Get(context, v8_str("context_id")) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); } THREADED_TEST(CreationContext) { v8::Isolate* isolate = CcTest::isolate(); HandleScope handle_scope(isolate); - Handle<Context> context1 = Context::New(isolate); + Local<Context> context1 = Context::New(isolate); InstallContextId(context1, 1); - Handle<Context> context2 = Context::New(isolate); + Local<Context> context2 = Context::New(isolate); InstallContextId(context2, 2); - Handle<Context> context3 = Context::New(isolate); + Local<Context> context3 = Context::New(isolate); InstallContextId(context3, 3); Local<v8::FunctionTemplate> tmpl = v8::FunctionTemplate::New(isolate); @@ -17694,7 +19657,7 @@ THREADED_TEST(CreationContext) { { Context::Scope scope(context1); object1 = Object::New(isolate); - func1 = tmpl->GetFunction(); + func1 = tmpl->GetFunction(context1).ToLocalChecked(); } Local<Object> object2; @@ -17702,7 +19665,7 @@ THREADED_TEST(CreationContext) { { Context::Scope scope(context2); object2 = Object::New(isolate); - func2 = tmpl->GetFunction(); + func2 = tmpl->GetFunction(context2).ToLocalChecked(); } Local<Object> instance1; @@ -17710,12 +19673,12 @@ THREADED_TEST(CreationContext) { { Context::Scope scope(context3); - instance1 = func1->NewInstance(); - instance2 = func2->NewInstance(); + instance1 = func1->NewInstance(context3).ToLocalChecked(); + instance2 = func2->NewInstance(context3).ToLocalChecked(); } { - Handle<Context> other_context = Context::New(isolate); + Local<Context> other_context = Context::New(isolate); Context::Scope scope(other_context); CHECK(object1->CreationContext() == context1); CheckContextId(object1, 1); @@ -17767,7 +19730,7 @@ THREADED_TEST(CreationContext) { THREADED_TEST(CreationContextOfJsFunction) { HandleScope handle_scope(CcTest::isolate()); - Handle<Context> context = Context::New(CcTest::isolate()); + Local<Context> context = Context::New(CcTest::isolate()); InstallContextId(context, 1); Local<Object> function; @@ -17776,13 +19739,46 @@ THREADED_TEST(CreationContextOfJsFunction) { function = CompileRun("function foo() {}; foo").As<Object>(); } - Handle<Context> other_context = Context::New(CcTest::isolate()); + Local<Context> other_context = Context::New(CcTest::isolate()); Context::Scope scope(other_context); CHECK(function->CreationContext() == context); CheckContextId(function, 1); } +THREADED_TEST(CreationContextOfJsBoundFunction) { + HandleScope handle_scope(CcTest::isolate()); + Local<Context> context1 = Context::New(CcTest::isolate()); + InstallContextId(context1, 1); + Local<Context> context2 = Context::New(CcTest::isolate()); + InstallContextId(context2, 2); + + Local<Function> target_function; + { + Context::Scope scope(context1); + target_function = CompileRun("function foo() {}; foo").As<Function>(); + } + + Local<Function> bound_function1, bound_function2; + { + Context::Scope scope(context2); + CHECK(context2->Global() + ->Set(context2, v8_str("foo"), target_function) + .FromJust()); + bound_function1 = CompileRun("foo.bind(1)").As<Function>(); + bound_function2 = + CompileRun("Function.prototype.bind.call(foo, 2)").As<Function>(); + } + + Local<Context> other_context = Context::New(CcTest::isolate()); + Context::Scope scope(other_context); + CHECK(bound_function1->CreationContext() == context1); + CheckContextId(bound_function1, 1); + CHECK(bound_function2->CreationContext() == context2); + CheckContextId(bound_function2, 1); +} + + void HasOwnPropertyIndexedPropertyGetter( uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) { @@ -17792,7 +19788,10 @@ void HasOwnPropertyIndexedPropertyGetter( void HasOwnPropertyNamedPropertyGetter( Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) { - if (property->Equals(v8_str("foo"))) info.GetReturnValue().Set(v8_str("yes")); + if (property->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("foo")) + .FromJust()) { + info.GetReturnValue().Set(v8_str("yes")); + } } @@ -17804,13 +19803,19 @@ void HasOwnPropertyIndexedPropertyQuery( void HasOwnPropertyNamedPropertyQuery( Local<Name> property, const v8::PropertyCallbackInfo<v8::Integer>& info) { - if (property->Equals(v8_str("foo"))) info.GetReturnValue().Set(1); + if (property->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("foo")) + .FromJust()) { + info.GetReturnValue().Set(1); + } } void HasOwnPropertyNamedPropertyQuery2( Local<Name> property, const v8::PropertyCallbackInfo<v8::Integer>& info) { - if (property->Equals(v8_str("bar"))) info.GetReturnValue().Set(1); + if (property->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("bar")) + .FromJust()) { + info.GetReturnValue().Set(1); + } } @@ -17826,7 +19831,7 @@ TEST(HasOwnProperty) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); { // Check normal properties and defined getters. - Handle<Value> value = CompileRun( + Local<Value> value = CompileRun( "function Foo() {" " this.foo = 11;" " this.__defineGetter__('baz', function() { return 1; });" @@ -17838,63 +19843,63 @@ TEST(HasOwnProperty) { "Bar.prototype = new Foo();" "new Bar();"); CHECK(value->IsObject()); - Handle<Object> object = value->ToObject(isolate); - CHECK(object->Has(v8_str("foo"))); - CHECK(!object->HasOwnProperty(v8_str("foo"))); - CHECK(object->HasOwnProperty(v8_str("bar"))); - CHECK(object->Has(v8_str("baz"))); - CHECK(!object->HasOwnProperty(v8_str("baz"))); - CHECK(object->HasOwnProperty(v8_str("bla"))); + Local<Object> object = value->ToObject(env.local()).ToLocalChecked(); + CHECK(object->Has(env.local(), v8_str("foo")).FromJust()); + CHECK(!object->HasOwnProperty(env.local(), v8_str("foo")).FromJust()); + CHECK(object->HasOwnProperty(env.local(), v8_str("bar")).FromJust()); + CHECK(object->Has(env.local(), v8_str("baz")).FromJust()); + CHECK(!object->HasOwnProperty(env.local(), v8_str("baz")).FromJust()); + CHECK(object->HasOwnProperty(env.local(), v8_str("bla")).FromJust()); } { // Check named getter interceptors. - Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration( HasOwnPropertyNamedPropertyGetter)); - Handle<Object> instance = templ->NewInstance(); - CHECK(!instance->HasOwnProperty(v8_str("42"))); - CHECK(instance->HasOwnProperty(v8_str("foo"))); - CHECK(!instance->HasOwnProperty(v8_str("bar"))); + Local<Object> instance = templ->NewInstance(env.local()).ToLocalChecked(); + CHECK(!instance->HasOwnProperty(env.local(), v8_str("42")).FromJust()); + CHECK(instance->HasOwnProperty(env.local(), v8_str("foo")).FromJust()); + CHECK(!instance->HasOwnProperty(env.local(), v8_str("bar")).FromJust()); } { // Check indexed getter interceptors. - Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::IndexedPropertyHandlerConfiguration( HasOwnPropertyIndexedPropertyGetter)); - Handle<Object> instance = templ->NewInstance(); - CHECK(instance->HasOwnProperty(v8_str("42"))); - CHECK(!instance->HasOwnProperty(v8_str("43"))); - CHECK(!instance->HasOwnProperty(v8_str("foo"))); + Local<Object> instance = templ->NewInstance(env.local()).ToLocalChecked(); + CHECK(instance->HasOwnProperty(env.local(), v8_str("42")).FromJust()); + CHECK(!instance->HasOwnProperty(env.local(), v8_str("43")).FromJust()); + CHECK(!instance->HasOwnProperty(env.local(), v8_str("foo")).FromJust()); } { // Check named query interceptors. - Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration( 0, 0, HasOwnPropertyNamedPropertyQuery)); - Handle<Object> instance = templ->NewInstance(); - CHECK(instance->HasOwnProperty(v8_str("foo"))); - CHECK(!instance->HasOwnProperty(v8_str("bar"))); + Local<Object> instance = templ->NewInstance(env.local()).ToLocalChecked(); + CHECK(instance->HasOwnProperty(env.local(), v8_str("foo")).FromJust()); + CHECK(!instance->HasOwnProperty(env.local(), v8_str("bar")).FromJust()); } { // Check indexed query interceptors. - Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::IndexedPropertyHandlerConfiguration( 0, 0, HasOwnPropertyIndexedPropertyQuery)); - Handle<Object> instance = templ->NewInstance(); - CHECK(instance->HasOwnProperty(v8_str("42"))); - CHECK(!instance->HasOwnProperty(v8_str("41"))); + Local<Object> instance = templ->NewInstance(env.local()).ToLocalChecked(); + CHECK(instance->HasOwnProperty(env.local(), v8_str("42")).FromJust()); + CHECK(!instance->HasOwnProperty(env.local(), v8_str("41")).FromJust()); } { // Check callbacks. - Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("foo"), HasOwnPropertyAccessorGetter); - Handle<Object> instance = templ->NewInstance(); - CHECK(instance->HasOwnProperty(v8_str("foo"))); - CHECK(!instance->HasOwnProperty(v8_str("bar"))); + Local<Object> instance = templ->NewInstance(env.local()).ToLocalChecked(); + CHECK(instance->HasOwnProperty(env.local(), v8_str("foo")).FromJust()); + CHECK(!instance->HasOwnProperty(env.local(), v8_str("bar")).FromJust()); } { // Check that query wins on disagreement. - Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::NamedPropertyHandlerConfiguration( HasOwnPropertyNamedPropertyGetter, 0, HasOwnPropertyNamedPropertyQuery2)); - Handle<Object> instance = templ->NewInstance(); - CHECK(!instance->HasOwnProperty(v8_str("foo"))); - CHECK(instance->HasOwnProperty(v8_str("bar"))); + Local<Object> instance = templ->NewInstance(env.local()).ToLocalChecked(); + CHECK(!instance->HasOwnProperty(env.local(), v8_str("foo")).FromJust()); + CHECK(instance->HasOwnProperty(env.local(), v8_str("bar")).FromJust()); } } @@ -17902,38 +19907,42 @@ TEST(HasOwnProperty) { TEST(IndexedInterceptorWithStringProto) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); + Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetHandler(v8::IndexedPropertyHandlerConfiguration( NULL, NULL, HasOwnPropertyIndexedPropertyQuery)); LocalContext context; - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun("var s = new String('foobar'); obj.__proto__ = s;"); // These should be intercepted. - CHECK(CompileRun("42 in obj")->BooleanValue()); - CHECK(CompileRun("'42' in obj")->BooleanValue()); + CHECK(CompileRun("42 in obj")->BooleanValue(context.local()).FromJust()); + CHECK(CompileRun("'42' in obj")->BooleanValue(context.local()).FromJust()); // These should fall through to the String prototype. - CHECK(CompileRun("0 in obj")->BooleanValue()); - CHECK(CompileRun("'0' in obj")->BooleanValue()); + CHECK(CompileRun("0 in obj")->BooleanValue(context.local()).FromJust()); + CHECK(CompileRun("'0' in obj")->BooleanValue(context.local()).FromJust()); // And these should both fail. - CHECK(!CompileRun("32 in obj")->BooleanValue()); - CHECK(!CompileRun("'32' in obj")->BooleanValue()); + CHECK(!CompileRun("32 in obj")->BooleanValue(context.local()).FromJust()); + CHECK(!CompileRun("'32' in obj")->BooleanValue(context.local()).FromJust()); } void CheckCodeGenerationAllowed() { - Handle<Value> result = CompileRun("eval('42')"); - CHECK_EQ(42, result->Int32Value()); + Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); + Local<Value> result = CompileRun("eval('42')"); + CHECK_EQ(42, result->Int32Value(context).FromJust()); result = CompileRun("(function(e) { return e('42'); })(eval)"); - CHECK_EQ(42, result->Int32Value()); + CHECK_EQ(42, result->Int32Value(context).FromJust()); result = CompileRun("var f = new Function('return 42'); f()"); - CHECK_EQ(42, result->Int32Value()); + CHECK_EQ(42, result->Int32Value(context).FromJust()); } void CheckCodeGenerationDisallowed() { TryCatch try_catch(CcTest::isolate()); - Handle<Value> result = CompileRun("eval('42')"); + Local<Value> result = CompileRun("eval('42')"); CHECK(result.IsEmpty()); CHECK(try_catch.HasCaught()); try_catch.Reset(); @@ -17980,12 +19989,14 @@ THREADED_TEST(AllowCodeGenFromStrings) { // Disallow but setting a global callback that will allow the calls. context->AllowCodeGenerationFromStrings(false); - V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationAllowed); + context->GetIsolate()->SetAllowCodeGenerationFromStringsCallback( + &CodeGenerationAllowed); CHECK(!context->IsCodeGenerationFromStringsAllowed()); CheckCodeGenerationAllowed(); // Set a callback that disallows the code generation. - V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationDisallowed); + context->GetIsolate()->SetAllowCodeGenerationFromStringsCallback( + &CodeGenerationDisallowed); CHECK(!context->IsCodeGenerationFromStringsAllowed()); CheckCodeGenerationDisallowed(); } @@ -17996,16 +20007,17 @@ TEST(SetErrorMessageForCodeGenFromStrings) { v8::HandleScope scope(context->GetIsolate()); TryCatch try_catch(context->GetIsolate()); - Handle<String> message = v8_str("Message"); - Handle<String> expected_message = v8_str("Uncaught EvalError: Message"); - V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationDisallowed); + Local<String> message = v8_str("Message"); + Local<String> expected_message = v8_str("Uncaught EvalError: Message"); + context->GetIsolate()->SetAllowCodeGenerationFromStringsCallback( + &CodeGenerationDisallowed); context->AllowCodeGenerationFromStrings(false); context->SetErrorMessageForCodeGenerationFromStrings(message); - Handle<Value> result = CompileRun("eval('42')"); + Local<Value> result = CompileRun("eval('42')"); CHECK(result.IsEmpty()); CHECK(try_catch.HasCaught()); - Handle<String> actual_message = try_catch.Message()->Get(); - CHECK(expected_message->Equals(actual_message)); + Local<String> actual_message = try_catch.Message()->Get(); + CHECK(expected_message->Equals(context.local(), actual_message).FromJust()); } @@ -18017,10 +20029,13 @@ THREADED_TEST(CallAPIFunctionOnNonObject) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - Handle<FunctionTemplate> templ = + Local<FunctionTemplate> templ = v8::FunctionTemplate::New(isolate, NonObjectThis); - Handle<Function> function = templ->GetFunction(); - context->Global()->Set(v8_str("f"), function); + Local<Function> function = + templ->GetFunction(context.local()).ToLocalChecked(); + CHECK(context->Global() + ->Set(context.local(), v8_str("f"), function) + .FromJust()); TryCatch try_catch(isolate); CompileRun("f.call(2)"); } @@ -18033,19 +20048,35 @@ THREADED_TEST(ReadOnlyIndexedProperties) { Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); LocalContext context; - Local<v8::Object> obj = templ->NewInstance(); - context->Global()->Set(v8_str("obj"), obj); - obj->ForceSet(v8_str("1"), v8_str("DONT_CHANGE"), v8::ReadOnly); - obj->Set(v8_str("1"), v8_str("foobar")); - CHECK(v8_str("DONT_CHANGE")->Equals(obj->Get(v8_str("1")))); - obj->ForceSet(v8_num(2), v8_str("DONT_CHANGE"), v8::ReadOnly); - obj->Set(v8_num(2), v8_str("foobar")); - CHECK(v8_str("DONT_CHANGE")->Equals(obj->Get(v8_num(2)))); + Local<v8::Object> obj = templ->NewInstance(context.local()).ToLocalChecked(); + CHECK(context->Global()->Set(context.local(), v8_str("obj"), obj).FromJust()); + obj->DefineOwnProperty(context.local(), v8_str("1"), v8_str("DONT_CHANGE"), + v8::ReadOnly) + .FromJust(); + obj->Set(context.local(), v8_str("1"), v8_str("foobar")).FromJust(); + CHECK(v8_str("DONT_CHANGE") + ->Equals(context.local(), + obj->Get(context.local(), v8_str("1")).ToLocalChecked()) + .FromJust()); + obj->DefineOwnProperty(context.local(), v8_str("2"), v8_str("DONT_CHANGE"), + v8::ReadOnly) + .FromJust(); + obj->Set(context.local(), v8_num(2), v8_str("foobar")).FromJust(); + CHECK(v8_str("DONT_CHANGE") + ->Equals(context.local(), + obj->Get(context.local(), v8_num(2)).ToLocalChecked()) + .FromJust()); // Test non-smi case. - obj->ForceSet(v8_str("2000000000"), v8_str("DONT_CHANGE"), v8::ReadOnly); - obj->Set(v8_str("2000000000"), v8_str("foobar")); - CHECK(v8_str("DONT_CHANGE")->Equals(obj->Get(v8_str("2000000000")))); + obj->DefineOwnProperty(context.local(), v8_str("2000000000"), + v8_str("DONT_CHANGE"), v8::ReadOnly) + .FromJust(); + obj->Set(context.local(), v8_str("2000000000"), v8_str("foobar")).FromJust(); + CHECK(v8_str("DONT_CHANGE") + ->Equals(context.local(), + obj->Get(context.local(), v8_str("2000000000")) + .ToLocalChecked()) + .FromJust()); } @@ -18113,20 +20144,24 @@ THREADED_TEST(Regress93759) { Local<Object> simple_object = Object::New(isolate); // Object with explicit security check. - Local<Object> protected_object = no_proto_template->NewInstance(); + Local<Object> protected_object = + no_proto_template->NewInstance(context).ToLocalChecked(); // JSGlobalProxy object, always have security check. Local<Object> proxy_object = context->Global(); // Global object, the prototype of proxy_object. No security checks. - Local<Object> global_object = proxy_object->GetPrototype()->ToObject(isolate); + Local<Object> global_object = + proxy_object->GetPrototype()->ToObject(context).ToLocalChecked(); // Hidden prototype without security check. - Local<Object> hidden_prototype = - hidden_proto_template->GetFunction()->NewInstance(); + Local<Object> hidden_prototype = hidden_proto_template->GetFunction(context) + .ToLocalChecked() + ->NewInstance(context) + .ToLocalChecked(); Local<Object> object_with_hidden = Object::New(isolate); - object_with_hidden->SetPrototype(hidden_prototype); + object_with_hidden->SetPrototype(context, hidden_prototype).FromJust(); context->Exit(); @@ -18142,20 +20177,25 @@ THREADED_TEST(Regress93759) { LocalContext context2(NULL, global_template); Local<Value> result1 = CompileRun("Object.getPrototypeOf(simple)"); - CHECK(result1->Equals(simple_object->GetPrototype())); + CHECK(result1->Equals(context2.local(), simple_object->GetPrototype()) + .FromJust()); Local<Value> result2 = CompileRun("Object.getPrototypeOf(protected)"); CHECK(result2->IsNull()); Local<Value> result3 = CompileRun("Object.getPrototypeOf(global)"); - CHECK(result3->Equals(global_object->GetPrototype())); + CHECK(result3->Equals(context2.local(), global_object->GetPrototype()) + .FromJust()); Local<Value> result4 = CompileRun("Object.getPrototypeOf(proxy)"); CHECK(result4->IsNull()); Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)"); - CHECK(result5->Equals( - object_with_hidden->GetPrototype()->ToObject(isolate)->GetPrototype())); + CHECK(result5->Equals(context2.local(), object_with_hidden->GetPrototype() + ->ToObject(context2.local()) + .ToLocalChecked() + ->GetPrototype()) + .FromJust()); } @@ -18163,9 +20203,16 @@ static void TestReceiver(Local<Value> expected_result, Local<Value> expected_receiver, const char* code) { Local<Value> result = CompileRun(code); + Local<Context> context = CcTest::isolate()->GetCurrentContext(); CHECK(result->IsObject()); - CHECK(expected_receiver->Equals(result.As<v8::Object>()->Get(1))); - CHECK(expected_result->Equals(result.As<v8::Object>()->Get(0))); + CHECK(expected_receiver + ->Equals(context, + result.As<v8::Object>()->Get(context, 1).ToLocalChecked()) + .FromJust()); + CHECK(expected_result + ->Equals(context, + result.As<v8::Object>()->Get(context, 0).ToLocalChecked()) + .FromJust()); } @@ -18214,11 +20261,19 @@ THREADED_TEST(ForeignFunctionReceiver) { "}" "var id = 'o';" "ownfunc"); - context->Global()->Set(v8_str("func"), foreign_function); + CHECK(context->Global() + ->Set(context.local(), v8_str("func"), foreign_function) + .FromJust()); // Sanity check the contexts. - CHECK(i->Equals(foreign_context->Global()->Get(id))); - CHECK(o->Equals(context->Global()->Get(id))); + CHECK( + i->Equals( + context.local(), + foreign_context->Global()->Get(context.local(), id).ToLocalChecked()) + .FromJust()); + CHECK(o->Equals(context.local(), + context->Global()->Get(context.local(), id).ToLocalChecked()) + .FromJust()); // Checking local function's receiver. // Calling function using its call/apply methods. @@ -18226,9 +20281,15 @@ THREADED_TEST(ForeignFunctionReceiver) { TestReceiver(o, context->Global(), "ownfunc.apply()"); // Making calls through built-in functions. TestReceiver(o, context->Global(), "[1].map(ownfunc)[0]"); - CHECK(o->Equals(CompileRun("'abcbd'.replace(/b/,ownfunc)[1]"))); - CHECK(o->Equals(CompileRun("'abcbd'.replace(/b/g,ownfunc)[1]"))); - CHECK(o->Equals(CompileRun("'abcbd'.replace(/b/g,ownfunc)[3]"))); + CHECK( + o->Equals(context.local(), CompileRun("'abcbd'.replace(/b/,ownfunc)[1]")) + .FromJust()); + CHECK( + o->Equals(context.local(), CompileRun("'abcbd'.replace(/b/g,ownfunc)[1]")) + .FromJust()); + CHECK( + o->Equals(context.local(), CompileRun("'abcbd'.replace(/b/g,ownfunc)[3]")) + .FromJust()); // Calling with environment record as base. TestReceiver(o, context->Global(), "ownfunc()"); // Calling with no base. @@ -18250,9 +20311,12 @@ THREADED_TEST(ForeignFunctionReceiver) { // Making calls through built-in functions. TestReceiver(i, foreign_context->Global(), "[1].map(func)[0]"); // ToString(func()) is func()[0], i.e., the returned this.id. - CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/,func)[1]"))); - CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[1]"))); - CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); + CHECK(i->Equals(context.local(), CompileRun("'abcbd'.replace(/b/,func)[1]")) + .FromJust()); + CHECK(i->Equals(context.local(), CompileRun("'abcbd'.replace(/b/g,func)[1]")) + .FromJust()); + CHECK(i->Equals(context.local(), CompileRun("'abcbd'.replace(/b/g,func)[3]")) + .FromJust()); // Calling with environment record as base. TestReceiver(i, foreign_context->Global(), "func()"); @@ -18277,7 +20341,8 @@ void CallCompletedCallback2() { void RecursiveCall(const v8::FunctionCallbackInfo<v8::Value>& args) { - int32_t level = args[0]->Int32Value(); + int32_t level = + args[0]->Int32Value(args.GetIsolate()->GetCurrentContext()).FromJust(); if (level < 3) { level++; v8::base::OS::Print("Entering recursion level %d.\n", level); @@ -18297,32 +20362,35 @@ void RecursiveCall(const v8::FunctionCallbackInfo<v8::Value>& args) { TEST(CallCompletedCallback) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Handle<v8::FunctionTemplate> recursive_runtime = + v8::Local<v8::FunctionTemplate> recursive_runtime = v8::FunctionTemplate::New(env->GetIsolate(), RecursiveCall); - env->Global()->Set(v8_str("recursion"), - recursive_runtime->GetFunction()); + env->Global() + ->Set(env.local(), v8_str("recursion"), + recursive_runtime->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); // Adding the same callback a second time has no effect. env->GetIsolate()->AddCallCompletedCallback(CallCompletedCallback1); env->GetIsolate()->AddCallCompletedCallback(CallCompletedCallback1); env->GetIsolate()->AddCallCompletedCallback(CallCompletedCallback2); v8::base::OS::Print("--- Script (1) ---\n"); - Local<Script> script = v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), "recursion(0)")); - script->Run(); + Local<Script> script = + v8::Script::Compile(env.local(), v8_str("recursion(0)")).ToLocalChecked(); + script->Run(env.local()).ToLocalChecked(); CHECK_EQ(3, callback_fired); v8::base::OS::Print("\n--- Script (2) ---\n"); callback_fired = 0; env->GetIsolate()->RemoveCallCompletedCallback(CallCompletedCallback1); - script->Run(); + script->Run(env.local()).ToLocalChecked(); CHECK_EQ(2, callback_fired); v8::base::OS::Print("\n--- Function ---\n"); callback_fired = 0; - Local<Function> recursive_function = - Local<Function>::Cast(env->Global()->Get(v8_str("recursion"))); - v8::Handle<Value> args[] = { v8_num(0) }; - recursive_function->Call(env->Global(), 1, args); + Local<Function> recursive_function = Local<Function>::Cast( + env->Global()->Get(env.local(), v8_str("recursion")).ToLocalChecked()); + v8::Local<Value> args[] = {v8_num(0)}; + recursive_function->Call(env.local(), env->Global(), 1, args) + .ToLocalChecked(); CHECK_EQ(2, callback_fired); } @@ -18382,50 +20450,50 @@ TEST(EnqueueMicrotask) { "var ext1Calls = 0;" "var ext2Calls = 0;"); CompileRun("1+1;"); - CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); env->GetIsolate()->EnqueueMicrotask( - Function::New(env->GetIsolate(), MicrotaskOne)); + Function::New(env.local(), MicrotaskOne).ToLocalChecked()); CompileRun("1+1;"); - CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); env->GetIsolate()->EnqueueMicrotask( - Function::New(env->GetIsolate(), MicrotaskOne)); + Function::New(env.local(), MicrotaskOne).ToLocalChecked()); env->GetIsolate()->EnqueueMicrotask( - Function::New(env->GetIsolate(), MicrotaskTwo)); + Function::New(env.local(), MicrotaskTwo).ToLocalChecked()); CompileRun("1+1;"); - CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); env->GetIsolate()->EnqueueMicrotask( - Function::New(env->GetIsolate(), MicrotaskTwo)); + Function::New(env.local(), MicrotaskTwo).ToLocalChecked()); CompileRun("1+1;"); - CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); CompileRun("1+1;"); - CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); g_passed_to_three = NULL; env->GetIsolate()->EnqueueMicrotask(MicrotaskThree); CompileRun("1+1;"); CHECK(!g_passed_to_three); - CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); int dummy; env->GetIsolate()->EnqueueMicrotask( - Function::New(env->GetIsolate(), MicrotaskOne)); + Function::New(env.local(), MicrotaskOne).ToLocalChecked()); env->GetIsolate()->EnqueueMicrotask(MicrotaskThree, &dummy); env->GetIsolate()->EnqueueMicrotask( - Function::New(env->GetIsolate(), MicrotaskTwo)); + Function::New(env.local(), MicrotaskTwo).ToLocalChecked()); CompileRun("1+1;"); CHECK_EQ(&dummy, g_passed_to_three); - CHECK_EQ(3, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(3, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); g_passed_to_three = NULL; } @@ -18456,14 +20524,16 @@ TEST(RunMicrotasksIgnoresThrownExceptions) { "var exception1Calls = 0;" "var exception2Calls = 0;"); isolate->EnqueueMicrotask( - Function::New(isolate, MicrotaskExceptionOne)); + Function::New(env.local(), MicrotaskExceptionOne).ToLocalChecked()); isolate->EnqueueMicrotask( - Function::New(isolate, MicrotaskExceptionTwo)); + Function::New(env.local(), MicrotaskExceptionTwo).ToLocalChecked()); TryCatch try_catch(isolate); CompileRun("1+1;"); CHECK(!try_catch.HasCaught()); - CHECK_EQ(1, CompileRun("exception1Calls")->Int32Value()); - CHECK_EQ(1, CompileRun("exception2Calls")->Int32Value()); + CHECK_EQ(1, + CompileRun("exception1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(1, + CompileRun("exception2Calls")->Int32Value(env.local()).FromJust()); } @@ -18474,57 +20544,57 @@ TEST(SetAutorunMicrotasks) { "var ext1Calls = 0;" "var ext2Calls = 0;"); CompileRun("1+1;"); - CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); env->GetIsolate()->EnqueueMicrotask( - Function::New(env->GetIsolate(), MicrotaskOne)); + Function::New(env.local(), MicrotaskOne).ToLocalChecked()); CompileRun("1+1;"); - CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); env->GetIsolate()->SetAutorunMicrotasks(false); env->GetIsolate()->EnqueueMicrotask( - Function::New(env->GetIsolate(), MicrotaskOne)); + Function::New(env.local(), MicrotaskOne).ToLocalChecked()); env->GetIsolate()->EnqueueMicrotask( - Function::New(env->GetIsolate(), MicrotaskTwo)); + Function::New(env.local(), MicrotaskTwo).ToLocalChecked()); CompileRun("1+1;"); - CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); env->GetIsolate()->RunMicrotasks(); - CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); env->GetIsolate()->EnqueueMicrotask( - Function::New(env->GetIsolate(), MicrotaskTwo)); + Function::New(env.local(), MicrotaskTwo).ToLocalChecked()); CompileRun("1+1;"); - CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); env->GetIsolate()->RunMicrotasks(); - CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); env->GetIsolate()->SetAutorunMicrotasks(true); env->GetIsolate()->EnqueueMicrotask( - Function::New(env->GetIsolate(), MicrotaskTwo)); + Function::New(env.local(), MicrotaskTwo).ToLocalChecked()); CompileRun("1+1;"); - CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); env->GetIsolate()->EnqueueMicrotask( - Function::New(env->GetIsolate(), MicrotaskTwo)); + Function::New(env.local(), MicrotaskTwo).ToLocalChecked()); { v8::Isolate::SuppressMicrotaskExecutionScope scope(env->GetIsolate()); CompileRun("1+1;"); - CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); } CompileRun("1+1;"); - CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value()); - CHECK_EQ(4, CompileRun("ext2Calls")->Int32Value()); + CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust()); + CHECK_EQ(4, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust()); } @@ -18532,16 +20602,17 @@ TEST(RunMicrotasksWithoutEnteringContext) { v8::Isolate* isolate = CcTest::isolate(); HandleScope handle_scope(isolate); isolate->SetAutorunMicrotasks(false); - Handle<Context> context = Context::New(isolate); + Local<Context> context = Context::New(isolate); { Context::Scope context_scope(context); CompileRun("var ext1Calls = 0;"); - isolate->EnqueueMicrotask(Function::New(isolate, MicrotaskOne)); + isolate->EnqueueMicrotask( + Function::New(context, MicrotaskOne).ToLocalChecked()); } isolate->RunMicrotasks(); { Context::Scope context_scope(context); - CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value()); + CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(context).FromJust()); } isolate->SetAutorunMicrotasks(true); } @@ -18550,22 +20621,25 @@ TEST(RunMicrotasksWithoutEnteringContext) { static void DebugEventInObserver(const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); if (event != v8::Break) return; - Handle<Object> exec_state = event_details.GetExecutionState(); - Handle<Value> break_id = exec_state->Get(v8_str("break_id")); + Local<Object> exec_state = event_details.GetExecutionState(); + Local<Context> context = CcTest::isolate()->GetCurrentContext(); + Local<Value> break_id = + exec_state->Get(context, v8_str("break_id")).ToLocalChecked(); CompileRun("function f(id) { new FrameDetails(id, 0); }"); - Handle<Function> fun = - Handle<Function>::Cast(CcTest::global()->Get(v8_str("f"))); - fun->Call(CcTest::global(), 1, &break_id); + Local<Function> fun = Local<Function>::Cast( + CcTest::global()->Get(context, v8_str("f")).ToLocalChecked()); + fun->Call(context, CcTest::global(), 1, &break_id).ToLocalChecked(); } TEST(Regress385349) { + i::FLAG_harmony_object_observe = true; i::FLAG_allow_natives_syntax = true; v8::Isolate* isolate = CcTest::isolate(); HandleScope handle_scope(isolate); isolate->SetAutorunMicrotasks(false); - Handle<Context> context = Context::New(isolate); - v8::Debug::SetDebugEventListener(DebugEventInObserver); + Local<Context> context = Context::New(isolate); + v8::Debug::SetDebugEventListener(isolate, DebugEventInObserver); { Context::Scope context_scope(context); CompileRun("var obj = {};" @@ -18574,7 +20648,7 @@ TEST(Regress385349) { } isolate->RunMicrotasks(); isolate->SetAutorunMicrotasks(true); - v8::Debug::SetDebugEventListener(NULL); + v8::Debug::SetDebugEventListener(isolate, nullptr); } @@ -18745,7 +20819,8 @@ static int instance_checked_getter_count = 0; static void InstanceCheckedGetter( Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { - CHECK(name->Equals(v8_str("foo"))); + CHECK(name->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("foo")) + .FromJust()); instance_checked_getter_count++; info.GetReturnValue().Set(v8_num(11)); } @@ -18755,8 +20830,10 @@ static int instance_checked_setter_count = 0; static void InstanceCheckedSetter(Local<String> name, Local<Value> value, const v8::PropertyCallbackInfo<void>& info) { - CHECK(name->Equals(v8_str("foo"))); - CHECK(value->Equals(v8_num(23))); + CHECK(name->Equals(info.GetIsolate()->GetCurrentContext(), v8_str("foo")) + .FromJust()); + CHECK(value->Equals(info.GetIsolate()->GetCurrentContext(), v8_num(23)) + .FromJust()); instance_checked_setter_count++; } @@ -18827,23 +20904,25 @@ THREADED_TEST(InstanceCheckOnInstanceAccessor) { Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); Local<ObjectTemplate> inst = templ->InstanceTemplate(); - inst->SetAccessor(v8_str("foo"), - InstanceCheckedGetter, InstanceCheckedSetter, - Handle<Value>(), - v8::DEFAULT, - v8::None, + inst->SetAccessor(v8_str("foo"), InstanceCheckedGetter, InstanceCheckedSetter, + Local<Value>(), v8::DEFAULT, v8::None, v8::AccessorSignature::New(context->GetIsolate(), templ)); - context->Global()->Set(v8_str("f"), templ->GetFunction()); + CHECK(context->Global() + ->Set(context.local(), v8_str("f"), + templ->GetFunction(context.local()).ToLocalChecked()) + .FromJust()); printf("Testing positive ...\n"); CompileRun("var obj = new f();"); - CHECK(templ->HasInstance(context->Global()->Get(v8_str("obj")))); + CHECK(templ->HasInstance( + context->Global()->Get(context.local(), v8_str("obj")).ToLocalChecked())); CheckInstanceCheckedAccessors(true); printf("Testing negative ...\n"); CompileRun("var obj = {};" "obj.__proto__ = new f();"); - CHECK(!templ->HasInstance(context->Global()->Get(v8_str("obj")))); + CHECK(!templ->HasInstance( + context->Global()->Get(context.local(), v8_str("obj")).ToLocalChecked())); CheckInstanceCheckedAccessors(false); } @@ -18866,23 +20945,25 @@ THREADED_TEST(InstanceCheckOnInstanceAccessorWithInterceptor) { Local<ObjectTemplate> inst = templ->InstanceTemplate(); templ->InstanceTemplate()->SetNamedPropertyHandler(EmptyInterceptorGetter, EmptyInterceptorSetter); - inst->SetAccessor(v8_str("foo"), - InstanceCheckedGetter, InstanceCheckedSetter, - Handle<Value>(), - v8::DEFAULT, - v8::None, + inst->SetAccessor(v8_str("foo"), InstanceCheckedGetter, InstanceCheckedSetter, + Local<Value>(), v8::DEFAULT, v8::None, v8::AccessorSignature::New(context->GetIsolate(), templ)); - context->Global()->Set(v8_str("f"), templ->GetFunction()); + CHECK(context->Global() + ->Set(context.local(), v8_str("f"), + templ->GetFunction(context.local()).ToLocalChecked()) + .FromJust()); printf("Testing positive ...\n"); CompileRun("var obj = new f();"); - CHECK(templ->HasInstance(context->Global()->Get(v8_str("obj")))); + CHECK(templ->HasInstance( + context->Global()->Get(context.local(), v8_str("obj")).ToLocalChecked())); CheckInstanceCheckedAccessors(true); printf("Testing negative ...\n"); CompileRun("var obj = {};" "obj.__proto__ = new f();"); - CHECK(!templ->HasInstance(context->Global()->Get(v8_str("obj")))); + CHECK(!templ->HasInstance( + context->Global()->Get(context.local(), v8_str("obj")).ToLocalChecked())); CheckInstanceCheckedAccessors(false); } @@ -18895,20 +20976,25 @@ THREADED_TEST(InstanceCheckOnPrototypeAccessor) { Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); Local<ObjectTemplate> proto = templ->PrototypeTemplate(); proto->SetAccessor(v8_str("foo"), InstanceCheckedGetter, - InstanceCheckedSetter, Handle<Value>(), v8::DEFAULT, + InstanceCheckedSetter, Local<Value>(), v8::DEFAULT, v8::None, v8::AccessorSignature::New(context->GetIsolate(), templ)); - context->Global()->Set(v8_str("f"), templ->GetFunction()); + CHECK(context->Global() + ->Set(context.local(), v8_str("f"), + templ->GetFunction(context.local()).ToLocalChecked()) + .FromJust()); printf("Testing positive ...\n"); CompileRun("var obj = new f();"); - CHECK(templ->HasInstance(context->Global()->Get(v8_str("obj")))); + CHECK(templ->HasInstance( + context->Global()->Get(context.local(), v8_str("obj")).ToLocalChecked())); CheckInstanceCheckedAccessors(true); printf("Testing negative ...\n"); CompileRun("var obj = {};" "obj.__proto__ = new f();"); - CHECK(!templ->HasInstance(context->Global()->Get(v8_str("obj")))); + CHECK(!templ->HasInstance( + context->Global()->Get(context.local(), v8_str("obj")).ToLocalChecked())); CheckInstanceCheckedAccessors(false); printf("Testing positive with modified prototype chain ...\n"); @@ -18916,7 +21002,8 @@ THREADED_TEST(InstanceCheckOnPrototypeAccessor) { "var pro = {};" "pro.__proto__ = obj.__proto__;" "obj.__proto__ = pro;"); - CHECK(templ->HasInstance(context->Global()->Get(v8_str("obj")))); + CHECK(templ->HasInstance( + context->Global()->Get(context.local(), v8_str("obj")).ToLocalChecked())); CheckInstanceCheckedAccessors(true); } @@ -18940,7 +21027,7 @@ TEST(TryFinallyMessage) { CHECK(try_catch.HasCaught()); Local<Message> message = try_catch.Message(); CHECK(!message.IsEmpty()); - CHECK_EQ(2, message->GetLineNumber()); + CHECK_EQ(2, message->GetLineNumber(context.local()).FromJust()); } { @@ -18959,7 +21046,7 @@ TEST(TryFinallyMessage) { CHECK(try_catch.HasCaught()); Local<Message> message = try_catch.Message(); CHECK(!message.IsEmpty()); - CHECK_EQ(6, message->GetLineNumber()); + CHECK_EQ(6, message->GetLineNumber(context.local()).FromJust()); } } @@ -18978,7 +21065,10 @@ static void Helper137002(bool do_store, GetterWhichReturns42, SetterWhichSetsYOnThisTo23); } - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); // Turn monomorphic on slow object with native accessor, then turn // polymorphic, finally optimize to create negative lookup and fail. @@ -19004,10 +21094,16 @@ static void Helper137002(bool do_store, CompileRun("result = obj.y;"); } if (remove_accessor && !interceptor) { - CHECK(context->Global()->Get(v8_str("result"))->IsUndefined()); + CHECK(context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->IsUndefined()); } else { - CHECK_EQ(do_store ? 23 : 42, - context->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(do_store ? 23 : 42, context->Global() + ->Get(context.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } } @@ -19031,7 +21127,10 @@ THREADED_TEST(Regress137002b) { templ->SetAccessor(v8_str("foo"), GetterWhichReturns42, SetterWhichSetsYOnThisTo23); - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); // Turn monomorphic on slow object with native accessor, then just // delete the property and fail. @@ -19082,12 +21181,30 @@ THREADED_TEST(Regress137002b) { "store2(subobj);" "var y_from_obj = obj.y;" "var y_from_subobj = subobj.y;"); - CHECK(context->Global()->Get(v8_str("load_result"))->IsUndefined()); - CHECK(context->Global()->Get(v8_str("load_result2"))->IsUndefined()); - CHECK(context->Global()->Get(v8_str("keyed_load_result"))->IsUndefined()); - CHECK(context->Global()->Get(v8_str("keyed_load_result2"))->IsUndefined()); - CHECK(context->Global()->Get(v8_str("y_from_obj"))->IsUndefined()); - CHECK(context->Global()->Get(v8_str("y_from_subobj"))->IsUndefined()); + CHECK(context->Global() + ->Get(context.local(), v8_str("load_result")) + .ToLocalChecked() + ->IsUndefined()); + CHECK(context->Global() + ->Get(context.local(), v8_str("load_result2")) + .ToLocalChecked() + ->IsUndefined()); + CHECK(context->Global() + ->Get(context.local(), v8_str("keyed_load_result")) + .ToLocalChecked() + ->IsUndefined()); + CHECK(context->Global() + ->Get(context.local(), v8_str("keyed_load_result2")) + .ToLocalChecked() + ->IsUndefined()); + CHECK(context->Global() + ->Get(context.local(), v8_str("y_from_obj")) + .ToLocalChecked() + ->IsUndefined()); + CHECK(context->Global() + ->Get(context.local(), v8_str("y_from_subobj")) + .ToLocalChecked() + ->IsUndefined()); } @@ -19100,7 +21217,10 @@ THREADED_TEST(Regress142088) { templ->SetAccessor(v8_str("foo"), GetterWhichReturns42, SetterWhichSetsYOnThisTo23); - context->Global()->Set(v8_str("obj"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("obj"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun("function load(x) { return x.foo; }" "var o = Object.create(obj);" @@ -19128,7 +21248,7 @@ THREADED_TEST(Regress157124) { v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); - Local<Object> obj = templ->NewInstance(); + Local<Object> obj = templ->NewInstance(context.local()).ToLocalChecked(); obj->GetIdentityHash(); obj->DeletePrivate(context.local(), v8::Private::ForApi(isolate, v8_str("Bug"))) @@ -19169,7 +21289,8 @@ THREADED_TEST(Regress260106) { Local<FunctionTemplate> templ = FunctionTemplate::New(isolate, DummyCallHandler); CompileRun("for (var i = 0; i < 128; i++) Object.prototype[i] = 0;"); - Local<Function> function = templ->GetFunction(); + Local<Function> function = + templ->GetFunction(context.local()).ToLocalChecked(); CHECK(!function.IsEmpty()); CHECK(function->IsFunction()); } @@ -19178,9 +21299,11 @@ THREADED_TEST(Regress260106) { THREADED_TEST(JSONParseObject) { LocalContext context; HandleScope scope(context->GetIsolate()); - Local<Value> obj = v8::JSON::Parse(v8_str("{\"x\":42}")); - Handle<Object> global = context->Global(); - global->Set(v8_str("obj"), obj); + Local<Value> obj = + v8::JSON::Parse(context->GetIsolate(), v8_str("{\"x\":42}")) + .ToLocalChecked(); + Local<Object> global = context->Global(); + global->Set(context.local(), v8_str("obj"), obj).FromJust(); ExpectString("JSON.stringify(obj)", "{\"x\":42}"); } @@ -19188,9 +21311,10 @@ THREADED_TEST(JSONParseObject) { THREADED_TEST(JSONParseNumber) { LocalContext context; HandleScope scope(context->GetIsolate()); - Local<Value> obj = v8::JSON::Parse(v8_str("42")); - Handle<Object> global = context->Global(); - global->Set(v8_str("obj"), obj); + Local<Value> obj = + v8::JSON::Parse(context->GetIsolate(), v8_str("42")).ToLocalChecked(); + Local<Object> global = context->Global(); + global->Set(context.local(), v8_str("obj"), obj).FromJust(); ExpectString("JSON.stringify(obj)", "42"); } @@ -19271,28 +21395,32 @@ TEST(JSONStringifyAccessCheck) { // Create an ObjectTemplate for global objects and install access // check callbacks that will block access. - v8::Handle<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallback(AccessAlwaysBlocked); // Create a context and set an x property on it's global object. LocalContext context0(NULL, global_template); - v8::Handle<v8::Object> global0 = context0->Global(); - global0->Set(v8_str("x"), v8_num(42)); + v8::Local<v8::Object> global0 = context0->Global(); + global0->Set(context0.local(), v8_str("x"), v8_num(42)).FromJust(); ExpectString("JSON.stringify(this)", "{\"x\":42}"); for (int i = 0; i < 2; i++) { if (i == 1) { // Install a toJSON function on the second run. - v8::Handle<v8::FunctionTemplate> toJSON = + v8::Local<v8::FunctionTemplate> toJSON = v8::FunctionTemplate::New(isolate, UnreachableCallback); - global0->Set(v8_str("toJSON"), toJSON->GetFunction()); + global0->Set(context0.local(), v8_str("toJSON"), + toJSON->GetFunction(context0.local()).ToLocalChecked()) + .FromJust(); } // Create a context with a different security token so that the // failed access check callback will be called on each access. LocalContext context1(NULL, global_template); - context1->Global()->Set(v8_str("other"), global0); + CHECK(context1->Global() + ->Set(context1.local(), v8_str("other"), global0) + .FromJust()); CHECK(CompileRun("JSON.stringify(other)").IsEmpty()); CHECK(CompileRun("JSON.stringify({ 'a' : other, 'b' : ['c'] })").IsEmpty()); @@ -19325,8 +21453,13 @@ void CatcherCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { void HasOwnPropertyCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { - args[0]->ToObject(args.GetIsolate())->HasOwnProperty( - args[1]->ToString(args.GetIsolate())); + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); + CHECK( + args[0] + ->ToObject(context) + .ToLocalChecked() + ->HasOwnProperty(context, args[1]->ToString(context).ToLocalChecked()) + .IsNothing()); } @@ -19353,33 +21486,41 @@ void CheckCorrectThrow(const char* script) { TEST(AccessCheckThrows) { i::FLAG_allow_natives_syntax = true; v8::V8::Initialize(); - v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckThrows); v8::Isolate* isolate = CcTest::isolate(); + isolate->SetFailedAccessCheckCallbackFunction(&FailedAccessCheckThrows); v8::HandleScope scope(isolate); // Create an ObjectTemplate for global objects and install access // check callbacks that will block access. - v8::Handle<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate); global_template->SetAccessCheckCallback(AccessAlwaysBlocked); // Create a context and set an x property on it's global object. LocalContext context0(NULL, global_template); - v8::Handle<v8::Object> global0 = context0->Global(); + v8::Local<v8::Object> global0 = context0->Global(); // Create a context with a different security token so that the // failed access check callback will be called on each access. LocalContext context1(NULL, global_template); - context1->Global()->Set(v8_str("other"), global0); + CHECK(context1->Global() + ->Set(context1.local(), v8_str("other"), global0) + .FromJust()); - v8::Handle<v8::FunctionTemplate> catcher_fun = + v8::Local<v8::FunctionTemplate> catcher_fun = v8::FunctionTemplate::New(isolate, CatcherCallback); - context1->Global()->Set(v8_str("catcher"), catcher_fun->GetFunction()); + CHECK(context1->Global() + ->Set(context1.local(), v8_str("catcher"), + catcher_fun->GetFunction(context1.local()).ToLocalChecked()) + .FromJust()); - v8::Handle<v8::FunctionTemplate> has_own_property_fun = + v8::Local<v8::FunctionTemplate> has_own_property_fun = v8::FunctionTemplate::New(isolate, HasOwnPropertyCallback); - context1->Global()->Set(v8_str("has_own_property"), - has_own_property_fun->GetFunction()); + CHECK(context1->Global() + ->Set(context1.local(), v8_str("has_own_property"), + has_own_property_fun->GetFunction(context1.local()) + .ToLocalChecked()) + .FromJust()); { v8::TryCatch try_catch(isolate); @@ -19402,14 +21543,14 @@ TEST(AccessCheckThrows) { CheckCorrectThrow("%DeleteProperty_Strict(other, '1')"); CheckCorrectThrow("%HasOwnProperty(other, 'x')"); CheckCorrectThrow("%HasProperty('x', other)"); - CheckCorrectThrow("%IsPropertyEnumerable(other, 'x')"); + CheckCorrectThrow("%PropertyIsEnumerable(other, 'x')"); // PROPERTY_ATTRIBUTES_NONE = 0 CheckCorrectThrow("%DefineAccessorPropertyUnchecked(" "other, 'x', null, null, 1)"); // Reset the failed access check callback so it does not influence // the other tests. - v8::V8::SetFailedAccessCheckCallbackFunction(NULL); + isolate->SetFailedAccessCheckCallbackFunction(NULL); } @@ -19510,9 +21651,12 @@ class RequestInterruptTestWithFunctionCall : public RequestInterruptTestBaseWithSimpleInterrupt { public: virtual void TestBody() { - Local<Function> func = Function::New( - isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)); - env_->Global()->Set(v8_str("ShouldContinue"), func); + Local<Function> func = Function::New(env_.local(), ShouldContinueCallback, + v8::External::New(isolate_, this)) + .ToLocalChecked(); + CHECK(env_->Global() + ->Set(env_.local(), v8_str("ShouldContinue"), func) + .FromJust()); CompileRun("while (ShouldContinue()) { }"); } @@ -19525,9 +21669,14 @@ class RequestInterruptTestWithMethodCall virtual void TestBody() { v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); v8::Local<v8::Template> proto = t->PrototypeTemplate(); - proto->Set(v8_str("shouldContinue"), Function::New( - isolate_, ShouldContinueCallback, v8::External::New(isolate_, this))); - env_->Global()->Set(v8_str("Klass"), t->GetFunction()); + proto->Set(v8_str("shouldContinue"), + Function::New(env_.local(), ShouldContinueCallback, + v8::External::New(isolate_, this)) + .ToLocalChecked()); + CHECK(env_->Global() + ->Set(env_.local(), v8_str("Klass"), + t->GetFunction(env_.local()).ToLocalChecked()) + .FromJust()); CompileRun("var obj = new Klass; while (obj.shouldContinue()) { }"); } @@ -19542,7 +21691,10 @@ class RequestInterruptTestWithAccessor v8::Local<v8::Template> proto = t->PrototypeTemplate(); proto->SetAccessorProperty(v8_str("shouldContinue"), FunctionTemplate::New( isolate_, ShouldContinueCallback, v8::External::New(isolate_, this))); - env_->Global()->Set(v8_str("Klass"), t->GetFunction()); + CHECK(env_->Global() + ->Set(env_.local(), v8_str("Klass"), + t->GetFunction(env_.local()).ToLocalChecked()) + .FromJust()); CompileRun("var obj = new Klass; while (obj.shouldContinue) { }"); } @@ -19559,7 +21711,10 @@ class RequestInterruptTestWithNativeAccessor &ShouldContinueNativeGetter, NULL, v8::External::New(isolate_, this)); - env_->Global()->Set(v8_str("Klass"), t->GetFunction()); + CHECK(env_->Global() + ->Set(env_.local(), v8_str("Klass"), + t->GetFunction(env_.local()).ToLocalChecked()) + .FromJust()); CompileRun("var obj = new Klass; while (obj.shouldContinue) { }"); } @@ -19582,13 +21737,18 @@ class RequestInterruptTestWithMethodCallAndInterceptor virtual void TestBody() { v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); v8::Local<v8::Template> proto = t->PrototypeTemplate(); - proto->Set(v8_str("shouldContinue"), Function::New( - isolate_, ShouldContinueCallback, v8::External::New(isolate_, this))); + proto->Set(v8_str("shouldContinue"), + Function::New(env_.local(), ShouldContinueCallback, + v8::External::New(isolate_, this)) + .ToLocalChecked()); v8::Local<v8::ObjectTemplate> instance_template = t->InstanceTemplate(); instance_template->SetHandler( v8::NamedPropertyHandlerConfiguration(EmptyInterceptor)); - env_->Global()->Set(v8_str("Klass"), t->GetFunction()); + CHECK(env_->Global() + ->Set(env_.local(), v8_str("Klass"), + t->GetFunction(env_.local()).ToLocalChecked()) + .FromJust()); CompileRun("var obj = new Klass; while (obj.shouldContinue()) { }"); } @@ -19603,15 +21763,19 @@ class RequestInterruptTestWithMathAbs : public RequestInterruptTestBaseWithSimpleInterrupt { public: virtual void TestBody() { - env_->Global()->Set(v8_str("WakeUpInterruptor"), Function::New( - isolate_, - WakeUpInterruptorCallback, - v8::External::New(isolate_, this))); - - env_->Global()->Set(v8_str("ShouldContinue"), Function::New( - isolate_, - ShouldContinueCallback, - v8::External::New(isolate_, this))); + env_->Global() + ->Set(env_.local(), v8_str("WakeUpInterruptor"), + Function::New(env_.local(), WakeUpInterruptorCallback, + v8::External::New(isolate_, this)) + .ToLocalChecked()) + .FromJust(); + + env_->Global() + ->Set(env_.local(), v8_str("ShouldContinue"), + Function::New(env_.local(), ShouldContinueCallback, + v8::External::New(isolate_, this)) + .ToLocalChecked()) + .FromJust(); i::FLAG_allow_natives_syntax = true; CompileRun("function loopish(o) {" @@ -19636,7 +21800,11 @@ class RequestInterruptTestWithMathAbs private: static void WakeUpInterruptorCallback( const v8::FunctionCallbackInfo<Value>& info) { - if (!info[0]->BooleanValue()) return; + if (!info[0] + ->BooleanValue(info.GetIsolate()->GetCurrentContext()) + .FromJust()) { + return; + } RequestInterruptTestBase* test = reinterpret_cast<RequestInterruptTestBase*>( @@ -19693,9 +21861,12 @@ class RequestMultipleInterrupts : public RequestInterruptTestBase { } virtual void TestBody() { - Local<Function> func = Function::New( - isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)); - env_->Global()->Set(v8_str("ShouldContinue"), func); + Local<Function> func = Function::New(env_.local(), ShouldContinueCallback, + v8::External::New(isolate_, this)) + .ToLocalChecked(); + CHECK(env_->Global() + ->Set(env_.local(), v8_str("ShouldContinue"), func) + .FromJust()); CompileRun("while (ShouldContinue()) { }"); } @@ -19754,7 +21925,10 @@ TEST(RequestInterruptSmallScripts) { static Local<Value> function_new_expected_env; static void FunctionNewCallback(const v8::FunctionCallbackInfo<Value>& info) { - CHECK(function_new_expected_env->Equals(info.Data())); + CHECK( + function_new_expected_env->Equals(info.GetIsolate()->GetCurrentContext(), + info.Data()) + .FromJust()); info.GetReturnValue().Set(17); } @@ -19765,10 +21939,11 @@ THREADED_TEST(FunctionNew) { v8::HandleScope scope(isolate); Local<Object> data = v8::Object::New(isolate); function_new_expected_env = data; - Local<Function> func = Function::New(isolate, FunctionNewCallback, data); - env->Global()->Set(v8_str("func"), func); + Local<Function> func = + Function::New(env.local(), FunctionNewCallback, data).ToLocalChecked(); + CHECK(env->Global()->Set(env.local(), v8_str("func"), func).FromJust()); Local<Value> result = CompileRun("func();"); - CHECK(v8::Integer::New(isolate, 17)->Equals(result)); + CHECK(v8::Integer::New(isolate, 17)->Equals(env.local(), result).FromJust()); i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); // Verify function not cached auto serial_number = handle( @@ -19782,12 +21957,13 @@ THREADED_TEST(FunctionNew) { // Verify that each Function::New creates a new function instance Local<Object> data2 = v8::Object::New(isolate); function_new_expected_env = data2; - Local<Function> func2 = Function::New(isolate, FunctionNewCallback, data2); + Local<Function> func2 = + Function::New(env.local(), FunctionNewCallback, data2).ToLocalChecked(); CHECK(!func2->IsNull()); - CHECK(!func->Equals(func2)); - env->Global()->Set(v8_str("func2"), func2); + CHECK(!func->Equals(env.local(), func2).FromJust()); + CHECK(env->Global()->Set(env.local(), v8_str("func2"), func2).FromJust()); Local<Value> result2 = CompileRun("func2();"); - CHECK(v8::Integer::New(isolate, 17)->Equals(result2)); + CHECK(v8::Integer::New(isolate, 17)->Equals(env.local(), result2).FromJust()); } @@ -19805,7 +21981,9 @@ TEST(EscapeableHandleScope) { for (int i = 0; i < runs; i++) { Local<String> expected; if (i != 0) { - CHECK(v8_str("escape value")->Equals(values[i])); + CHECK(v8_str("escape value") + ->Equals(context.local(), values[i]) + .FromJust()); } else { CHECK(values[i].IsEmpty()); } @@ -19825,7 +22003,10 @@ TEST(Regress239669) { v8::HandleScope scope(isolate); Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); templ->SetAccessor(v8_str("x"), 0, SetterWhichExpectsThisAndHolderToDiffer); - context->Global()->Set(v8_str("P"), templ->NewInstance()); + CHECK(context->Global() + ->Set(context.local(), v8_str("P"), + templ->NewInstance(context.local()).ToLocalChecked()) + .FromJust()); CompileRun( "function C1() {" " this.x = 23;" @@ -19851,7 +22032,9 @@ class ApiCallOptimizationChecker { CHECK(data == info.Data()); CHECK(receiver == info.This()); if (info.Length() == 1) { - CHECK(v8_num(1)->Equals(info[0])); + CHECK(v8_num(1) + ->Equals(info.GetIsolate()->GetCurrentContext(), info[0]) + .FromJust()); } CHECK(holder == info.Holder()); count++; @@ -19909,8 +22092,11 @@ class ApiCallOptimizationChecker { v8::Context::New(isolate, NULL, signature_template); v8::Context::Scope context_scope(context); // Install regular object that can pass signature checks. - Local<Object> function_receiver = signature_template->NewInstance(); - context->Global()->Set(v8_str("function_receiver"), function_receiver); + Local<Object> function_receiver = + signature_template->NewInstance(context).ToLocalChecked(); + CHECK(context->Global() + ->Set(context, v8_str("function_receiver"), function_receiver) + .FromJust()); // Get the holder objects. Local<Object> inner_global = Local<Object>::Cast(context->Global()->GetPrototype()); @@ -19918,16 +22104,17 @@ class ApiCallOptimizationChecker { data = Object::New(isolate); Local<FunctionTemplate> function_template = FunctionTemplate::New( isolate, OptimizationCallback, data, signature); - Local<Function> function = function_template->GetFunction(); + Local<Function> function = + function_template->GetFunction(context).ToLocalChecked(); Local<Object> global_holder = inner_global; Local<Object> function_holder = function_receiver; if (signature_type == kSignatureOnPrototype) { function_holder = Local<Object>::Cast(function_holder->GetPrototype()); global_holder = Local<Object>::Cast(global_holder->GetPrototype()); } - global_holder->Set(v8_str("g_f"), function); + global_holder->Set(context, v8_str("g_f"), function).FromJust(); global_holder->SetAccessorProperty(v8_str("g_acc"), function, function); - function_holder->Set(v8_str("f"), function); + function_holder->Set(context, v8_str("f"), function).FromJust(); function_holder->SetAccessorProperty(v8_str("acc"), function, function); // Initialize expected values. callee = function; @@ -20001,7 +22188,7 @@ class ApiCallOptimizationChecker { wrap_function.start(), key, key, key, key, key, key); v8::TryCatch try_catch(isolate); CompileRun(source.start()); - DCHECK(!try_catch.HasCaught()); + CHECK(!try_catch.HasCaught()); CHECK_EQ(9, count); } }; @@ -20026,9 +22213,10 @@ TEST(FunctionCallOptimizationMultipleArgs) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - Handle<Object> global = context->Global(); - Local<v8::Function> function = Function::New(isolate, Returns42); - global->Set(v8_str("x"), function); + Local<Object> global = context->Global(); + Local<v8::Function> function = + Function::New(context.local(), Returns42).ToLocalChecked(); + global->Set(context.local(), v8_str("x"), function).FromJust(); CompileRun( "function x_wrap() {\n" " for (var i = 0; i < 5; i++) {\n" @@ -20052,9 +22240,10 @@ TEST(ApiCallbackCanReturnSymbols) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - Handle<Object> global = context->Global(); - Local<v8::Function> function = Function::New(isolate, ReturnsSymbolCallback); - global->Set(v8_str("x"), function); + Local<Object> global = context->Global(); + Local<v8::Function> function = + Function::New(context.local(), ReturnsSymbolCallback).ToLocalChecked(); + global->Set(context.local(), v8_str("x"), function).FromJust(); CompileRun( "function x_wrap() {\n" " for (var i = 0; i < 5; i++) {\n" @@ -20072,8 +22261,10 @@ TEST(EmptyApiCallback) { auto isolate = context->GetIsolate(); v8::HandleScope scope(isolate); auto global = context->Global(); - auto function = FunctionTemplate::New(isolate)->GetFunction(); - global->Set(v8_str("x"), function); + auto function = FunctionTemplate::New(isolate) + ->GetFunction(context.local()) + .ToLocalChecked(); + global->Set(context.local(), v8_str("x"), function).FromJust(); auto result = CompileRun("x()"); CHECK(v8::Utils::OpenHandle(*result)->IsJSGlobalProxy()); @@ -20081,13 +22272,19 @@ TEST(EmptyApiCallback) { result = CompileRun("x(1,2,3)"); CHECK(v8::Utils::OpenHandle(*result)->IsJSGlobalProxy()); + result = CompileRun("x.call(undefined)"); + CHECK(v8::Utils::OpenHandle(*result)->IsJSGlobalProxy()); + + result = CompileRun("x.call(null)"); + CHECK(v8::Utils::OpenHandle(*result)->IsJSGlobalProxy()); + result = CompileRun("7 + x.call(3) + 11"); CHECK(result->IsInt32()); - CHECK_EQ(21, result->Int32Value()); + CHECK_EQ(21, result->Int32Value(context.local()).FromJust()); result = CompileRun("7 + x.call(3, 101, 102, 103, 104) + 11"); CHECK(result->IsInt32()); - CHECK_EQ(21, result->Int32Value()); + CHECK_EQ(21, result->Int32Value(context.local()).FromJust()); result = CompileRun("var y = []; x.call(y)"); CHECK(result->IsArray()); @@ -20104,9 +22301,13 @@ TEST(SimpleSignatureCheck) { auto global = context->Global(); auto sig_obj = FunctionTemplate::New(isolate); auto sig = v8::Signature::New(isolate, sig_obj); - auto x = FunctionTemplate::New(isolate, Returns42, Handle<Value>(), sig); - global->Set(v8_str("sig_obj"), sig_obj->GetFunction()); - global->Set(v8_str("x"), x->GetFunction()); + auto x = FunctionTemplate::New(isolate, Returns42, Local<Value>(), sig); + global->Set(context.local(), v8_str("sig_obj"), + sig_obj->GetFunction(context.local()).ToLocalChecked()) + .FromJust(); + global->Set(context.local(), v8_str("x"), + x->GetFunction(context.local()).ToLocalChecked()) + .FromJust(); CompileRun("var s = new sig_obj();"); { TryCatch try_catch(isolate); @@ -20122,13 +22323,13 @@ TEST(SimpleSignatureCheck) { TryCatch try_catch(isolate); auto result = CompileRun("s.x = x; s.x()"); CHECK(!try_catch.HasCaught()); - CHECK_EQ(42, result->Int32Value()); + CHECK_EQ(42, result->Int32Value(context.local()).FromJust()); } { TryCatch try_catch(isolate); auto result = CompileRun("x.call(s)"); CHECK(!try_catch.HasCaught()); - CHECK_EQ(42, result->Int32Value()); + CHECK_EQ(42, result->Int32Value(context.local()).FromJust()); } } @@ -20145,9 +22346,13 @@ TEST(ChainSignatureCheck) { temp->Inherit(sig_obj); sig_obj = temp; } - auto x = FunctionTemplate::New(isolate, Returns42, Handle<Value>(), sig); - global->Set(v8_str("sig_obj"), sig_obj->GetFunction()); - global->Set(v8_str("x"), x->GetFunction()); + auto x = FunctionTemplate::New(isolate, Returns42, Local<Value>(), sig); + global->Set(context.local(), v8_str("sig_obj"), + sig_obj->GetFunction(context.local()).ToLocalChecked()) + .FromJust(); + global->Set(context.local(), v8_str("x"), + x->GetFunction(context.local()).ToLocalChecked()) + .FromJust(); CompileRun("var s = new sig_obj();"); { TryCatch try_catch(isolate); @@ -20163,13 +22368,13 @@ TEST(ChainSignatureCheck) { TryCatch try_catch(isolate); auto result = CompileRun("s.x = x; s.x()"); CHECK(!try_catch.HasCaught()); - CHECK_EQ(42, result->Int32Value()); + CHECK_EQ(42, result->Int32Value(context.local()).FromJust()); } { TryCatch try_catch(isolate); auto result = CompileRun("x.call(s)"); CHECK(!try_catch.HasCaught()); - CHECK_EQ(42, result->Int32Value()); + CHECK_EQ(42, result->Int32Value(context.local()).FromJust()); } } @@ -20182,9 +22387,13 @@ TEST(PrototypeSignatureCheck) { auto sig_obj = FunctionTemplate::New(isolate); sig_obj->SetHiddenPrototype(true); auto sig = v8::Signature::New(isolate, sig_obj); - auto x = FunctionTemplate::New(isolate, Returns42, Handle<Value>(), sig); - global->Set(v8_str("sig_obj"), sig_obj->GetFunction()); - global->Set(v8_str("x"), x->GetFunction()); + auto x = FunctionTemplate::New(isolate, Returns42, Local<Value>(), sig); + global->Set(context.local(), v8_str("sig_obj"), + sig_obj->GetFunction(context.local()).ToLocalChecked()) + .FromJust(); + global->Set(context.local(), v8_str("x"), + x->GetFunction(context.local()).ToLocalChecked()) + .FromJust(); CompileRun("s = {}; s.__proto__ = new sig_obj();"); { TryCatch try_catch(isolate); @@ -20200,13 +22409,13 @@ TEST(PrototypeSignatureCheck) { TryCatch try_catch(isolate); auto result = CompileRun("s.x = x; s.x()"); CHECK(!try_catch.HasCaught()); - CHECK_EQ(42, result->Int32Value()); + CHECK_EQ(42, result->Int32Value(context.local()).FromJust()); } { TryCatch try_catch(isolate); auto result = CompileRun("x.call(s)"); CHECK(!try_catch.HasCaught()); - CHECK_EQ(42, result->Int32Value()); + CHECK_EQ(42, result->Int32Value(context.local()).FromJust()); } } @@ -20238,94 +22447,26 @@ TEST(Promises) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - Handle<Object> global = context->Global(); // Creation. - Handle<v8::Promise::Resolver> pr = v8::Promise::Resolver::New(isolate); - Handle<v8::Promise::Resolver> rr = v8::Promise::Resolver::New(isolate); - Handle<v8::Promise> p = pr->GetPromise(); - Handle<v8::Promise> r = rr->GetPromise(); - CHECK_EQ(isolate, p->GetIsolate()); + Local<v8::Promise::Resolver> pr = + v8::Promise::Resolver::New(context.local()).ToLocalChecked(); + Local<v8::Promise::Resolver> rr = + v8::Promise::Resolver::New(context.local()).ToLocalChecked(); + Local<v8::Promise> p = pr->GetPromise(); + Local<v8::Promise> r = rr->GetPromise(); // IsPromise predicate. CHECK(p->IsPromise()); CHECK(r->IsPromise()); - Handle<Value> o = v8::Object::New(isolate); + Local<Value> o = v8::Object::New(isolate); CHECK(!o->IsPromise()); // Resolution and rejection. - pr->Resolve(v8::Integer::New(isolate, 1)); + pr->Resolve(context.local(), v8::Integer::New(isolate, 1)).FromJust(); CHECK(p->IsPromise()); - rr->Reject(v8::Integer::New(isolate, 2)); + rr->Reject(context.local(), v8::Integer::New(isolate, 2)).FromJust(); CHECK(r->IsPromise()); - - // Chaining non-pending promises. - CompileRun( - "var x1 = 0;\n" - "var x2 = 0;\n" - "function f1(x) { x1 = x; return x+1 };\n" - "function f2(x) { x2 = x; return x+1 };\n"); - Handle<Function> f1 = Handle<Function>::Cast(global->Get(v8_str("f1"))); - Handle<Function> f2 = Handle<Function>::Cast(global->Get(v8_str("f2"))); - - p->Chain(f1); - CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value()); - isolate->RunMicrotasks(); - CHECK_EQ(1, global->Get(v8_str("x1"))->Int32Value()); - - p->Catch(f2); - isolate->RunMicrotasks(); - CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value()); - - r->Catch(f2); - CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value()); - isolate->RunMicrotasks(); - CHECK_EQ(2, global->Get(v8_str("x2"))->Int32Value()); - - r->Chain(f1); - isolate->RunMicrotasks(); - CHECK_EQ(1, global->Get(v8_str("x1"))->Int32Value()); - - // Chaining pending promises. - CompileRun("x1 = x2 = 0;"); - pr = v8::Promise::Resolver::New(isolate); - rr = v8::Promise::Resolver::New(isolate); - - pr->GetPromise()->Chain(f1); - rr->GetPromise()->Catch(f2); - isolate->RunMicrotasks(); - CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value()); - CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value()); - - pr->Resolve(v8::Integer::New(isolate, 1)); - rr->Reject(v8::Integer::New(isolate, 2)); - CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value()); - CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value()); - - isolate->RunMicrotasks(); - CHECK_EQ(1, global->Get(v8_str("x1"))->Int32Value()); - CHECK_EQ(2, global->Get(v8_str("x2"))->Int32Value()); - - // Multi-chaining. - CompileRun("x1 = x2 = 0;"); - pr = v8::Promise::Resolver::New(isolate); - pr->GetPromise()->Chain(f1)->Chain(f2); - pr->Resolve(v8::Integer::New(isolate, 3)); - CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value()); - CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value()); - isolate->RunMicrotasks(); - CHECK_EQ(3, global->Get(v8_str("x1"))->Int32Value()); - CHECK_EQ(4, global->Get(v8_str("x2"))->Int32Value()); - - CompileRun("x1 = x2 = 0;"); - rr = v8::Promise::Resolver::New(isolate); - rr->GetPromise()->Catch(f1)->Chain(f2); - rr->Reject(v8::Integer::New(isolate, 3)); - CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value()); - CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value()); - isolate->RunMicrotasks(); - CHECK_EQ(3, global->Get(v8_str("x1"))->Int32Value()); - CHECK_EQ(4, global->Get(v8_str("x2"))->Int32Value()); } @@ -20333,19 +22474,21 @@ TEST(PromiseThen) { LocalContext context; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope scope(isolate); - Handle<Object> global = context->Global(); + Local<Object> global = context->Global(); // Creation. - Handle<v8::Promise::Resolver> pr = v8::Promise::Resolver::New(isolate); - Handle<v8::Promise::Resolver> qr = v8::Promise::Resolver::New(isolate); - Handle<v8::Promise> p = pr->GetPromise(); - Handle<v8::Promise> q = qr->GetPromise(); + Local<v8::Promise::Resolver> pr = + v8::Promise::Resolver::New(context.local()).ToLocalChecked(); + Local<v8::Promise::Resolver> qr = + v8::Promise::Resolver::New(context.local()).ToLocalChecked(); + Local<v8::Promise> p = pr->GetPromise(); + Local<v8::Promise> q = qr->GetPromise(); CHECK(p->IsPromise()); CHECK(q->IsPromise()); - pr->Resolve(v8::Integer::New(isolate, 1)); - qr->Resolve(p); + pr->Resolve(context.local(), v8::Integer::New(isolate, 1)).FromJust(); + qr->Resolve(context.local(), p).FromJust(); // Chaining non-pending promises. CompileRun( @@ -20353,45 +22496,73 @@ TEST(PromiseThen) { "var x2 = 0;\n" "function f1(x) { x1 = x; return x+1 };\n" "function f2(x) { x2 = x; return x+1 };\n"); - Handle<Function> f1 = Handle<Function>::Cast(global->Get(v8_str("f1"))); - Handle<Function> f2 = Handle<Function>::Cast(global->Get(v8_str("f2"))); - - // Chain - q->Chain(f1); - CHECK(global->Get(v8_str("x1"))->IsNumber()); - CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value()); - isolate->RunMicrotasks(); - CHECK(!global->Get(v8_str("x1"))->IsNumber()); - CHECK(p->Equals(global->Get(v8_str("x1")))); + Local<Function> f1 = Local<Function>::Cast( + global->Get(context.local(), v8_str("f1")).ToLocalChecked()); + Local<Function> f2 = Local<Function>::Cast( + global->Get(context.local(), v8_str("f2")).ToLocalChecked()); // Then CompileRun("x1 = x2 = 0;"); - q->Then(f1); - CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value()); + q->Then(context.local(), f1).ToLocalChecked(); + CHECK_EQ(0, global->Get(context.local(), v8_str("x1")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); isolate->RunMicrotasks(); - CHECK_EQ(1, global->Get(v8_str("x1"))->Int32Value()); + CHECK_EQ(1, global->Get(context.local(), v8_str("x1")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); // Then CompileRun("x1 = x2 = 0;"); - pr = v8::Promise::Resolver::New(isolate); - qr = v8::Promise::Resolver::New(isolate); + pr = v8::Promise::Resolver::New(context.local()).ToLocalChecked(); + qr = v8::Promise::Resolver::New(context.local()).ToLocalChecked(); - qr->Resolve(pr); - qr->GetPromise()->Then(f1)->Then(f2); + qr->Resolve(context.local(), pr).FromJust(); + qr->GetPromise() + ->Then(context.local(), f1) + .ToLocalChecked() + ->Then(context.local(), f2) + .ToLocalChecked(); - CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value()); - CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value()); + CHECK_EQ(0, global->Get(context.local(), v8_str("x1")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(0, global->Get(context.local(), v8_str("x2")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); isolate->RunMicrotasks(); - CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value()); - CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value()); + CHECK_EQ(0, global->Get(context.local(), v8_str("x1")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(0, global->Get(context.local(), v8_str("x2")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); - pr->Resolve(v8::Integer::New(isolate, 3)); + pr->Resolve(context.local(), v8::Integer::New(isolate, 3)).FromJust(); - CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value()); - CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value()); + CHECK_EQ(0, global->Get(context.local(), v8_str("x1")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(0, global->Get(context.local(), v8_str("x2")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); isolate->RunMicrotasks(); - CHECK_EQ(3, global->Get(v8_str("x1"))->Int32Value()); - CHECK_EQ(4, global->Get(v8_str("x2"))->Int32Value()); + CHECK_EQ(3, global->Get(context.local(), v8_str("x1")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); + CHECK_EQ(4, global->Get(context.local(), v8_str("x2")) + .ToLocalChecked() + ->Int32Value(context.local()) + .FromJust()); } @@ -20436,9 +22607,12 @@ TEST(Regress354123) { v8::Isolate* isolate = current->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); templ->SetAccessCheckCallback(AccessCounter); - current->Global()->Set(v8_str("friend"), templ->NewInstance()); + CHECK(current->Global() + ->Set(current.local(), v8_str("friend"), + templ->NewInstance(current.local()).ToLocalChecked()) + .FromJust()); // Test access using __proto__ from the prototype chain. access_count = 0; @@ -20481,8 +22655,8 @@ TEST(CaptureStackTraceForStackOverflow) { LocalContext current; v8::Isolate* isolate = current->GetIsolate(); v8::HandleScope scope(isolate); - V8::SetCaptureStackTraceForUncaughtExceptions( - true, 10, v8::StackTrace::kDetailed); + isolate->SetCaptureStackTraceForUncaughtExceptions(true, 10, + v8::StackTrace::kDetailed); v8::TryCatch try_catch(isolate); CompileRun("(function f(x) { f(x+1); })(0)"); CHECK(try_catch.HasCaught()); @@ -20496,8 +22670,8 @@ TEST(ScriptNameAndLineNumber) { const char* url = "http://www.foo.com/foo.js"; v8::ScriptOrigin origin(v8_str(url), v8::Integer::New(isolate, 13)); v8::ScriptCompiler::Source script_source(v8_str("var foo;"), origin); - Local<Script> script = v8::ScriptCompiler::Compile( - isolate, &script_source); + Local<Script> script = + v8::ScriptCompiler::Compile(env.local(), &script_source).ToLocalChecked(); Local<Value> script_name = script->GetUnboundScript()->GetScriptName(); CHECK(!script_name.IsEmpty()); CHECK(script_name->IsString()); @@ -20507,7 +22681,7 @@ TEST(ScriptNameAndLineNumber) { CHECK_EQ(13, line_number); } -void CheckMagicComments(Handle<Script> script, const char* expected_source_url, +void CheckMagicComments(Local<Script> script, const char* expected_source_url, const char* expected_source_mapping_url) { if (expected_source_url != NULL) { v8::String::Utf8Value url(script->GetUnboundScript()->GetSourceURL()); @@ -20605,34 +22779,56 @@ TEST(GetOwnPropertyDescriptor) { " set : function(value) { this.value = value; }," " get : function() { return this.value; }," "});"); - Local<Object> x = Local<Object>::Cast(env->Global()->Get(v8_str("x"))); - Local<Value> desc = x->GetOwnPropertyDescriptor(v8_str("no_prop")); + Local<Object> x = Local<Object>::Cast( + env->Global()->Get(env.local(), v8_str("x")).ToLocalChecked()); + Local<Value> desc = + x->GetOwnPropertyDescriptor(env.local(), v8_str("no_prop")) + .ToLocalChecked(); CHECK(desc->IsUndefined()); - desc = x->GetOwnPropertyDescriptor(v8_str("p0")); - CHECK(v8_num(12)->Equals(Local<Object>::Cast(desc)->Get(v8_str("value")))); - desc = x->GetOwnPropertyDescriptor(v8_str("p1")); + desc = + x->GetOwnPropertyDescriptor(env.local(), v8_str("p0")).ToLocalChecked(); + CHECK(v8_num(12) + ->Equals(env.local(), Local<Object>::Cast(desc) + ->Get(env.local(), v8_str("value")) + .ToLocalChecked()) + .FromJust()); + desc = + x->GetOwnPropertyDescriptor(env.local(), v8_str("p1")).ToLocalChecked(); Local<Function> set = - Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("set"))); + Local<Function>::Cast(Local<Object>::Cast(desc) + ->Get(env.local(), v8_str("set")) + .ToLocalChecked()); Local<Function> get = - Local<Function>::Cast(Local<Object>::Cast(desc)->Get(v8_str("get"))); - CHECK(v8_num(13)->Equals(get->Call(x, 0, NULL))); - Handle<Value> args[] = { v8_num(14) }; - set->Call(x, 1, args); - CHECK(v8_num(14)->Equals(get->Call(x, 0, NULL))); + Local<Function>::Cast(Local<Object>::Cast(desc) + ->Get(env.local(), v8_str("get")) + .ToLocalChecked()); + CHECK(v8_num(13) + ->Equals(env.local(), + get->Call(env.local(), x, 0, NULL).ToLocalChecked()) + .FromJust()); + Local<Value> args[] = {v8_num(14)}; + set->Call(env.local(), x, 1, args).ToLocalChecked(); + CHECK(v8_num(14) + ->Equals(env.local(), + get->Call(env.local(), x, 0, NULL).ToLocalChecked()) + .FromJust()); } TEST(Regress411877) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> object_template = + v8::Local<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(isolate); object_template->SetAccessCheckCallback(AccessCounter); - v8::Handle<Context> context = Context::New(isolate); + v8::Local<Context> context = Context::New(isolate); v8::Context::Scope context_scope(context); - context->Global()->Set(v8_str("o"), object_template->NewInstance()); + CHECK(context->Global() + ->Set(context, v8_str("o"), + object_template->NewInstance(context).ToLocalChecked()) + .FromJust()); CompileRun("Object.getOwnPropertyNames(o)"); } @@ -20640,16 +22836,17 @@ TEST(Regress411877) { TEST(GetHiddenPropertyTableAfterAccessCheck) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> object_template = + v8::Local<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(isolate); object_template->SetAccessCheckCallback(AccessCounter); - v8::Handle<Context> context = Context::New(isolate); + v8::Local<Context> context = Context::New(isolate); v8::Context::Scope context_scope(context); - v8::Handle<v8::Object> obj = object_template->NewInstance(); - obj->Set(v8_str("key"), v8_str("value")); - obj->Delete(v8_str("key")); + v8::Local<v8::Object> obj = + object_template->NewInstance(context).ToLocalChecked(); + obj->Set(context, v8_str("key"), v8_str("value")).FromJust(); + obj->Delete(context, v8_str("key")).FromJust(); obj->SetPrivate(context, v8::Private::New(isolate, v8_str("hidden key 2")), v8_str("hidden value 2")) @@ -20660,14 +22857,17 @@ TEST(GetHiddenPropertyTableAfterAccessCheck) { TEST(Regress411793) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> object_template = + v8::Local<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(isolate); object_template->SetAccessCheckCallback(AccessCounter); - v8::Handle<Context> context = Context::New(isolate); + v8::Local<Context> context = Context::New(isolate); v8::Context::Scope context_scope(context); - context->Global()->Set(v8_str("o"), object_template->NewInstance()); + CHECK(context->Global() + ->Set(context, v8_str("o"), + object_template->NewInstance(context).ToLocalChecked()) + .FromJust()); CompileRun( "Object.defineProperty(o, 'key', " " { get: function() {}, set: function() {} });"); @@ -20743,14 +22943,15 @@ void RunStreamingTest(const char** chunks, v8::ScriptOrigin origin(v8_str("http://foo.com")); char* full_source = TestSourceStream::FullSourceString(chunks); - v8::Handle<Script> script = v8::ScriptCompiler::Compile( - isolate, &source, v8_str(full_source), origin); + v8::MaybeLocal<Script> script = v8::ScriptCompiler::Compile( + env.local(), &source, v8_str(full_source), origin); if (expected_success) { CHECK(!script.IsEmpty()); - v8::Handle<Value> result(script->Run()); + v8::Local<Value> result( + script.ToLocalChecked()->Run(env.local()).ToLocalChecked()); // All scripts are supposed to return the fixed value 13 when ran. - CHECK_EQ(13, result->Int32Value()); - CheckMagicComments(script, expected_source_url, + CHECK_EQ(13, result->Int32Value(env.local()).FromJust()); + CheckMagicComments(script.ToLocalChecked(), expected_source_url, expected_source_mapping_url); } else { CHECK(script.IsEmpty()); @@ -21016,10 +23217,12 @@ TEST(StreamingWithDebuggingEnabledLate) { v8::ScriptOrigin origin(v8_str("http://foo.com")); char* full_source = TestSourceStream::FullSourceString(chunks); - EnableDebugger(); + EnableDebugger(isolate); - v8::Handle<Script> script = v8::ScriptCompiler::Compile( - isolate, &source, v8_str(full_source), origin); + v8::Local<Script> script = + v8::ScriptCompiler::Compile(env.local(), &source, v8_str(full_source), + origin) + .ToLocalChecked(); Maybe<uint32_t> result = script->Run(env.local()).ToLocalChecked()->Uint32Value(env.local()); @@ -21027,7 +23230,7 @@ TEST(StreamingWithDebuggingEnabledLate) { delete[] full_source; - DisableDebugger(); + DisableDebugger(isolate); } @@ -21122,14 +23325,15 @@ TEST(StreamingWithHarmonyScopes) { v8::ScriptOrigin origin(v8_str("http://foo.com")); char* full_source = TestSourceStream::FullSourceString(chunks); - v8::Handle<Script> script = v8::ScriptCompiler::Compile( - isolate, &source, v8_str(full_source), origin); + v8::Local<Script> script = + v8::ScriptCompiler::Compile(env.local(), &source, v8_str(full_source), + origin) + .ToLocalChecked(); CHECK(!script.IsEmpty()); CHECK_EQ(false, try_catch.HasCaught()); // Running the script exposes the error. - v8::Handle<Value> result(script->Run()); - CHECK(result.IsEmpty()); + CHECK(script->Run(env.local()).IsEmpty()); CHECK(try_catch.HasCaught()); delete[] full_source; } @@ -21181,7 +23385,12 @@ TEST(CodeCache) { script = v8::ScriptCompiler::Compile(context, &source, option) .ToLocalChecked(); } - CHECK_EQ(2, script->Run()->ToInt32(isolate2)->Int32Value()); + CHECK_EQ(2, script->Run(context) + .ToLocalChecked() + ->ToInt32(context) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); } isolate2->Dispose(); } @@ -21193,13 +23402,16 @@ void TestInvalidCacheData(v8::ScriptCompiler::CompileOptions option) { int length = 16; v8::ScriptCompiler::CachedData* cached_data = new v8::ScriptCompiler::CachedData(data, length); - DCHECK(!cached_data->rejected); + CHECK(!cached_data->rejected); v8::ScriptOrigin origin(v8_str("origin")); v8::ScriptCompiler::Source source(v8_str("42"), origin, cached_data); - v8::Handle<v8::Script> script = - v8::ScriptCompiler::Compile(CcTest::isolate(), &source, option); + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); + v8::Local<v8::Script> script = + v8::ScriptCompiler::Compile(context, &source, option).ToLocalChecked(); CHECK(cached_data->rejected); - CHECK_EQ(42, script->Run()->Int32Value()); + CHECK_EQ( + 42, + script->Run(context).ToLocalChecked()->Int32Value(context).FromJust()); } @@ -21221,9 +23433,11 @@ TEST(ParserCacheRejectedGracefully) { v8::ScriptOrigin origin(v8_str("origin")); v8::Local<v8::String> source_str = v8_str("function foo() {}"); v8::ScriptCompiler::Source source(source_str, origin); - v8::Handle<v8::Script> script = v8::ScriptCompiler::Compile( - CcTest::isolate(), &source, v8::ScriptCompiler::kProduceParserCache); - CHECK(!script.IsEmpty()); + v8::Local<v8::Script> script = + v8::ScriptCompiler::Compile(context.local(), &source, + v8::ScriptCompiler::kProduceParserCache) + .ToLocalChecked(); + USE(script); const v8::ScriptCompiler::CachedData* original_cached_data = source.GetCachedData(); CHECK(original_cached_data != NULL); @@ -21236,10 +23450,11 @@ TEST(ParserCacheRejectedGracefully) { source_str, origin, new v8::ScriptCompiler::CachedData(original_cached_data->data, original_cached_data->length)); - v8::Handle<v8::Script> script = - v8::ScriptCompiler::Compile(CcTest::isolate(), &source_with_cached_data, - v8::ScriptCompiler::kConsumeParserCache); - CHECK(!script.IsEmpty()); + v8::Local<v8::Script> script = + v8::ScriptCompiler::Compile(context.local(), &source_with_cached_data, + v8::ScriptCompiler::kConsumeParserCache) + .ToLocalChecked(); + USE(script); const v8::ScriptCompiler::CachedData* new_cached_data = source_with_cached_data.GetCachedData(); CHECK(new_cached_data != NULL); @@ -21255,10 +23470,11 @@ TEST(ParserCacheRejectedGracefully) { incompatible_source_str, origin, new v8::ScriptCompiler::CachedData(original_cached_data->data, original_cached_data->length)); - v8::Handle<v8::Script> script = - v8::ScriptCompiler::Compile(CcTest::isolate(), &source_with_cached_data, - v8::ScriptCompiler::kConsumeParserCache); - CHECK(!script.IsEmpty()); + v8::Local<v8::Script> script = + v8::ScriptCompiler::Compile(context.local(), &source_with_cached_data, + v8::ScriptCompiler::kConsumeParserCache) + .ToLocalChecked(); + USE(script); const v8::ScriptCompiler::CachedData* new_cached_data = source_with_cached_data.GetCachedData(); CHECK(new_cached_data != NULL); @@ -21272,7 +23488,8 @@ TEST(StringConcatOverflow) { v8::HandleScope scope(CcTest::isolate()); RandomLengthOneByteResource* r = new RandomLengthOneByteResource(i::String::kMaxLength); - v8::Local<v8::String> str = v8::String::NewExternal(CcTest::isolate(), r); + v8::Local<v8::String> str = + v8::String::NewExternalOneByte(CcTest::isolate(), r).ToLocalChecked(); CHECK(!str.IsEmpty()); v8::TryCatch try_catch(CcTest::isolate()); v8::Local<v8::String> result = v8::String::Concat(str, str); @@ -21324,11 +23541,13 @@ TEST(GetPrototypeAccessControl) { v8::HandleScope handle_scope(isolate); LocalContext env; - v8::Handle<v8::ObjectTemplate> obj_template = - v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(isolate); obj_template->SetAccessCheckCallback(AccessAlwaysBlocked); - env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance()); + CHECK(env->Global() + ->Set(env.local(), v8_str("prohibited"), + obj_template->NewInstance(env.local()).ToLocalChecked()) + .FromJust()); CHECK(CompileRun( "function f() { return %_GetPrototype(prohibited); }" @@ -21343,26 +23562,29 @@ TEST(GetPrototypeHidden) { v8::HandleScope handle_scope(isolate); LocalContext env; - Handle<FunctionTemplate> t = FunctionTemplate::New(isolate); + Local<FunctionTemplate> t = FunctionTemplate::New(isolate); t->SetHiddenPrototype(true); - Handle<Object> proto = t->GetFunction()->NewInstance(); - Handle<Object> object = Object::New(isolate); - Handle<Object> proto2 = Object::New(isolate); - object->SetPrototype(proto); - proto->SetPrototype(proto2); - - env->Global()->Set(v8_str("object"), object); - env->Global()->Set(v8_str("proto"), proto); - env->Global()->Set(v8_str("proto2"), proto2); - - v8::Handle<v8::Value> result = CompileRun("%_GetPrototype(object)"); - CHECK(result->Equals(proto2)); + Local<Object> proto = t->GetFunction(env.local()) + .ToLocalChecked() + ->NewInstance(env.local()) + .ToLocalChecked(); + Local<Object> object = Object::New(isolate); + Local<Object> proto2 = Object::New(isolate); + object->SetPrototype(env.local(), proto).FromJust(); + proto->SetPrototype(env.local(), proto2).FromJust(); + + CHECK(env->Global()->Set(env.local(), v8_str("object"), object).FromJust()); + CHECK(env->Global()->Set(env.local(), v8_str("proto"), proto).FromJust()); + CHECK(env->Global()->Set(env.local(), v8_str("proto2"), proto2).FromJust()); + + v8::Local<v8::Value> result = CompileRun("%_GetPrototype(object)"); + CHECK(result->Equals(env.local(), proto2).FromJust()); result = CompileRun( "function f() { return %_GetPrototype(object); }" "%OptimizeFunctionOnNextCall(f);" "f()"); - CHECK(result->Equals(proto2)); + CHECK(result->Equals(env.local(), proto2).FromJust()); } @@ -21371,7 +23593,7 @@ TEST(ClassPrototypeCreationContext) { v8::HandleScope handle_scope(isolate); LocalContext env; - Handle<Object> result = Handle<Object>::Cast( + Local<Object> result = Local<Object>::Cast( CompileRun("'use strict'; class Example { }; Example.prototype")); CHECK(env.local() == result->CreationContext()); } @@ -21412,22 +23634,25 @@ TEST(NewStringRangeError) { { v8::TryCatch try_catch(isolate); char* data = reinterpret_cast<char*>(buffer); - CHECK(v8::String::NewFromUtf8(isolate, data, v8::String::kNormalString, - length).IsEmpty()); + CHECK(v8::String::NewFromUtf8(isolate, data, v8::NewStringType::kNormal, + length) + .IsEmpty()); CHECK(!try_catch.HasCaught()); } { v8::TryCatch try_catch(isolate); uint8_t* data = reinterpret_cast<uint8_t*>(buffer); - CHECK(v8::String::NewFromOneByte(isolate, data, v8::String::kNormalString, - length).IsEmpty()); + CHECK(v8::String::NewFromOneByte(isolate, data, v8::NewStringType::kNormal, + length) + .IsEmpty()); CHECK(!try_catch.HasCaught()); } { v8::TryCatch try_catch(isolate); uint16_t* data = reinterpret_cast<uint16_t*>(buffer); - CHECK(v8::String::NewFromTwoByte(isolate, data, v8::String::kNormalString, - length).IsEmpty()); + CHECK(v8::String::NewFromTwoByte(isolate, data, v8::NewStringType::kNormal, + length) + .IsEmpty()); CHECK(!try_catch.HasCaught()); } free(buffer); @@ -21487,11 +23712,10 @@ TEST(StrongModeAccessCheckAllowed) { i::FLAG_strong_mode = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<Value> value; + v8::Local<Value> value; access_was_called = false; - v8::Handle<v8::ObjectTemplate> obj_template = - v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(isolate); obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42)); obj_template->SetAccessCheckCallback(AccessAlwaysAllowedWithFlag); @@ -21499,14 +23723,16 @@ TEST(StrongModeAccessCheckAllowed) { // Create an environment v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template); context0->Enter(); - v8::Handle<v8::Object> global0 = context0->Global(); - global0->Set(v8_str("object"), obj_template->NewInstance()); + v8::Local<v8::Object> global0 = context0->Global(); + global0->Set(context0, v8_str("object"), + obj_template->NewInstance(context0).ToLocalChecked()) + .FromJust(); { v8::TryCatch try_catch(isolate); value = CompileRun("'use strong'; object.x"); CHECK(!try_catch.HasCaught()); CHECK(!access_was_called); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(context0).FromJust()); } { v8::TryCatch try_catch(isolate); @@ -21524,14 +23750,16 @@ TEST(StrongModeAccessCheckAllowed) { // Create an environment v8::Local<Context> context1 = Context::New(isolate); context1->Enter(); - v8::Handle<v8::Object> global1 = context1->Global(); - global1->Set(v8_str("object"), obj_template->NewInstance()); + v8::Local<v8::Object> global1 = context1->Global(); + global1->Set(context1, v8_str("object"), + obj_template->NewInstance(context1).ToLocalChecked()) + .FromJust(); { v8::TryCatch try_catch(isolate); value = CompileRun("'use strong'; object.x"); CHECK(!try_catch.HasCaught()); CHECK(access_was_called); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(context1).FromJust()); } access_was_called = false; { @@ -21557,11 +23785,10 @@ TEST(StrongModeAccessCheckBlocked) { i::FLAG_strong_mode = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<Value> value; + v8::Local<Value> value; access_was_called = false; - v8::Handle<v8::ObjectTemplate> obj_template = - v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> obj_template = v8::ObjectTemplate::New(isolate); obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42)); obj_template->SetAccessCheckCallback(AccessAlwaysBlockedWithFlag); @@ -21569,14 +23796,16 @@ TEST(StrongModeAccessCheckBlocked) { // Create an environment v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template); context0->Enter(); - v8::Handle<v8::Object> global0 = context0->Global(); - global0->Set(v8_str("object"), obj_template->NewInstance()); + v8::Local<v8::Object> global0 = context0->Global(); + global0->Set(context0, v8_str("object"), + obj_template->NewInstance(context0).ToLocalChecked()) + .FromJust(); { v8::TryCatch try_catch(isolate); value = CompileRun("'use strong'; object.x"); CHECK(!try_catch.HasCaught()); CHECK(!access_was_called); - CHECK_EQ(42, value->Int32Value()); + CHECK_EQ(42, value->Int32Value(context0).FromJust()); } { v8::TryCatch try_catch(isolate); @@ -21594,8 +23823,10 @@ TEST(StrongModeAccessCheckBlocked) { // Create an environment v8::Local<Context> context1 = Context::New(isolate); context1->Enter(); - v8::Handle<v8::Object> global1 = context1->Global(); - global1->Set(v8_str("object"), obj_template->NewInstance()); + v8::Local<v8::Object> global1 = context1->Global(); + global1->Set(context1, v8_str("object"), + obj_template->NewInstance(context1).ToLocalChecked()) + .FromJust(); { v8::TryCatch try_catch(isolate); value = CompileRun("'use strong'; object.x"); @@ -21639,21 +23870,23 @@ TEST(StrongModeArityCallFromApi) { { v8::TryCatch try_catch(isolate); - fun->Call(v8::Undefined(isolate), 0, nullptr); + CHECK(fun->Call(env.local(), v8::Undefined(isolate), 0, nullptr).IsEmpty()); CHECK(try_catch.HasCaught()); } { v8::TryCatch try_catch(isolate); - v8::Handle<Value> args[] = {v8_num(42)}; - fun->Call(v8::Undefined(isolate), arraysize(args), args); + v8::Local<Value> args[] = {v8_num(42)}; + fun->Call(env.local(), v8::Undefined(isolate), arraysize(args), args) + .ToLocalChecked(); CHECK(!try_catch.HasCaught()); } { v8::TryCatch try_catch(isolate); - v8::Handle<Value> args[] = {v8_num(42), v8_num(555)}; - fun->Call(v8::Undefined(isolate), arraysize(args), args); + v8::Local<Value> args[] = {v8_num(42), v8_num(555)}; + fun->Call(env.local(), v8::Undefined(isolate), arraysize(args), args) + .ToLocalChecked(); CHECK(!try_catch.HasCaught()); } } @@ -21677,21 +23910,23 @@ TEST(StrongModeArityCallFromApi2) { { v8::TryCatch try_catch(isolate); - fun->Call(v8::Undefined(isolate), 0, nullptr); + CHECK(fun->Call(env.local(), v8::Undefined(isolate), 0, nullptr).IsEmpty()); CHECK(try_catch.HasCaught()); } { v8::TryCatch try_catch(isolate); - v8::Handle<Value> args[] = {v8_num(42)}; - fun->Call(v8::Undefined(isolate), arraysize(args), args); + v8::Local<Value> args[] = {v8_num(42)}; + fun->Call(env.local(), v8::Undefined(isolate), arraysize(args), args) + .ToLocalChecked(); CHECK(!try_catch.HasCaught()); } { v8::TryCatch try_catch(isolate); - v8::Handle<Value> args[] = {v8_num(42), v8_num(555)}; - fun->Call(v8::Undefined(isolate), arraysize(args), args); + v8::Local<Value> args[] = {v8_num(42), v8_num(555)}; + fun->Call(env.local(), v8::Undefined(isolate), arraysize(args), args) + .ToLocalChecked(); CHECK(!try_catch.HasCaught()); } } @@ -21704,24 +23939,28 @@ TEST(StrongObjectDelete) { v8::HandleScope scope(isolate); Local<Object> obj; { - v8::TryCatch try_catch; + v8::TryCatch try_catch(isolate); obj = Local<Object>::Cast(CompileRun( "'use strong';" "({});")); CHECK(!try_catch.HasCaught()); } - obj->ForceSet(v8_str("foo"), v8_num(1), v8::None); - obj->ForceSet(v8_str("2"), v8_num(1), v8::None); - CHECK(obj->HasOwnProperty(v8_str("foo"))); - CHECK(obj->HasOwnProperty(v8_str("2"))); - CHECK(!obj->Delete(v8_str("foo"))); - CHECK(!obj->Delete(2)); + obj->DefineOwnProperty(env.local(), v8_str("foo"), v8_num(1), v8::None) + .FromJust(); + obj->DefineOwnProperty(env.local(), v8_str("2"), v8_num(1), v8::None) + .FromJust(); + CHECK(obj->HasOwnProperty(env.local(), v8_str("foo")).FromJust()); + CHECK(obj->HasOwnProperty(env.local(), v8_str("2")).FromJust()); + CHECK(!obj->Delete(env.local(), v8_str("foo")).FromJust()); + CHECK(!obj->Delete(env.local(), 2).FromJust()); } static void ExtrasBindingTestRuntimeFunction( const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK_EQ(3, args[0]->Int32Value()); + CHECK_EQ( + 3, + args[0]->Int32Value(args.GetIsolate()->GetCurrentContext()).FromJust()); args.GetReturnValue().Set(v8_num(7)); } @@ -21735,19 +23974,27 @@ TEST(ExtrasBindingObject) { // export the tested functions. v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - auto func = - binding->Get(v8_str("testExtraShouldReturnFive")).As<v8::Function>(); + auto func = binding->Get(env.local(), v8_str("testExtraShouldReturnFive")) + .ToLocalChecked() + .As<v8::Function>(); auto undefined = v8::Undefined(isolate); - auto result = func->Call(undefined, 0, {}).As<v8::Number>(); - CHECK_EQ(5, result->Int32Value()); + auto result = func->Call(env.local(), undefined, 0, {}) + .ToLocalChecked() + .As<v8::Number>(); + CHECK_EQ(5, result->Int32Value(env.local()).FromJust()); - v8::Handle<v8::FunctionTemplate> runtimeFunction = + v8::Local<v8::FunctionTemplate> runtimeFunction = v8::FunctionTemplate::New(isolate, ExtrasBindingTestRuntimeFunction); - binding->Set(v8_str("runtime"), runtimeFunction->GetFunction()); - func = - binding->Get(v8_str("testExtraShouldCallToRuntime")).As<v8::Function>(); - result = func->Call(undefined, 0, {}).As<v8::Number>(); - CHECK_EQ(7, result->Int32Value()); + binding->Set(env.local(), v8_str("runtime"), + runtimeFunction->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); + func = binding->Get(env.local(), v8_str("testExtraShouldCallToRuntime")) + .ToLocalChecked() + .As<v8::Function>(); + result = func->Call(env.local(), undefined, 0, {}) + .ToLocalChecked() + .As<v8::Number>(); + CHECK_EQ(7, result->Int32Value(env.local()).FromJust()); } @@ -21762,19 +24009,29 @@ TEST(ExperimentalExtras) { // which should export the tested functions. v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - auto func = binding->Get(v8_str("testExperimentalExtraShouldReturnTen")) - .As<v8::Function>(); + auto func = + binding->Get(env.local(), v8_str("testExperimentalExtraShouldReturnTen")) + .ToLocalChecked() + .As<v8::Function>(); auto undefined = v8::Undefined(isolate); - auto result = func->Call(undefined, 0, {}).As<v8::Number>(); - CHECK_EQ(10, result->Int32Value()); + auto result = func->Call(env.local(), undefined, 0, {}) + .ToLocalChecked() + .As<v8::Number>(); + CHECK_EQ(10, result->Int32Value(env.local()).FromJust()); - v8::Handle<v8::FunctionTemplate> runtimeFunction = + v8::Local<v8::FunctionTemplate> runtimeFunction = v8::FunctionTemplate::New(isolate, ExtrasBindingTestRuntimeFunction); - binding->Set(v8_str("runtime"), runtimeFunction->GetFunction()); - func = binding->Get(v8_str("testExperimentalExtraShouldCallToRuntime")) + binding->Set(env.local(), v8_str("runtime"), + runtimeFunction->GetFunction(env.local()).ToLocalChecked()) + .FromJust(); + func = binding->Get(env.local(), + v8_str("testExperimentalExtraShouldCallToRuntime")) + .ToLocalChecked() .As<v8::Function>(); - result = func->Call(undefined, 0, {}).As<v8::Number>(); - CHECK_EQ(7, result->Int32Value()); + result = func->Call(env.local(), undefined, 0, {}) + .ToLocalChecked() + .As<v8::Number>(); + CHECK_EQ(7, result->Int32Value(env.local()).FromJust()); } @@ -21786,34 +24043,44 @@ TEST(ExtrasUtilsObject) { LocalContext env; v8::Local<v8::Object> binding = env->GetExtrasBindingObject(); - auto func = binding->Get(v8_str("testExtraCanUseUtils")).As<v8::Function>(); + auto func = binding->Get(env.local(), v8_str("testExtraCanUseUtils")) + .ToLocalChecked() + .As<v8::Function>(); auto undefined = v8::Undefined(isolate); - auto result = func->Call(undefined, 0, {}).As<v8::Object>(); + auto result = func->Call(env.local(), undefined, 0, {}) + .ToLocalChecked() + .As<v8::Object>(); - auto private_symbol = result->Get(v8_str("privateSymbol")).As<v8::Symbol>(); + auto private_symbol = result->Get(env.local(), v8_str("privateSymbol")) + .ToLocalChecked() + .As<v8::Symbol>(); i::Handle<i::Symbol> ips = v8::Utils::OpenHandle(*private_symbol); CHECK_EQ(true, ips->IsPrivate()); CompileRun("var result = 0; function store(x) { result = x; }"); auto store = CompileRun("store").As<v8::Function>(); - auto fulfilled_promise = - result->Get(v8_str("fulfilledPromise")).As<v8::Promise>(); - fulfilled_promise->Then(store); + auto fulfilled_promise = result->Get(env.local(), v8_str("fulfilledPromise")) + .ToLocalChecked() + .As<v8::Promise>(); + fulfilled_promise->Then(env.local(), store).ToLocalChecked(); isolate->RunMicrotasks(); - CHECK_EQ(1, CompileRun("result")->Int32Value()); + CHECK_EQ(1, CompileRun("result")->Int32Value(env.local()).FromJust()); auto fulfilled_promise_2 = - result->Get(v8_str("fulfilledPromise2")).As<v8::Promise>(); - fulfilled_promise_2->Then(store); + result->Get(env.local(), v8_str("fulfilledPromise2")) + .ToLocalChecked() + .As<v8::Promise>(); + fulfilled_promise_2->Then(env.local(), store).ToLocalChecked(); isolate->RunMicrotasks(); - CHECK_EQ(2, CompileRun("result")->Int32Value()); + CHECK_EQ(2, CompileRun("result")->Int32Value(env.local()).FromJust()); - auto rejected_promise = - result->Get(v8_str("rejectedPromise")).As<v8::Promise>(); - rejected_promise->Catch(store); + auto rejected_promise = result->Get(env.local(), v8_str("rejectedPromise")) + .ToLocalChecked() + .As<v8::Promise>(); + rejected_promise->Catch(env.local(), store).ToLocalChecked(); isolate->RunMicrotasks(); - CHECK_EQ(3, CompileRun("result")->Int32Value()); + CHECK_EQ(3, CompileRun("result")->Int32Value(env.local()).FromJust()); } @@ -21835,10 +24102,18 @@ TEST(Map) { v8::Local<v8::Array> contents = map->AsArray(); CHECK_EQ(4U, contents->Length()); - CHECK_EQ(1, contents->Get(0).As<v8::Int32>()->Value()); - CHECK_EQ(2, contents->Get(1).As<v8::Int32>()->Value()); - CHECK_EQ(3, contents->Get(2).As<v8::Int32>()->Value()); - CHECK_EQ(4, contents->Get(3).As<v8::Int32>()->Value()); + CHECK_EQ( + 1, + contents->Get(env.local(), 0).ToLocalChecked().As<v8::Int32>()->Value()); + CHECK_EQ( + 2, + contents->Get(env.local(), 1).ToLocalChecked().As<v8::Int32>()->Value()); + CHECK_EQ( + 3, + contents->Get(env.local(), 2).ToLocalChecked().As<v8::Int32>()->Value()); + CHECK_EQ( + 4, + contents->Get(env.local(), 3).ToLocalChecked().As<v8::Int32>()->Value()); CHECK_EQ(2U, map->Size()); @@ -21850,10 +24125,12 @@ TEST(Map) { CHECK_EQ(2, map->Get(env.local(), v8::Integer::New(isolate, 1)) .ToLocalChecked() - ->Int32Value()); + ->Int32Value(env.local()) + .FromJust()); CHECK_EQ(4, map->Get(env.local(), v8::Integer::New(isolate, 3)) .ToLocalChecked() - ->Int32Value()); + ->Int32Value(env.local()) + .FromJust()); CHECK(map->Get(env.local(), v8::Integer::New(isolate, 42)) .ToLocalChecked() @@ -21891,8 +24168,10 @@ TEST(Set) { v8::Local<v8::Array> keys = set->AsArray(); CHECK_EQ(2U, keys->Length()); - CHECK_EQ(1, keys->Get(0).As<v8::Int32>()->Value()); - CHECK_EQ(2, keys->Get(1).As<v8::Int32>()->Value()); + CHECK_EQ(1, + keys->Get(env.local(), 0).ToLocalChecked().As<v8::Int32>()->Value()); + CHECK_EQ(2, + keys->Get(env.local(), 1).ToLocalChecked().As<v8::Int32>()->Value()); CHECK_EQ(2U, set->Size()); @@ -21927,7 +24206,10 @@ TEST(CompatibleReceiverCheckOnCachedICHandler) { v8::Local<v8::FunctionTemplate> child = v8::FunctionTemplate::New(isolate); child->Inherit(parent); LocalContext env; - env->Global()->Set(v8_str("Child"), child->GetFunction()); + CHECK(env->Global() + ->Set(env.local(), v8_str("Child"), + child->GetFunction(env.local()).ToLocalChecked()) + .FromJust()); // Make sure there's a compiled stub for "Child.prototype.age" in the cache. CompileRun( @@ -21962,7 +24244,7 @@ class FutexInterruptionThread : public v8::base::Thread { virtual void Run() { // Wait a bit before terminating. v8::base::OS::Sleep(v8::base::TimeDelta::FromMilliseconds(100)); - v8::V8::TerminateExecution(isolate_); + isolate_->TerminateExecution(); } private: @@ -22010,7 +24292,7 @@ bool NoAbortOnUncaughtException(v8::Isolate* isolate) { TEST(AbortOnUncaughtExceptionNoAbort) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate); LocalContext env(NULL, global_template); @@ -22020,10 +24302,10 @@ TEST(AbortOnUncaughtExceptionNoAbort) { CompileRun("function boom() { throw new Error(\"boom\") }"); v8::Local<v8::Object> global_object = env->Global(); - v8::Local<v8::Function> foo = - v8::Local<v8::Function>::Cast(global_object->Get(v8_str("boom"))); + v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( + global_object->Get(env.local(), v8_str("boom")).ToLocalChecked()); - foo->Call(global_object, 0, NULL); + CHECK(foo->Call(env.local(), global_object, 0, NULL).IsEmpty()); CHECK_EQ(1, nb_uncaught_exception_callback_calls); } @@ -22040,13 +24322,14 @@ TEST(AccessCheckedIsConcatSpreadable) { spreadable_template->SetAccessCheckCallback(AccessBlocker); spreadable_template->Set(v8::Symbol::GetIsConcatSpreadable(isolate), v8::Boolean::New(isolate, true)); - Local<Object> object = spreadable_template->NewInstance(); + Local<Object> object = + spreadable_template->NewInstance(env.local()).ToLocalChecked(); allowed_access = true; - env->Global()->Set(v8_str("object"), object); - object->Set(v8_str("length"), v8_num(2)); - object->Set(0U, v8_str("a")); - object->Set(1U, v8_str("b")); + CHECK(env->Global()->Set(env.local(), v8_str("object"), object).FromJust()); + object->Set(env.local(), v8_str("length"), v8_num(2)).FromJust(); + object->Set(env.local(), 0U, v8_str("a")).FromJust(); + object->Set(env.local(), 1U, v8_str("b")).FromJust(); // Access check is allowed, and the object is spread CompileRun("var result = [].concat(object)"); @@ -22075,11 +24358,13 @@ TEST(AccessCheckedToStringTag) { // Object with access check Local<ObjectTemplate> object_template = v8::ObjectTemplate::New(isolate); object_template->SetAccessCheckCallback(AccessBlocker); - Local<Object> object = object_template->NewInstance(); + Local<Object> object = + object_template->NewInstance(env.local()).ToLocalChecked(); allowed_access = true; - env->Global()->Set(v8_str("object"), object); - object->Set(v8::Symbol::GetToStringTag(isolate), v8_str("hello")); + env->Global()->Set(env.local(), v8_str("object"), object).FromJust(); + object->Set(env.local(), v8::Symbol::GetToStringTag(isolate), v8_str("hello")) + .FromJust(); // Access check is allowed, and the toStringTag is read CompileRun("var result = Object.prototype.toString.call(object)"); @@ -22112,26 +24397,57 @@ TEST(ObjectTemplateIntrinsics) { Local<ObjectTemplate> object_template = v8::ObjectTemplate::New(isolate); object_template->SetIntrinsicDataProperty(v8_str("values"), v8::kArrayProto_values); - Local<Object> object = object_template->NewInstance(); + Local<Object> object = + object_template->NewInstance(env.local()).ToLocalChecked(); - env->Global()->Set(v8_str("obj1"), object); + CHECK(env->Global()->Set(env.local(), v8_str("obj1"), object).FromJust()); ExpectString("typeof obj1.values", "function"); - auto values = Local<Function>::Cast(object->Get(v8_str("values"))); + auto values = Local<Function>::Cast( + object->Get(env.local(), v8_str("values")).ToLocalChecked()); auto fn = i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*values)); auto ctx = v8::Utils::OpenHandle(*env.local()); CHECK_EQ(fn->GetCreationContext(), *ctx); { LocalContext env2; - Local<Object> object2 = object_template->NewInstance(); - env2->Global()->Set(v8_str("obj2"), object2); + Local<Object> object2 = + object_template->NewInstance(env2.local()).ToLocalChecked(); + CHECK( + env2->Global()->Set(env2.local(), v8_str("obj2"), object2).FromJust()); ExpectString("typeof obj2.values", "function"); - CHECK_NE(*object->Get(v8_str("values")), *object2->Get(v8_str("values"))); + CHECK_NE(*object->Get(env2.local(), v8_str("values")).ToLocalChecked(), + *object2->Get(env2.local(), v8_str("values")).ToLocalChecked()); - auto values2 = Local<Function>::Cast(object2->Get(v8_str("values"))); + auto values2 = Local<Function>::Cast( + object2->Get(env2.local(), v8_str("values")).ToLocalChecked()); auto fn2 = i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*values2)); auto ctx2 = v8::Utils::OpenHandle(*env2.local()); CHECK_EQ(fn2->GetCreationContext(), *ctx2); } } + + +TEST(Proxy) { + i::FLAG_harmony_proxies = true; + LocalContext context; + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Local<v8::Object> target = CompileRun("({})").As<v8::Object>(); + v8::Local<v8::Object> handler = CompileRun("({})").As<v8::Object>(); + + v8::Local<v8::Proxy> proxy = + v8::Proxy::New(context.local(), target, handler).ToLocalChecked(); + CHECK(proxy->IsProxy()); + CHECK(!target->IsProxy()); + CHECK(!proxy->IsRevoked()); + CHECK(proxy->GetTarget()->SameValue(target)); + CHECK(proxy->GetHandler()->SameValue(handler)); + + proxy->Revoke(); + CHECK(proxy->IsProxy()); + CHECK(!target->IsProxy()); + CHECK(proxy->IsRevoked()); + CHECK(proxy->GetTarget()->SameValue(target)); + CHECK(proxy->GetHandler()->IsNull()); +} diff --git a/deps/v8/test/cctest/test-asm-validator.cc b/deps/v8/test/cctest/test-asm-validator.cc index 8923e21e9f..fae75008c7 100644 --- a/deps/v8/test/cctest/test-asm-validator.cc +++ b/deps/v8/test/cctest/test-asm-validator.cc @@ -4,11 +4,11 @@ #include "src/v8.h" -#include "src/ast.h" -#include "src/ast-expression-visitor.h" -#include "src/parser.h" -#include "src/rewriter.h" -#include "src/scopes.h" +#include "src/ast/ast.h" +#include "src/ast/ast-expression-visitor.h" +#include "src/ast/scopes.h" +#include "src/parsing/parser.h" +#include "src/parsing/rewriter.h" #include "src/type-cache.h" #include "src/typing-asm.h" #include "test/cctest/cctest.h" @@ -16,28 +16,34 @@ #include "test/cctest/expression-type-collector-macros.h" // Macros for function types. -#define FUNC_V_TYPE Bounds(Type::Function(Type::Undefined(), zone)) -#define FUNC_I_TYPE Bounds(Type::Function(cache.kInt32, zone)) -#define FUNC_F_TYPE Bounds(Type::Function(cache.kFloat32, zone)) -#define FUNC_D_TYPE Bounds(Type::Function(cache.kFloat64, zone)) +#define FUNC_V_TYPE Bounds(Type::Function(Type::Undefined(zone), zone)) +#define FUNC_I_TYPE Bounds(Type::Function(cache.kAsmSigned, zone)) +#define FUNC_F_TYPE Bounds(Type::Function(cache.kAsmFloat, zone)) +#define FUNC_D_TYPE Bounds(Type::Function(cache.kAsmDouble, zone)) #define FUNC_D2D_TYPE \ - Bounds(Type::Function(cache.kFloat64, cache.kFloat64, zone)) + Bounds(Type::Function(cache.kAsmDouble, cache.kAsmDouble, zone)) #define FUNC_N2F_TYPE \ - Bounds(Type::Function(cache.kFloat32, Type::Number(), zone)) -#define FUNC_I2I_TYPE Bounds(Type::Function(cache.kInt32, cache.kInt32, zone)) + Bounds(Type::Function(cache.kAsmFloat, Type::Number(zone), zone)) +#define FUNC_I2I_TYPE \ + Bounds(Type::Function(cache.kAsmSigned, cache.kAsmInt, zone)) #define FUNC_II2D_TYPE \ - Bounds(Type::Function(cache.kFloat64, cache.kInt32, cache.kInt32, zone)) + Bounds(Type::Function(cache.kAsmDouble, cache.kAsmInt, cache.kAsmInt, zone)) #define FUNC_II2I_TYPE \ - Bounds(Type::Function(cache.kInt32, cache.kInt32, cache.kInt32, zone)) -#define FUNC_DD2D_TYPE \ - Bounds(Type::Function(cache.kFloat64, cache.kFloat64, cache.kFloat64, zone)) + Bounds(Type::Function(cache.kAsmSigned, cache.kAsmInt, cache.kAsmInt, zone)) +#define FUNC_DD2D_TYPE \ + Bounds(Type::Function(cache.kAsmDouble, cache.kAsmDouble, cache.kAsmDouble, \ + zone)) +#define FUNC_NN2N_TYPE \ + Bounds(Type::Function(Type::Number(zone), Type::Number(zone), \ + Type::Number(zone), zone)) #define FUNC_N2N_TYPE \ - Bounds(Type::Function(Type::Number(), Type::Number(), zone)) + Bounds(Type::Function(Type::Number(zone), Type::Number(zone), zone)) // Macros for array types. -#define FLOAT64_ARRAY_TYPE Bounds(Type::Array(cache.kFloat64, zone)) -#define FUNC_I2I_ARRAY_TYPE \ - Bounds(Type::Array(Type::Function(cache.kInt32, cache.kInt32, zone), zone)) +#define FLOAT64_ARRAY_TYPE Bounds(Type::Array(cache.kAsmDouble, zone)) +#define FUNC_I2I_ARRAY_TYPE \ + Bounds(Type::Array(Type::Function(cache.kAsmSigned, cache.kAsmInt, zone), \ + zone)) using namespace v8::internal; @@ -123,143 +129,143 @@ TEST(ValidateMinimum) { CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) { // function logSum CHECK_EXPR(FunctionLiteral, FUNC_II2D_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(start, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(start, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(start, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(start, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(end, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(end, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(end, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(end, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } - CHECK_EXPR(Assignment, Bounds(cache.kFloat64)) { - CHECK_VAR(sum, Bounds(cache.kFloat64)); - CHECK_EXPR(Literal, Bounds(cache.kFloat64)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) { + CHECK_VAR(sum, Bounds(cache.kAsmDouble)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); } - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(p, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(p, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(q, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(q, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } // for (p = start << 3, q = end << 3; - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(p, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(start, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(p, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(start, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(q, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(end, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(q, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(end, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } } // (p|0) < (q|0); - CHECK_EXPR(CompareOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(p, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(p, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(q, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(q, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } // p = (p + 8)|0) {\n" - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(p, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(p, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(p, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) { + CHECK_VAR(p, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } // sum = sum + +log(values[p>>3]); - CHECK_EXPR(Assignment, Bounds(cache.kFloat64)) { - CHECK_VAR(sum, Bounds(cache.kFloat64)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kFloat64)) { - CHECK_VAR(sum, Bounds(cache.kFloat64)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kFloat64)) { - CHECK_EXPR(Call, Bounds(cache.kFloat64)) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) { + CHECK_VAR(sum, Bounds(cache.kAsmDouble)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) { + CHECK_VAR(sum, Bounds(cache.kAsmDouble)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) { + CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) { CHECK_VAR(log, FUNC_D2D_TYPE); - CHECK_EXPR(Property, Bounds(cache.kFloat64)) { + CHECK_EXPR(Property, Bounds(cache.kAsmDouble)) { CHECK_VAR(values, FLOAT64_ARRAY_TYPE); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(p, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(p, Bounds(cache.kAsmSigned)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } } - CHECK_EXPR(Literal, Bounds(cache.kFloat64)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); } } } // return +sum; - CHECK_EXPR(BinaryOperation, Bounds(cache.kFloat64)) { - CHECK_VAR(sum, Bounds(cache.kFloat64)); - CHECK_EXPR(Literal, Bounds(cache.kFloat64)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) { + CHECK_VAR(sum, Bounds(cache.kAsmDouble)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); } } // function geometricMean CHECK_EXPR(FunctionLiteral, FUNC_II2D_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(start, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(start, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(start, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(start, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(end, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(end, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(end, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(end, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } // return +exp(+logSum(start, end) / +((end - start)|0)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kFloat64)) { - CHECK_EXPR(Call, Bounds(cache.kFloat64)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) { + CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) { CHECK_VAR(exp, FUNC_D2D_TYPE); - CHECK_EXPR(BinaryOperation, Bounds(cache.kFloat64)) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kFloat64)) { - CHECK_EXPR(Call, Bounds(cache.kFloat64)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) { + CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) { CHECK_VAR(logSum, FUNC_II2D_TYPE); - CHECK_VAR(start, Bounds(cache.kInt32)); - CHECK_VAR(end, Bounds(cache.kInt32)); + CHECK_VAR(start, Bounds(cache.kAsmInt)); + CHECK_VAR(end, Bounds(cache.kAsmInt)); } - CHECK_EXPR(Literal, Bounds(cache.kFloat64)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); } - CHECK_EXPR(BinaryOperation, Bounds(cache.kFloat64)) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(end, Bounds(cache.kInt32)); - CHECK_VAR(start, Bounds(cache.kInt32)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) { + CHECK_VAR(end, Bounds(cache.kAsmInt)); + CHECK_VAR(start, Bounds(cache.kAsmInt)); } - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } - CHECK_EXPR(Literal, Bounds(cache.kFloat64)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); } } } - CHECK_EXPR(Literal, Bounds(cache.kFloat64)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); } } // "use asm"; - CHECK_EXPR(Literal, Bounds(Type::String())); + CHECK_EXPR(Literal, Bounds(Type::String(zone))); // var exp = stdlib.Math.exp; CHECK_EXPR(Assignment, FUNC_D2D_TYPE) { CHECK_VAR(exp, FUNC_D2D_TYPE); @@ -303,6 +309,52 @@ TEST(ValidateMinimum) { } +TEST(MissingUseAsm) { + const char test_function[] = + "function foo() {\n" + " function bar() {}\n" + " return { bar: bar };\n" + "}\n"; + v8::V8::Initialize(); + HandleAndZoneScope handles; + Zone* zone = handles.main_zone(); + ZoneVector<ExpressionTypeEntry> types(zone); + CHECK_EQ("asm: line 1: missing \"use asm\"\n", + Validate(zone, test_function, &types)); +} + + +TEST(WrongUseAsm) { + const char test_function[] = + "function foo() {\n" + " \"use wasm\"\n" + " function bar() {}\n" + " return { bar: bar };\n" + "}\n"; + v8::V8::Initialize(); + HandleAndZoneScope handles; + Zone* zone = handles.main_zone(); + ZoneVector<ExpressionTypeEntry> types(zone); + CHECK_EQ("asm: line 1: missing \"use asm\"\n", + Validate(zone, test_function, &types)); +} + + +TEST(MissingReturnExports) { + const char test_function[] = + "function foo() {\n" + " \"use asm\"\n" + " function bar() {}\n" + "}\n"; + v8::V8::Initialize(); + HandleAndZoneScope handles; + Zone* zone = handles.main_zone(); + ZoneVector<ExpressionTypeEntry> types(zone); + CHECK_EQ("asm: line 2: last statement in module is not a return\n", + Validate(zone, test_function, &types)); +} + + #define HARNESS_STDLIB() \ "var Infinity = stdlib.Infinity;\n" \ "var NaN = stdlib.NaN;\n" \ @@ -394,12 +446,12 @@ TEST(ValidateMinimum) { namespace { -void CheckStdlibShortcuts(Zone* zone, ZoneVector<ExpressionTypeEntry>& types, - size_t& index, int& depth, TypeCache& cache) { - // var exp = stdlib.*; (D * 12) - CHECK_VAR_SHORTCUT(Infinity, Bounds(cache.kFloat64)); - CHECK_VAR_SHORTCUT(NaN, Bounds(cache.kFloat64)); - // var x = stdlib.Math.x; D2D +void CheckStdlibShortcuts1(Zone* zone, ZoneVector<ExpressionTypeEntry>& types, + size_t& index, int& depth, TypeCache& cache) { + // var exp = stdlib.*; + CHECK_VAR_SHORTCUT(Infinity, Bounds(cache.kAsmDouble)); + CHECK_VAR_SHORTCUT(NaN, Bounds(cache.kAsmDouble)); + // var x = stdlib.Math.x; CHECK_VAR_MATH_SHORTCUT(acos, FUNC_D2D_TYPE); CHECK_VAR_MATH_SHORTCUT(asin, FUNC_D2D_TYPE); CHECK_VAR_MATH_SHORTCUT(atan, FUNC_D2D_TYPE); @@ -408,27 +460,34 @@ void CheckStdlibShortcuts(Zone* zone, ZoneVector<ExpressionTypeEntry>& types, CHECK_VAR_MATH_SHORTCUT(tan, FUNC_D2D_TYPE); CHECK_VAR_MATH_SHORTCUT(exp, FUNC_D2D_TYPE); CHECK_VAR_MATH_SHORTCUT(log, FUNC_D2D_TYPE); - CHECK_VAR_MATH_SHORTCUT(ceil, FUNC_D2D_TYPE); - CHECK_VAR_MATH_SHORTCUT(floor, FUNC_D2D_TYPE); - CHECK_VAR_MATH_SHORTCUT(sqrt, FUNC_D2D_TYPE); - // var exp = stdlib.Math.*; (DD2D * 12) - CHECK_VAR_MATH_SHORTCUT(min, FUNC_DD2D_TYPE); - CHECK_VAR_MATH_SHORTCUT(max, FUNC_DD2D_TYPE); + + CHECK_VAR_MATH_SHORTCUT(ceil, FUNC_N2N_TYPE); + CHECK_VAR_MATH_SHORTCUT(floor, FUNC_N2N_TYPE); + CHECK_VAR_MATH_SHORTCUT(sqrt, FUNC_N2N_TYPE); + + CHECK_VAR_MATH_SHORTCUT(min, FUNC_NN2N_TYPE); + CHECK_VAR_MATH_SHORTCUT(max, FUNC_NN2N_TYPE); + CHECK_VAR_MATH_SHORTCUT(atan2, FUNC_DD2D_TYPE); CHECK_VAR_MATH_SHORTCUT(pow, FUNC_DD2D_TYPE); - // Special ones. + CHECK_VAR_MATH_SHORTCUT(abs, FUNC_N2N_TYPE); CHECK_VAR_MATH_SHORTCUT(imul, FUNC_II2I_TYPE); CHECK_VAR_MATH_SHORTCUT(fround, FUNC_N2F_TYPE); +} + + +void CheckStdlibShortcuts2(Zone* zone, ZoneVector<ExpressionTypeEntry>& types, + size_t& index, int& depth, TypeCache& cache) { // var exp = stdlib.Math.*; (D * 12) - CHECK_VAR_MATH_SHORTCUT(E, Bounds(cache.kFloat64)); - CHECK_VAR_MATH_SHORTCUT(LN10, Bounds(cache.kFloat64)); - CHECK_VAR_MATH_SHORTCUT(LN2, Bounds(cache.kFloat64)); - CHECK_VAR_MATH_SHORTCUT(LOG2E, Bounds(cache.kFloat64)); - CHECK_VAR_MATH_SHORTCUT(LOG10E, Bounds(cache.kFloat64)); - CHECK_VAR_MATH_SHORTCUT(PI, Bounds(cache.kFloat64)); - CHECK_VAR_MATH_SHORTCUT(SQRT1_2, Bounds(cache.kFloat64)); - CHECK_VAR_MATH_SHORTCUT(SQRT2, Bounds(cache.kFloat64)); + CHECK_VAR_MATH_SHORTCUT(E, Bounds(cache.kAsmDouble)); + CHECK_VAR_MATH_SHORTCUT(LN10, Bounds(cache.kAsmDouble)); + CHECK_VAR_MATH_SHORTCUT(LN2, Bounds(cache.kAsmDouble)); + CHECK_VAR_MATH_SHORTCUT(LOG2E, Bounds(cache.kAsmDouble)); + CHECK_VAR_MATH_SHORTCUT(LOG10E, Bounds(cache.kAsmDouble)); + CHECK_VAR_MATH_SHORTCUT(PI, Bounds(cache.kAsmDouble)); + CHECK_VAR_MATH_SHORTCUT(SQRT1_2, Bounds(cache.kAsmDouble)); + CHECK_VAR_MATH_SHORTCUT(SQRT2, Bounds(cache.kAsmDouble)); // var values = new stdlib.*Array(buffer); CHECK_VAR_NEW_SHORTCUT(u8, Bounds(cache.kUint8Array)); CHECK_VAR_NEW_SHORTCUT(i8, Bounds(cache.kInt8Array)); @@ -457,11 +516,12 @@ void CheckStdlibShortcuts(Zone* zone, ZoneVector<ExpressionTypeEntry>& types, CHECK_TYPES_BEGIN { \ /* Module. */ \ CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) { -#define CHECK_FUNC_TYPES_END_1() \ - /* "use asm"; */ \ - CHECK_EXPR(Literal, Bounds(Type::String())); \ - /* stdlib shortcuts. */ \ - CheckStdlibShortcuts(zone, types, index, depth, cache); +#define CHECK_FUNC_TYPES_END_1() \ + /* "use asm"; */ \ + CHECK_EXPR(Literal, Bounds(Type::String(zone))); \ + /* stdlib shortcuts. */ \ + CheckStdlibShortcuts1(zone, types, index, depth, cache); \ + CheckStdlibShortcuts2(zone, types, index, depth, cache); #define CHECK_FUNC_TYPES_END_2() \ @@ -504,10 +564,10 @@ TEST(ReturnVoid) { "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { // return undefined; - CHECK_EXPR(Literal, Bounds(Type::Undefined())); + CHECK_EXPR(Literal, Bounds(Type::Undefined(zone))); } CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { - CHECK_EXPR(Call, Bounds(Type::Undefined())) { + CHECK_EXPR(Call, Bounds(Type::Undefined(zone))) { CHECK_VAR(bar, FUNC_V_TYPE); } } @@ -522,7 +582,7 @@ TEST(EmptyBody) { "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE); CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { - CHECK_EXPR(Call, Bounds(Type::Undefined())) { + CHECK_EXPR(Call, Bounds(Type::Undefined(zone))) { CHECK_VAR(bar, FUNC_V_TYPE); } } @@ -536,13 +596,13 @@ TEST(DoesNothing) { "function bar() { var x = 1.0; }\n" "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kFloat64)) { - CHECK_VAR(x, Bounds(cache.kFloat64)); - CHECK_EXPR(Literal, Bounds(cache.kFloat64)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) { + CHECK_VAR(x, Bounds(cache.kAsmDouble)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); } } CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { - CHECK_EXPR(Call, Bounds(Type::Undefined())) { + CHECK_EXPR(Call, Bounds(Type::Undefined(zone))) { CHECK_VAR(bar, FUNC_V_TYPE); } } @@ -557,10 +617,12 @@ TEST(ReturnInt32Literal) { "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { // return 1; - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); } CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { - CHECK_EXPR(Call, Bounds(cache.kInt32)) { CHECK_VAR(bar, FUNC_I_TYPE); } + CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) { + CHECK_VAR(bar, FUNC_I_TYPE); + } } } CHECK_FUNC_TYPES_END @@ -573,10 +635,12 @@ TEST(ReturnFloat64Literal) { "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) { // return 1.0; - CHECK_EXPR(Literal, Bounds(cache.kFloat64)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); } CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { - CHECK_EXPR(Call, Bounds(cache.kFloat64)) { CHECK_VAR(bar, FUNC_D_TYPE); } + CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) { + CHECK_VAR(bar, FUNC_D_TYPE); + } } } CHECK_FUNC_TYPES_END @@ -589,13 +653,13 @@ TEST(ReturnFloat32Literal) { "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_F_TYPE) { // return fround(1.0); - CHECK_EXPR(Call, Bounds(cache.kFloat32)) { + CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) { CHECK_VAR(fround, FUNC_N2F_TYPE); - CHECK_EXPR(Literal, Bounds(cache.kFloat64)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); } } CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { - CHECK_EXPR(Call, Bounds(cache.kFloat32)) { CHECK_VAR(bar, FUNC_F_TYPE); } + CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) { CHECK_VAR(bar, FUNC_F_TYPE); } } } CHECK_FUNC_TYPES_END @@ -608,18 +672,20 @@ TEST(ReturnFloat64Var) { "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_D_TYPE) { // return 1.0; - CHECK_EXPR(Assignment, Bounds(cache.kFloat64)) { - CHECK_VAR(x, Bounds(cache.kFloat64)); - CHECK_EXPR(Literal, Bounds(cache.kFloat64)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) { + CHECK_VAR(x, Bounds(cache.kAsmDouble)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); } // return 1.0; - CHECK_EXPR(BinaryOperation, Bounds(cache.kFloat64)) { - CHECK_VAR(x, Bounds(cache.kFloat64)); - CHECK_EXPR(Literal, Bounds(cache.kFloat64)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) { + CHECK_VAR(x, Bounds(cache.kAsmDouble)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); } } CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { - CHECK_EXPR(Call, Bounds(cache.kFloat64)) { CHECK_VAR(bar, FUNC_D_TYPE); } + CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) { + CHECK_VAR(bar, FUNC_D_TYPE); + } } } CHECK_FUNC_TYPES_END @@ -631,20 +697,259 @@ TEST(Addition2) { "function bar() { var x = 1; var y = 2; return (x+y)|0; }\n" "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); - } - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(y, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); - } - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_VAR(y, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_VAR(y, Bounds(cache.kAsmInt)); } - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +#define TEST_COMPARE_OP(name, op) \ + TEST(name) { \ + CHECK_FUNC_TYPES_BEGIN("function bar() { return (0 " op \ + " 0)|0; }\n" \ + "function foo() { bar(); }") { \ + CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { \ + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { \ + CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) { \ + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \ + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \ + } \ + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \ + } \ + } \ + CHECK_SKIP(); \ + } \ + CHECK_FUNC_TYPES_END \ + } + + +TEST_COMPARE_OP(EqOperator, "==") +TEST_COMPARE_OP(LtOperator, "<") +TEST_COMPARE_OP(LteOperator, "<=") +TEST_COMPARE_OP(GtOperator, ">") +TEST_COMPARE_OP(GteOperator, ">=") + + +TEST(NeqOperator) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { return (0 != 0)|0; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(UnaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(NotOperator) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = 0; return (!x)|0; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(UnaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + } + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(InvertOperator) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = 0; return (~x)|0; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); + } + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(InvertConversion) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = 0.0; return (~~x)|0; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) { + CHECK_VAR(x, Bounds(cache.kAsmDouble)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmDouble)); + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); + } + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); + } + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(Ternary) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = 1; var y = 1; return (x?y:5)|0; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(Conditional, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +#define TEST_INT_BIN_OP(name, op) \ + TEST(name) { \ + CHECK_FUNC_TYPES_BEGIN("function bar() { var x = 0; return (x " op \ + " 123)|0; }\n" \ + "function foo() { bar(); }") { \ + CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { \ + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { \ + CHECK_VAR(x, Bounds(cache.kAsmInt)); \ + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \ + } \ + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { \ + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { \ + CHECK_VAR(x, Bounds(cache.kAsmInt)); \ + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \ + } \ + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); \ + } \ + } \ + CHECK_SKIP(); \ + } \ + CHECK_FUNC_TYPES_END \ + } + + +TEST_INT_BIN_OP(AndOperator, "&") +TEST_INT_BIN_OP(OrOperator, "|") +TEST_INT_BIN_OP(XorOperator, "^") + + +TEST(SignedCompare) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = 1; var y = 1; return ((x|0) < (y|0))|0; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(SignedCompareConst) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = 1; var y = 1; return ((x|0) < (1<<31))|0; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); + } + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } CHECK_SKIP(); @@ -658,26 +963,87 @@ TEST(UnsignedCompare) { "function bar() { var x = 1; var y = 1; return ((x>>>0) < (y>>>0))|0; }\n" "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); - } - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(y, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); - } - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(CompareOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kUint32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(UnsignedCompareConst0) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = 1; var y = 1; return ((x>>>0) < (0>>>0))|0; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } - CHECK_EXPR(BinaryOperation, Bounds(cache.kUint32)) { - CHECK_VAR(y, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(UnsignedCompareConst1) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = 1; var y = 1; return ((x>>>0) < " + "(0xffffffff>>>0))|0; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(CompareOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } + CHECK_EXPR(Literal, Bounds(cache.kAsmUnsigned)); } - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } CHECK_SKIP(); @@ -691,26 +1057,26 @@ TEST(UnsignedDivide) { "function bar() { var x = 1; var y = 1; return ((x>>>0) / (y>>>0))|0; }\n" "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); - } - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(y, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); - } - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(BinaryOperation, Bounds(Type::None(), Type::Any())) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kUint32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(Type::None(zone), Type::Any(zone))) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } - CHECK_EXPR(BinaryOperation, Bounds(cache.kUint32)) { - CHECK_VAR(y, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmUnsigned)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } CHECK_SKIP(); @@ -723,7 +1089,15 @@ TEST(UnsignedFromFloat64) { CHECK_FUNC_ERROR( "function bar() { var x = 1.0; return (x>>>0)|0; }\n" "function foo() { bar(); }", - "asm: line 39: ill typed bitwise operation\n"); + "asm: line 39: left bitwise operand expected to be an integer\n"); +} + + +TEST(AndFloat64) { + CHECK_FUNC_ERROR( + "function bar() { var x = 1.0; return (x&0)|0; }\n" + "function foo() { bar(); }", + "asm: line 39: left bitwise operand expected to be an integer\n"); } @@ -771,7 +1145,31 @@ TEST(TernaryMismatchInt32Float64) { CHECK_FUNC_ERROR( "function bar() { var x = 1; var y = 0.0; return (1 ? x : y)|0; }\n" "function foo() { bar(); }", - "asm: line 39: ill-typed conditional\n"); + "asm: line 39: then and else expressions in ? must have the same type\n"); +} + + +TEST(TernaryMismatchIntish) { + CHECK_FUNC_ERROR( + "function bar() { var x = 1; var y = 0; return (1 ? x + x : y)|0; }\n" + "function foo() { bar(); }", + "asm: line 39: invalid type in ? then expression\n"); +} + + +TEST(TernaryMismatchInt32Float32) { + CHECK_FUNC_ERROR( + "function bar() { var x = 1; var y = 2; return (x?fround(y):x)|0; }\n" + "function foo() { bar(); }", + "asm: line 39: then and else expressions in ? must have the same type\n"); +} + + +TEST(TernaryBadCondition) { + CHECK_FUNC_ERROR( + "function bar() { var x = 1; var y = 2.0; return (y?x:1)|0; }\n" + "function foo() { bar(); }", + "asm: line 39: condition must be of type int\n"); } @@ -780,13 +1178,13 @@ TEST(FroundFloat32) { "function bar() { var x = 1; return fround(x); }\n" "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_F_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } - CHECK_EXPR(Call, Bounds(cache.kFloat32)) { + CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) { CHECK_VAR(fround, FUNC_N2F_TYPE); - CHECK_VAR(x, Bounds(cache.kInt32)); + CHECK_VAR(x, Bounds(cache.kAsmInt)); } } CHECK_SKIP(); @@ -800,26 +1198,26 @@ TEST(Addition4) { "function bar() { var x = 1; var y = 2; return (x+y+x+y)|0; }\n" "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); - } - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(y, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); - } - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_VAR(y, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_VAR(y, Bounds(cache.kAsmInt)); } - CHECK_VAR(x, Bounds(cache.kInt32)); + CHECK_VAR(x, Bounds(cache.kAsmInt)); } - CHECK_VAR(y, Bounds(cache.kInt32)); + CHECK_VAR(y, Bounds(cache.kAsmInt)); } - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } CHECK_SKIP(); @@ -844,19 +1242,35 @@ TEST(Division4) { } +TEST(CompareToStringLeft) { + CHECK_FUNC_ERROR( + "function bar() { var x = 1; return ('hi' > x)|0; }\n" + "function foo() { bar(); }", + "asm: line 39: bad type on left side of comparison\n"); +} + + +TEST(CompareToStringRight) { + CHECK_FUNC_ERROR( + "function bar() { var x = 1; return (x < 'hi')|0; }\n" + "function foo() { bar(); }", + "asm: line 39: bad type on right side of comparison\n"); +} + + TEST(CompareMismatchInt32Float64) { CHECK_FUNC_ERROR( "function bar() { var x = 1; var y = 2.0; return (x < y)|0; }\n" "function foo() { bar(); }", - "asm: line 39: ill-typed comparison operation\n"); + "asm: line 39: left and right side of comparison must match\n"); } TEST(CompareMismatchInt32Uint32) { CHECK_FUNC_ERROR( - "function bar() { var x = 1; var y = 2; return (x < (y>>>0))|0; }\n" + "function bar() { var x = 1; var y = 2; return ((x|0) < (y>>>0))|0; }\n" "function foo() { bar(); }", - "asm: line 39: ill-typed comparison operation\n"); + "asm: line 39: left and right side of comparison must match\n"); } @@ -864,7 +1278,7 @@ TEST(CompareMismatchInt32Float32) { CHECK_FUNC_ERROR( "function bar() { var x = 1; var y = 2; return (x < fround(y))|0; }\n" "function foo() { bar(); }", - "asm: line 39: ill-typed comparison operation\n"); + "asm: line 39: left and right side of comparison must match\n"); } @@ -873,22 +1287,22 @@ TEST(Float64ToInt32) { "function bar() { var x = 1; var y = 0.0; x = ~~y; }\n" "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); - } - CHECK_EXPR(Assignment, Bounds(cache.kFloat64)) { - CHECK_VAR(y, Bounds(cache.kFloat64)); - CHECK_EXPR(Literal, Bounds(cache.kFloat64)); - } - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(y, Bounds(cache.kFloat64)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) { + CHECK_VAR(y, Bounds(cache.kAsmDouble)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(y, Bounds(cache.kAsmDouble)); + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); } - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); } } } @@ -903,21 +1317,116 @@ TEST(Load1) { "function bar() { var x = 1; var y = i8[x>>0]|0; }\n" "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); - } - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(y, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(Property, Bounds(cache.kInt8)) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(Property, Bounds(cache.kAsmInt)) { CHECK_VAR(i8, Bounds(cache.kInt8Array)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmSigned)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(LoadDouble) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = 1; var y = 0.0; y = +f64[x>>3]; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) { + CHECK_VAR(y, Bounds(cache.kAsmDouble)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) { + CHECK_VAR(y, Bounds(cache.kAsmDouble)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmDouble)) { + CHECK_EXPR(Property, Bounds(cache.kAsmDouble)) { + CHECK_VAR(f64, Bounds(cache.kFloat64Array)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmSigned)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); + } + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(Store1) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = 1; i8[x>>0] = 0; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_EXPR(Property, Bounds::Unbounded()) { + CHECK_VAR(i8, Bounds(cache.kInt8Array)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmSigned)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(StoreFloat) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = fround(1.0); " + "f32[0] = fround(x + fround(1.0)); }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) { + CHECK_VAR(x, Bounds(cache.kAsmFloat)); + CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) { + CHECK_VAR(fround, FUNC_N2F_TYPE); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); + } + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) { + CHECK_EXPR(Property, Bounds::Unbounded()) { + CHECK_VAR(f32, Bounds(cache.kFloat32Array)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) { + CHECK_VAR(fround, FUNC_N2F_TYPE); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmFloat)) { + CHECK_VAR(x, Bounds(cache.kAsmFloat)); + CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) { + CHECK_VAR(fround, FUNC_N2F_TYPE); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); } } - CHECK_EXPR(Literal, Bounds(cache.kInt32)); } } } @@ -932,18 +1441,18 @@ TEST(Load1Constant) { "function bar() { var x = 1; var y = i8[5]|0; }\n" "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); - } - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(y, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(Property, Bounds(cache.kInt8)) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(Property, Bounds(cache.kAsmInt)) { CHECK_VAR(i8, Bounds(cache.kInt8Array)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } } @@ -962,64 +1471,64 @@ TEST(FunctionTables) { " return table1[x & 1](y)|0; }\n" "function foo() { bar(1, 2); }") { CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } CHECK_EXPR(FunctionLiteral, FUNC_II2I_TYPE) { - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } - CHECK_EXPR(Assignment, Bounds(cache.kInt32)) { - CHECK_VAR(y, Bounds(cache.kInt32)); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(y, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(y, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_EXPR(Call, Bounds(cache.kInt32)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) { CHECK_EXPR(Property, FUNC_I2I_TYPE) { CHECK_VAR(table1, FUNC_I2I_ARRAY_TYPE); - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { - CHECK_VAR(x, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmSigned)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } - CHECK_VAR(y, Bounds(cache.kInt32)); + CHECK_VAR(y, Bounds(cache.kAsmInt)); } - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } CHECK_SKIP(); @@ -1075,7 +1584,7 @@ TEST(InvalidArgumentCount) { CHECK_FUNC_ERROR( "function bar(x) { return fround(4, 5); }\n" "function foo() { bar(); }", - "asm: line 39: invalid argument count calling fround\n"); + "asm: line 39: invalid argument count calling function\n"); } @@ -1127,29 +1636,112 @@ TEST(UnboundVariable) { } +TEST(EqStrict) { + CHECK_FUNC_ERROR( + "function bar() { return (0 === 0)|0; }\n" + "function foo() { bar(); }", + "asm: line 39: illegal comparison operator\n"); +} + + +TEST(NeStrict) { + CHECK_FUNC_ERROR( + "function bar() { return (0 !== 0)|0; }\n" + "function foo() { bar(); }", + "asm: line 39: illegal comparison operator\n"); +} + + +TEST(InstanceOf) { + CHECK_FUNC_ERROR( + "function bar() { return (0 instanceof 0)|0; }\n" + "function foo() { bar(); }", + "asm: line 39: illegal comparison operator\n"); +} + + +TEST(InOperator) { + CHECK_FUNC_ERROR( + "function bar() { return (0 in 0)|0; }\n" + "function foo() { bar(); }", + "asm: line 39: illegal comparison operator\n"); +} + + +TEST(LogicalAndOperator) { + CHECK_FUNC_ERROR( + "function bar() { return (0 && 0)|0; }\n" + "function foo() { bar(); }", + "asm: line 39: illegal logical operator\n"); +} + + +TEST(LogicalOrOperator) { + CHECK_FUNC_ERROR( + "function bar() { return (0 || 0)|0; }\n" + "function foo() { bar(); }", + "asm: line 39: illegal logical operator\n"); +} + + +TEST(BadLiteral) { + CHECK_FUNC_ERROR( + "function bar() { return true | 0; }\n" + "function foo() { bar(); }", + "asm: line 39: illegal literal\n"); +} + + +TEST(MismatchedReturnTypeLiteral) { + CHECK_FUNC_ERROR( + "function bar() { if(1) { return 1; } return 1.0; }\n" + "function foo() { bar(); }", + "asm: line 39: return type does not match function signature\n"); +} + + +TEST(MismatchedReturnTypeExpression) { + CHECK_FUNC_ERROR( + "function bar() {\n" + " var x = 1; var y = 1.0; if(1) { return x; } return +y; }\n" + "function foo() { bar(); }", + "asm: line 40: return type does not match function signature\n"); +} + + +TEST(AssignToFloatishToF64) { + CHECK_FUNC_ERROR( + "function bar() { var v = fround(1.0); f32[0] = v + fround(1.0); }\n" + "function foo() { bar(); }", + "asm: line 39: intish or floatish assignment\n"); +} + + TEST(ForeignFunction) { CHECK_FUNC_TYPES_BEGIN( "var baz = foreign.baz;\n" "function bar() { return baz(1, 2)|0; }\n" "function foo() { bar(); }") { CHECK_EXPR(FunctionLiteral, FUNC_I_TYPE) { - CHECK_EXPR(BinaryOperation, Bounds(cache.kInt32)) { + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { CHECK_EXPR(Call, Bounds(Type::Number(zone))) { - CHECK_VAR(baz, Bounds(Type::Any())); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_VAR(baz, Bounds(Type::Any(zone))); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } - CHECK_EXPR(Literal, Bounds(cache.kInt32)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); } } CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { - CHECK_EXPR(Call, Bounds(cache.kInt32)) { CHECK_VAR(bar, FUNC_I_TYPE); } + CHECK_EXPR(Call, Bounds(cache.kAsmSigned)) { + CHECK_VAR(bar, FUNC_I_TYPE); + } } } CHECK_FUNC_TYPES_END_1() - CHECK_EXPR(Assignment, Bounds(Type::Any())) { - CHECK_VAR(baz, Bounds(Type::Any())); - CHECK_EXPR(Property, Bounds(Type::Any())) { + CHECK_EXPR(Assignment, Bounds(Type::Any(zone))) { + CHECK_VAR(baz, Bounds(Type::Any(zone))); + CHECK_EXPR(Property, Bounds(Type::Any(zone))) { CHECK_VAR(foreign, Bounds::Unbounded()); CHECK_EXPR(Literal, Bounds::Unbounded()); } @@ -1171,3 +1763,288 @@ TEST(BadExports) { CHECK_EQ("asm: line 40: non-function in function table\n", Validate(zone, test_function, &types)); } + + +TEST(NestedHeapAssignment) { + CHECK_FUNC_ERROR( + "function bar() { var x = 0; i8[x = 1] = 2; }\n" + "function foo() { bar(); }", + "asm: line 39: expected >> in heap access\n"); +} + + +TEST(BadArrayAssignment) { + CHECK_FUNC_ERROR( + "function bar() { i8[0] = 0.0; }\n" + "function foo() { bar(); }", + "asm: line 39: illegal type in assignment\n"); +} + + +TEST(BadStandardFunctionCallOutside) { + CHECK_FUNC_ERROR( + "var s0 = sin(0);\n" + "function bar() { }\n" + "function foo() { bar(); }", + "asm: line 39: calls forbidden outside function bodies\n"); +} + + +TEST(BadFunctionCallOutside) { + CHECK_FUNC_ERROR( + "function bar() { return 0.0; }\n" + "var s0 = bar(0);\n" + "function foo() { bar(); }", + "asm: line 40: calls forbidden outside function bodies\n"); +} + + +TEST(NestedVariableAssignment) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = 0; x = x = 4; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(NestedAssignmentInHeap) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = 0; i8[(x = 1) >> 0] = 2; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_EXPR(Property, Bounds::Unbounded()) { + CHECK_VAR(i8, Bounds(cache.kInt8Array)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(NegativeDouble) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = -123.2; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) { + CHECK_VAR(x, Bounds(cache.kAsmDouble)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(NegativeInteger) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = -123; }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(AbsFunction) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = -123.0; x = abs(x); }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) { + CHECK_VAR(x, Bounds(cache.kAsmDouble)); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmDouble)) { + CHECK_VAR(x, Bounds(cache.kAsmDouble)); + CHECK_EXPR(Call, Bounds(cache.kAsmDouble)) { + CHECK_VAR(abs, FUNC_N2N_TYPE); + CHECK_VAR(x, Bounds(cache.kAsmDouble)); + } + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(CeilFloat) { + CHECK_FUNC_TYPES_BEGIN( + "function bar() { var x = fround(3.1); x = ceil(x); }\n" + "function foo() { bar(); }") { + CHECK_EXPR(FunctionLiteral, FUNC_V_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) { + CHECK_VAR(x, Bounds(cache.kAsmFloat)); + CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) { + CHECK_VAR(fround, FUNC_N2F_TYPE); + CHECK_EXPR(Literal, Bounds(cache.kAsmDouble)); + } + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmFloat)) { + CHECK_VAR(x, Bounds(cache.kAsmFloat)); + CHECK_EXPR(Call, Bounds(cache.kAsmFloat)) { + CHECK_VAR(ceil, FUNC_N2N_TYPE); + CHECK_VAR(x, Bounds(cache.kAsmFloat)); + } + } + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(TypeConsistency) { + v8::V8::Initialize(); + TypeCache cache; + // Check the consistency of each of the main Asm.js types. + CHECK(cache.kAsmFixnum->Is(cache.kAsmFixnum)); + CHECK(cache.kAsmFixnum->Is(cache.kAsmSigned)); + CHECK(cache.kAsmFixnum->Is(cache.kAsmUnsigned)); + CHECK(cache.kAsmFixnum->Is(cache.kAsmInt)); + CHECK(!cache.kAsmFixnum->Is(cache.kAsmFloat)); + CHECK(!cache.kAsmFixnum->Is(cache.kAsmDouble)); + + CHECK(cache.kAsmSigned->Is(cache.kAsmSigned)); + CHECK(cache.kAsmSigned->Is(cache.kAsmInt)); + CHECK(!cache.kAsmSigned->Is(cache.kAsmFixnum)); + CHECK(!cache.kAsmSigned->Is(cache.kAsmUnsigned)); + CHECK(!cache.kAsmSigned->Is(cache.kAsmFloat)); + CHECK(!cache.kAsmSigned->Is(cache.kAsmDouble)); + + CHECK(cache.kAsmUnsigned->Is(cache.kAsmUnsigned)); + CHECK(cache.kAsmUnsigned->Is(cache.kAsmInt)); + CHECK(!cache.kAsmUnsigned->Is(cache.kAsmSigned)); + CHECK(!cache.kAsmUnsigned->Is(cache.kAsmFixnum)); + CHECK(!cache.kAsmUnsigned->Is(cache.kAsmFloat)); + CHECK(!cache.kAsmUnsigned->Is(cache.kAsmDouble)); + + CHECK(cache.kAsmInt->Is(cache.kAsmInt)); + CHECK(!cache.kAsmInt->Is(cache.kAsmUnsigned)); + CHECK(!cache.kAsmInt->Is(cache.kAsmSigned)); + CHECK(!cache.kAsmInt->Is(cache.kAsmFixnum)); + CHECK(!cache.kAsmInt->Is(cache.kAsmFloat)); + CHECK(!cache.kAsmInt->Is(cache.kAsmDouble)); + + CHECK(cache.kAsmFloat->Is(cache.kAsmFloat)); + CHECK(!cache.kAsmFloat->Is(cache.kAsmInt)); + CHECK(!cache.kAsmFloat->Is(cache.kAsmUnsigned)); + CHECK(!cache.kAsmFloat->Is(cache.kAsmSigned)); + CHECK(!cache.kAsmFloat->Is(cache.kAsmFixnum)); + CHECK(!cache.kAsmFloat->Is(cache.kAsmDouble)); + + CHECK(cache.kAsmDouble->Is(cache.kAsmDouble)); + CHECK(!cache.kAsmDouble->Is(cache.kAsmInt)); + CHECK(!cache.kAsmDouble->Is(cache.kAsmUnsigned)); + CHECK(!cache.kAsmDouble->Is(cache.kAsmSigned)); + CHECK(!cache.kAsmDouble->Is(cache.kAsmFixnum)); + CHECK(!cache.kAsmDouble->Is(cache.kAsmFloat)); +} + + +TEST(SwitchTest) { + CHECK_FUNC_TYPES_BEGIN( + "function switcher(x) {\n" + " x = x|0;\n" + " switch (x|0) {\n" + " case 1: return 23;\n" + " case 2: return 43;\n" + " default: return 66;\n" + " }\n" + " return 0;\n" + "}\n" + "function foo() { switcher(1); }") { + CHECK_EXPR(FunctionLiteral, FUNC_I2I_TYPE) { + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_EXPR(Assignment, Bounds(cache.kAsmInt)) { + CHECK_VAR(.switch_tag, Bounds(cache.kAsmInt)); + CHECK_EXPR(BinaryOperation, Bounds(cache.kAsmSigned)) { + CHECK_VAR(x, Bounds(cache.kAsmInt)); + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + } + } + CHECK_EXPR(Literal, Bounds(Type::Undefined(zone))); + CHECK_VAR(.switch_tag, Bounds(cache.kAsmSigned)); + // case 1: return 23; + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); + // case 2: return 43; + CHECK_EXPR(Literal, Bounds(cache.kAsmFixnum)); + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); + // default: return 66; + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); + // return 0; + CHECK_EXPR(Literal, Bounds(cache.kAsmSigned)); + } + CHECK_SKIP(); + } + CHECK_FUNC_TYPES_END +} + + +TEST(BadSwitchRange) { + CHECK_FUNC_ERROR( + "function bar() { switch (1) { case -1: case 0x7fffffff: } }\n" + "function foo() { bar(); }", + "asm: line 39: case range too large\n"); +} + + +TEST(DuplicateSwitchCase) { + CHECK_FUNC_ERROR( + "function bar() { switch (1) { case 0: case 0: } }\n" + "function foo() { bar(); }", + "asm: line 39: duplicate case value\n"); +} + + +TEST(BadSwitchOrder) { + CHECK_FUNC_ERROR( + "function bar() { switch (1) { default: case 0: } }\n" + "function foo() { bar(); }", + "asm: line 39: default case out of order\n"); +} diff --git a/deps/v8/test/cctest/test-assembler-arm.cc b/deps/v8/test/cctest/test-assembler-arm.cc index 3c91d3a7fa..563b050c48 100644 --- a/deps/v8/test/cctest/test-assembler-arm.cc +++ b/deps/v8/test/cctest/test-assembler-arm.cc @@ -69,7 +69,8 @@ TEST(0) { code->Print(os); #endif F2 f = FUNCTION_CAST<F2>(code->entry()); - int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 3, 4, 0, 0, 0)); + int res = + reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, 3, 4, 0, 0, 0)); ::printf("f() = %d\n", res); CHECK_EQ(7, res); } @@ -105,7 +106,8 @@ TEST(1) { code->Print(os); #endif F1 f = FUNCTION_CAST<F1>(code->entry()); - int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 100, 0, 0, 0, 0)); + int res = + reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, 100, 0, 0, 0, 0)); ::printf("f() = %d\n", res); CHECK_EQ(5050, res); } @@ -150,7 +152,8 @@ TEST(2) { code->Print(os); #endif F1 f = FUNCTION_CAST<F1>(code->entry()); - int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 10, 0, 0, 0, 0)); + int res = + reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, 10, 0, 0, 0, 0)); ::printf("f() = %d\n", res); CHECK_EQ(3628800, res); } @@ -200,7 +203,8 @@ TEST(3) { t.i = 100000; t.c = 10; t.s = 1000; - int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0)); + int res = + reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0)); ::printf("f() = %d\n", res); CHECK_EQ(101010, res); CHECK_EQ(100000/2, t.i); @@ -335,7 +339,7 @@ TEST(4) { t.n = 123.456; t.x = 4.5; t.y = 9.0; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(-123.456, t.n); CHECK_EQ(2718.2818, t.m); @@ -383,7 +387,7 @@ TEST(5) { #endif F1 f = FUNCTION_CAST<F1>(code->entry()); int res = reinterpret_cast<int>( - CALL_GENERATED_CODE(f, 0xAAAAAAAA, 0, 0, 0, 0)); + CALL_GENERATED_CODE(isolate, f, 0xAAAAAAAA, 0, 0, 0, 0)); ::printf("f() = %d\n", res); CHECK_EQ(-7, res); } @@ -417,7 +421,7 @@ TEST(6) { #endif F1 f = FUNCTION_CAST<F1>(code->entry()); int res = reinterpret_cast<int>( - CALL_GENERATED_CODE(f, 0xFFFF, 0, 0, 0, 0)); + CALL_GENERATED_CODE(isolate, f, 0xFFFF, 0, 0, 0, 0)); ::printf("f() = %d\n", res); CHECK_EQ(382, res); } @@ -490,8 +494,8 @@ static void TestRoundingMode(VCVTTypes types, code->Print(os); #endif F1 f = FUNCTION_CAST<F1>(code->entry()); - int res = reinterpret_cast<int>( - CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + int res = + reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); ::printf("res = %d\n", res); CHECK_EQ(expected, res); } @@ -692,7 +696,7 @@ TEST(8) { f.g = 7.0; f.h = 8.0; - Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, fn, &d, &f, 0, 0, 0); USE(dummy); CHECK_EQ(7.7, d.a); @@ -802,7 +806,7 @@ TEST(9) { f.g = 7.0; f.h = 8.0; - Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, fn, &d, &f, 0, 0, 0); USE(dummy); CHECK_EQ(7.7, d.a); @@ -908,7 +912,7 @@ TEST(10) { f.g = 7.0; f.h = 8.0; - Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, fn, &d, &f, 0, 0, 0); USE(dummy); CHECK_EQ(7.7, d.a); @@ -985,7 +989,7 @@ TEST(11) { code->Print(os); #endif F3 f = FUNCTION_CAST<F3>(code->entry()); - Object* dummy = CALL_GENERATED_CODE(f, &i, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &i, 0, 0, 0, 0); USE(dummy); CHECK_EQ(static_cast<int32_t>(0xabcd0001), i.a); @@ -1119,7 +1123,7 @@ TEST(13) { t.x = 1.5; t.y = 2.75; t.z = 17.17; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(14.7610017472335499, t.a); CHECK_EQ(3.84200491244266251, t.b); @@ -1192,14 +1196,14 @@ TEST(14) { t.sub_result = 0; t.mul_result = 0; t.div_result = 0; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); const uint32_t kArmNanUpper32 = 0x7ff80000; const uint32_t kArmNanLower32 = 0x00000000; #ifdef DEBUG const uint64_t kArmNanInt64 = (static_cast<uint64_t>(kArmNanUpper32) << 32) | kArmNanLower32; - DCHECK(kArmNanInt64 != kHoleNanInt64); + CHECK(kArmNanInt64 != kHoleNanInt64); #endif // With VFP2 the sign of the canonicalized Nan is undefined. So // we remove the sign bit for the upper tests. @@ -1320,7 +1324,7 @@ TEST(15) { t.dstA5 = 0; t.dstA6 = 0; t.dstA7 = 0; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(0x01020304u, t.dst0); CHECK_EQ(0x11121314u, t.dst1); @@ -1405,7 +1409,7 @@ TEST(16) { t.dst2 = 0; t.dst3 = 0; t.dst4 = 0; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(0x12130304u, t.dst0); CHECK_EQ(0x01021213u, t.dst1); @@ -1435,12 +1439,12 @@ TEST(17) { } -#define TEST_SDIV(expected_, dividend_, divisor_) \ - t.dividend = dividend_; \ - t.divisor = divisor_; \ - t.result = 0; \ - dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); \ - CHECK_EQ(expected_, t.result); +#define TEST_SDIV(expected_, dividend_, divisor_) \ + t.dividend = dividend_; \ + t.divisor = divisor_; \ + t.result = 0; \ + dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); \ + CHECK_EQ(expected_, t.result); TEST(sdiv) { @@ -1499,11 +1503,11 @@ TEST(sdiv) { #undef TEST_SDIV -#define TEST_UDIV(expected_, dividend_, divisor_) \ - t.dividend = dividend_; \ - t.divisor = divisor_; \ - t.result = 0; \ - dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); \ +#define TEST_UDIV(expected_, dividend_, divisor_) \ + t.dividend = dividend_; \ + t.divisor = divisor_; \ + t.result = 0; \ + dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); \ CHECK_EQ(expected_, t.result); @@ -1574,7 +1578,7 @@ TEST(smmla) { F3 f = FUNCTION_CAST<F3>(code->entry()); for (size_t i = 0; i < 128; ++i) { int32_t r, x = rng->NextInt(), y = rng->NextInt(), z = rng->NextInt(); - Object* dummy = CALL_GENERATED_CODE(f, &r, x, y, z, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &r, x, y, z, 0); CHECK_EQ(bits::SignedMulHighAndAdd32(x, y, z), r); USE(dummy); } @@ -1600,7 +1604,7 @@ TEST(smmul) { F3 f = FUNCTION_CAST<F3>(code->entry()); for (size_t i = 0; i < 128; ++i) { int32_t r, x = rng->NextInt(), y = rng->NextInt(); - Object* dummy = CALL_GENERATED_CODE(f, &r, x, y, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &r, x, y, 0, 0); CHECK_EQ(bits::SignedMulHigh32(x, y), r); USE(dummy); } @@ -1626,7 +1630,7 @@ TEST(sxtb) { F3 f = FUNCTION_CAST<F3>(code->entry()); for (size_t i = 0; i < 128; ++i) { int32_t r, x = rng->NextInt(); - Object* dummy = CALL_GENERATED_CODE(f, &r, x, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &r, x, 0, 0, 0); CHECK_EQ(static_cast<int32_t>(static_cast<int8_t>(x)), r); USE(dummy); } @@ -1652,7 +1656,7 @@ TEST(sxtab) { F3 f = FUNCTION_CAST<F3>(code->entry()); for (size_t i = 0; i < 128; ++i) { int32_t r, x = rng->NextInt(), y = rng->NextInt(); - Object* dummy = CALL_GENERATED_CODE(f, &r, x, y, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &r, x, y, 0, 0); CHECK_EQ(static_cast<int32_t>(static_cast<int8_t>(x)) + y, r); USE(dummy); } @@ -1678,7 +1682,7 @@ TEST(sxth) { F3 f = FUNCTION_CAST<F3>(code->entry()); for (size_t i = 0; i < 128; ++i) { int32_t r, x = rng->NextInt(); - Object* dummy = CALL_GENERATED_CODE(f, &r, x, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &r, x, 0, 0, 0); CHECK_EQ(static_cast<int32_t>(static_cast<int16_t>(x)), r); USE(dummy); } @@ -1704,7 +1708,7 @@ TEST(sxtah) { F3 f = FUNCTION_CAST<F3>(code->entry()); for (size_t i = 0; i < 128; ++i) { int32_t r, x = rng->NextInt(), y = rng->NextInt(); - Object* dummy = CALL_GENERATED_CODE(f, &r, x, y, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &r, x, y, 0, 0); CHECK_EQ(static_cast<int32_t>(static_cast<int16_t>(x)) + y, r); USE(dummy); } @@ -1730,7 +1734,7 @@ TEST(uxtb) { F3 f = FUNCTION_CAST<F3>(code->entry()); for (size_t i = 0; i < 128; ++i) { int32_t r, x = rng->NextInt(); - Object* dummy = CALL_GENERATED_CODE(f, &r, x, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &r, x, 0, 0, 0); CHECK_EQ(static_cast<int32_t>(static_cast<uint8_t>(x)), r); USE(dummy); } @@ -1756,7 +1760,7 @@ TEST(uxtab) { F3 f = FUNCTION_CAST<F3>(code->entry()); for (size_t i = 0; i < 128; ++i) { int32_t r, x = rng->NextInt(), y = rng->NextInt(); - Object* dummy = CALL_GENERATED_CODE(f, &r, x, y, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &r, x, y, 0, 0); CHECK_EQ(static_cast<int32_t>(static_cast<uint8_t>(x)) + y, r); USE(dummy); } @@ -1782,7 +1786,7 @@ TEST(uxth) { F3 f = FUNCTION_CAST<F3>(code->entry()); for (size_t i = 0; i < 128; ++i) { int32_t r, x = rng->NextInt(); - Object* dummy = CALL_GENERATED_CODE(f, &r, x, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &r, x, 0, 0, 0); CHECK_EQ(static_cast<int32_t>(static_cast<uint16_t>(x)), r); USE(dummy); } @@ -1808,7 +1812,7 @@ TEST(uxtah) { F3 f = FUNCTION_CAST<F3>(code->entry()); for (size_t i = 0; i < 128; ++i) { int32_t r, x = rng->NextInt(), y = rng->NextInt(); - Object* dummy = CALL_GENERATED_CODE(f, &r, x, y, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &r, x, y, 0, 0); CHECK_EQ(static_cast<int32_t>(static_cast<uint16_t>(x)) + y, r); USE(dummy); } @@ -1880,12 +1884,118 @@ TEST(code_relative_offset) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), code_object); F1 f = FUNCTION_CAST<F1>(code->entry()); - int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 21, 0, 0, 0, 0)); + int res = + reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, 21, 0, 0, 0, 0)); ::printf("f() = %d\n", res); CHECK_EQ(42, res); } +TEST(ARMv8_float32_vrintX) { + // Test the vrintX floating point instructions. + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + + typedef struct { + float input; + float ar; + float nr; + float mr; + float pr; + float zr; + } T; + T t; + + // Create a function that accepts &t, and loads, manipulates, and stores + // the floats. + Assembler assm(isolate, NULL, 0); + Label L, C; + + + if (CpuFeatures::IsSupported(ARMv8)) { + CpuFeatureScope scope(&assm, ARMv8); + + __ mov(ip, Operand(sp)); + __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); + + __ mov(r4, Operand(r0)); + + // Test vrinta + __ vldr(s6, r4, offsetof(T, input)); + __ vrinta(s5, s6); + __ vstr(s5, r4, offsetof(T, ar)); + + // Test vrintn + __ vldr(s6, r4, offsetof(T, input)); + __ vrintn(s5, s6); + __ vstr(s5, r4, offsetof(T, nr)); + + // Test vrintp + __ vldr(s6, r4, offsetof(T, input)); + __ vrintp(s5, s6); + __ vstr(s5, r4, offsetof(T, pr)); + + // Test vrintm + __ vldr(s6, r4, offsetof(T, input)); + __ vrintm(s5, s6); + __ vstr(s5, r4, offsetof(T, mr)); + + // Test vrintz + __ vldr(s6, r4, offsetof(T, input)); + __ vrintz(s5, s6); + __ vstr(s5, r4, offsetof(T, zr)); + + __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit()); + + CodeDesc desc; + assm.GetCode(&desc); + Handle<Code> code = isolate->factory()->NewCode( + desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); +#ifdef DEBUG + OFStream os(stdout); + code->Print(os); +#endif + F3 f = FUNCTION_CAST<F3>(code->entry()); + + Object* dummy = nullptr; + USE(dummy); + +#define CHECK_VRINT(input_val, ares, nres, mres, pres, zres) \ + t.input = input_val; \ + dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); \ + CHECK_EQ(ares, t.ar); \ + CHECK_EQ(nres, t.nr); \ + CHECK_EQ(mres, t.mr); \ + CHECK_EQ(pres, t.pr); \ + CHECK_EQ(zres, t.zr); + + CHECK_VRINT(-0.5, -1.0, -0.0, -1.0, -0.0, -0.0) + CHECK_VRINT(-0.6, -1.0, -1.0, -1.0, -0.0, -0.0) + CHECK_VRINT(-1.1, -1.0, -1.0, -2.0, -1.0, -1.0) + CHECK_VRINT(0.5, 1.0, 0.0, 0.0, 1.0, 0.0) + CHECK_VRINT(0.6, 1.0, 1.0, 0.0, 1.0, 0.0) + CHECK_VRINT(1.1, 1.0, 1.0, 1.0, 2.0, 1.0) + float inf = std::numeric_limits<float>::infinity(); + CHECK_VRINT(inf, inf, inf, inf, inf, inf) + CHECK_VRINT(-inf, -inf, -inf, -inf, -inf, -inf) + CHECK_VRINT(-0.0, -0.0, -0.0, -0.0, -0.0, -0.0) + + // Check NaN propagation. + float nan = std::numeric_limits<float>::quiet_NaN(); + t.input = nan; + dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); + CHECK_EQ(bit_cast<int32_t>(nan), bit_cast<int32_t>(t.ar)); + CHECK_EQ(bit_cast<int32_t>(nan), bit_cast<int32_t>(t.nr)); + CHECK_EQ(bit_cast<int32_t>(nan), bit_cast<int32_t>(t.mr)); + CHECK_EQ(bit_cast<int32_t>(nan), bit_cast<int32_t>(t.pr)); + CHECK_EQ(bit_cast<int32_t>(nan), bit_cast<int32_t>(t.zr)); + +#undef CHECK_VRINT + } +} + + TEST(ARMv8_vrintX) { // Test the vrintX floating point instructions. CcTest::InitializeVM(); @@ -1958,7 +2068,7 @@ TEST(ARMv8_vrintX) { #define CHECK_VRINT(input_val, ares, nres, mres, pres, zres) \ t.input = input_val; \ - dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); \ + dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); \ CHECK_EQ(ares, t.ar); \ CHECK_EQ(nres, t.nr); \ CHECK_EQ(mres, t.mr); \ @@ -1979,7 +2089,7 @@ TEST(ARMv8_vrintX) { // Check NaN propagation. double nan = std::numeric_limits<double>::quiet_NaN(); t.input = nan; - dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); CHECK_EQ(bit_cast<int64_t>(nan), bit_cast<int64_t>(t.ar)); CHECK_EQ(bit_cast<int64_t>(nan), bit_cast<int64_t>(t.nr)); CHECK_EQ(bit_cast<int64_t>(nan), bit_cast<int64_t>(t.mr)); diff --git a/deps/v8/test/cctest/test-assembler-arm64.cc b/deps/v8/test/cctest/test-assembler-arm64.cc index 7450a4375f..d930173937 100644 --- a/deps/v8/test/cctest/test-assembler-arm64.cc +++ b/deps/v8/test/cctest/test-assembler-arm64.cc @@ -114,16 +114,17 @@ static void InitializeVM() { #ifdef USE_SIMULATOR // Run tests with the simulator. -#define SETUP_SIZE(buf_size) \ - Isolate* isolate = Isolate::Current(); \ - HandleScope scope(isolate); \ - DCHECK(isolate != NULL); \ - byte* buf = new byte[buf_size]; \ - MacroAssembler masm(isolate, buf, buf_size); \ - Decoder<DispatchingDecoderVisitor>* decoder = \ - new Decoder<DispatchingDecoderVisitor>(); \ - Simulator simulator(decoder); \ - PrintDisassembler* pdis = NULL; \ +#define SETUP_SIZE(buf_size) \ + Isolate* isolate = CcTest::i_isolate(); \ + HandleScope scope(isolate); \ + CHECK(isolate != NULL); \ + byte* buf = new byte[buf_size]; \ + MacroAssembler masm(isolate, buf, buf_size, \ + v8::internal::CodeObjectRequired::kYes); \ + Decoder<DispatchingDecoderVisitor>* decoder = \ + new Decoder<DispatchingDecoderVisitor>(); \ + Simulator simulator(decoder); \ + PrintDisassembler* pdis = NULL; \ RegisterDump core; /* if (Cctest::trace_sim()) { \ @@ -168,12 +169,13 @@ static void InitializeVM() { #else // ifdef USE_SIMULATOR. // Run the test on real hardware or models. -#define SETUP_SIZE(buf_size) \ - Isolate* isolate = Isolate::Current(); \ - HandleScope scope(isolate); \ - DCHECK(isolate != NULL); \ - byte* buf = new byte[buf_size]; \ - MacroAssembler masm(isolate, buf, buf_size); \ +#define SETUP_SIZE(buf_size) \ + Isolate* isolate = CcTest::i_isolate(); \ + HandleScope scope(isolate); \ + CHECK(isolate != NULL); \ + byte* buf = new byte[buf_size]; \ + MacroAssembler masm(isolate, buf, buf_size, \ + v8::internal::CodeObjectRequired::kYes); \ RegisterDump core; #define RESET() \ @@ -229,11 +231,10 @@ static void InitializeVM() { CHECK(EqualFP64(expected, &core, result)) #ifdef DEBUG -#define DCHECK_LITERAL_POOL_SIZE(expected) \ +#define CHECK_LITERAL_POOL_SIZE(expected) \ CHECK((expected) == (__ LiteralPoolSize())) #else -#define DCHECK_LITERAL_POOL_SIZE(expected) \ - ((void) 0) +#define CHECK_LITERAL_POOL_SIZE(expected) ((void)0) #endif @@ -3299,7 +3300,7 @@ TEST(ldr_literal) { static void LdrLiteralRangeHelper(ptrdiff_t range_, LiteralPoolEmitOption option, bool expect_dump) { - DCHECK(range_ > 0); + CHECK(range_ > 0); SETUP_SIZE(range_ + 1024); Label label_1, label_2; @@ -3318,19 +3319,19 @@ static void LdrLiteralRangeHelper(ptrdiff_t range_, START(); // Force a pool dump so the pool starts off empty. __ EmitLiteralPool(JumpRequired); - DCHECK_LITERAL_POOL_SIZE(0); + CHECK_LITERAL_POOL_SIZE(0); __ Ldr(x0, 0x1234567890abcdefUL); __ Ldr(w1, 0xfedcba09); __ Ldr(d0, 1.234); __ Ldr(s1, 2.5); - DCHECK_LITERAL_POOL_SIZE(4); + CHECK_LITERAL_POOL_SIZE(4); code_size += 4 * sizeof(Instr); // Check that the requested range (allowing space for a branch over the pool) // can be handled by this test. - DCHECK((code_size + pool_guard_size) <= range); + CHECK((code_size + pool_guard_size) <= range); // Emit NOPs up to 'range', leaving space for the pool guard. while ((code_size + pool_guard_size) < range) { @@ -3344,28 +3345,28 @@ static void LdrLiteralRangeHelper(ptrdiff_t range_, code_size += sizeof(Instr); } - DCHECK(code_size == range); - DCHECK_LITERAL_POOL_SIZE(4); + CHECK(code_size == range); + CHECK_LITERAL_POOL_SIZE(4); // Possibly generate a literal pool. __ CheckLiteralPool(option); __ Bind(&label_1); if (expect_dump) { - DCHECK_LITERAL_POOL_SIZE(0); + CHECK_LITERAL_POOL_SIZE(0); } else { - DCHECK_LITERAL_POOL_SIZE(4); + CHECK_LITERAL_POOL_SIZE(4); } // Force a pool flush to check that a second pool functions correctly. __ EmitLiteralPool(JumpRequired); - DCHECK_LITERAL_POOL_SIZE(0); + CHECK_LITERAL_POOL_SIZE(0); // These loads should be after the pool (and will require a new one). __ Ldr(x4, 0x34567890abcdef12UL); __ Ldr(w5, 0xdcba09fe); __ Ldr(d4, 123.4); __ Ldr(s5, 250.0); - DCHECK_LITERAL_POOL_SIZE(4); + CHECK_LITERAL_POOL_SIZE(4); END(); RUN(); @@ -5443,12 +5444,12 @@ TEST(fmadd_fmsub_double_nans) { double q1 = rawbits_to_double(0x7ffaaaaa11111111); double q2 = rawbits_to_double(0x7ffaaaaa22222222); double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa); - DCHECK(IsSignallingNaN(s1)); - DCHECK(IsSignallingNaN(s2)); - DCHECK(IsSignallingNaN(sa)); - DCHECK(IsQuietNaN(q1)); - DCHECK(IsQuietNaN(q2)); - DCHECK(IsQuietNaN(qa)); + CHECK(IsSignallingNaN(s1)); + CHECK(IsSignallingNaN(s2)); + CHECK(IsSignallingNaN(sa)); + CHECK(IsQuietNaN(q1)); + CHECK(IsQuietNaN(q2)); + CHECK(IsQuietNaN(qa)); // The input NaNs after passing through ProcessNaN. double s1_proc = rawbits_to_double(0x7ffd555511111111); @@ -5457,22 +5458,22 @@ TEST(fmadd_fmsub_double_nans) { double q1_proc = q1; double q2_proc = q2; double qa_proc = qa; - DCHECK(IsQuietNaN(s1_proc)); - DCHECK(IsQuietNaN(s2_proc)); - DCHECK(IsQuietNaN(sa_proc)); - DCHECK(IsQuietNaN(q1_proc)); - DCHECK(IsQuietNaN(q2_proc)); - DCHECK(IsQuietNaN(qa_proc)); + CHECK(IsQuietNaN(s1_proc)); + CHECK(IsQuietNaN(s2_proc)); + CHECK(IsQuietNaN(sa_proc)); + CHECK(IsQuietNaN(q1_proc)); + CHECK(IsQuietNaN(q2_proc)); + CHECK(IsQuietNaN(qa_proc)); // Negated NaNs as it would be done on ARMv8 hardware. double s1_proc_neg = rawbits_to_double(0xfffd555511111111); double sa_proc_neg = rawbits_to_double(0xfffd5555aaaaaaaa); double q1_proc_neg = rawbits_to_double(0xfffaaaaa11111111); double qa_proc_neg = rawbits_to_double(0xfffaaaaaaaaaaaaa); - DCHECK(IsQuietNaN(s1_proc_neg)); - DCHECK(IsQuietNaN(sa_proc_neg)); - DCHECK(IsQuietNaN(q1_proc_neg)); - DCHECK(IsQuietNaN(qa_proc_neg)); + CHECK(IsQuietNaN(s1_proc_neg)); + CHECK(IsQuietNaN(sa_proc_neg)); + CHECK(IsQuietNaN(q1_proc_neg)); + CHECK(IsQuietNaN(qa_proc_neg)); // Quiet NaNs are propagated. FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc); @@ -5526,12 +5527,12 @@ TEST(fmadd_fmsub_float_nans) { float q1 = rawbits_to_float(0x7fea1111); float q2 = rawbits_to_float(0x7fea2222); float qa = rawbits_to_float(0x7feaaaaa); - DCHECK(IsSignallingNaN(s1)); - DCHECK(IsSignallingNaN(s2)); - DCHECK(IsSignallingNaN(sa)); - DCHECK(IsQuietNaN(q1)); - DCHECK(IsQuietNaN(q2)); - DCHECK(IsQuietNaN(qa)); + CHECK(IsSignallingNaN(s1)); + CHECK(IsSignallingNaN(s2)); + CHECK(IsSignallingNaN(sa)); + CHECK(IsQuietNaN(q1)); + CHECK(IsQuietNaN(q2)); + CHECK(IsQuietNaN(qa)); // The input NaNs after passing through ProcessNaN. float s1_proc = rawbits_to_float(0x7fd51111); @@ -5540,22 +5541,22 @@ TEST(fmadd_fmsub_float_nans) { float q1_proc = q1; float q2_proc = q2; float qa_proc = qa; - DCHECK(IsQuietNaN(s1_proc)); - DCHECK(IsQuietNaN(s2_proc)); - DCHECK(IsQuietNaN(sa_proc)); - DCHECK(IsQuietNaN(q1_proc)); - DCHECK(IsQuietNaN(q2_proc)); - DCHECK(IsQuietNaN(qa_proc)); + CHECK(IsQuietNaN(s1_proc)); + CHECK(IsQuietNaN(s2_proc)); + CHECK(IsQuietNaN(sa_proc)); + CHECK(IsQuietNaN(q1_proc)); + CHECK(IsQuietNaN(q2_proc)); + CHECK(IsQuietNaN(qa_proc)); // Negated NaNs as it would be done on ARMv8 hardware. float s1_proc_neg = rawbits_to_float(0xffd51111); float sa_proc_neg = rawbits_to_float(0xffd5aaaa); float q1_proc_neg = rawbits_to_float(0xffea1111); float qa_proc_neg = rawbits_to_float(0xffeaaaaa); - DCHECK(IsQuietNaN(s1_proc_neg)); - DCHECK(IsQuietNaN(sa_proc_neg)); - DCHECK(IsQuietNaN(q1_proc_neg)); - DCHECK(IsQuietNaN(qa_proc_neg)); + CHECK(IsQuietNaN(s1_proc_neg)); + CHECK(IsQuietNaN(sa_proc_neg)); + CHECK(IsQuietNaN(q1_proc_neg)); + CHECK(IsQuietNaN(qa_proc_neg)); // Quiet NaNs are propagated. FmaddFmsubHelper(q1, 0, 0, q1_proc, q1_proc_neg, q1_proc_neg, q1_proc); @@ -5773,10 +5774,10 @@ TEST(fmax_fmin_d) { double snan_processed = rawbits_to_double(0x7ffd555512345678); double qnan_processed = qnan; - DCHECK(IsSignallingNaN(snan)); - DCHECK(IsQuietNaN(qnan)); - DCHECK(IsQuietNaN(snan_processed)); - DCHECK(IsQuietNaN(qnan_processed)); + CHECK(IsSignallingNaN(snan)); + CHECK(IsQuietNaN(qnan)); + CHECK(IsQuietNaN(snan_processed)); + CHECK(IsQuietNaN(qnan_processed)); // Bootstrap tests. FminFmaxDoubleHelper(0, 0, 0, 0, 0, 0); @@ -5858,10 +5859,10 @@ TEST(fmax_fmin_s) { float snan_processed = rawbits_to_float(0x7fd51234); float qnan_processed = qnan; - DCHECK(IsSignallingNaN(snan)); - DCHECK(IsQuietNaN(qnan)); - DCHECK(IsQuietNaN(snan_processed)); - DCHECK(IsQuietNaN(qnan_processed)); + CHECK(IsSignallingNaN(snan)); + CHECK(IsQuietNaN(qnan)); + CHECK(IsQuietNaN(snan_processed)); + CHECK(IsQuietNaN(qnan_processed)); // Bootstrap tests. FminFmaxFloatHelper(0, 0, 0, 0, 0, 0); @@ -6833,8 +6834,8 @@ TEST(fcvt_sd) { float expected = test[i].expected; // We only expect positive input. - DCHECK(std::signbit(in) == 0); - DCHECK(std::signbit(expected) == 0); + CHECK(std::signbit(in) == 0); + CHECK(std::signbit(expected) == 0); SETUP(); START(); @@ -8545,7 +8546,7 @@ TEST(peek_poke_mixed) { __ Poke(x1, 8); __ Poke(x0, 0); { - DCHECK(__ StackPointer().Is(csp)); + CHECK(__ StackPointer().Is(csp)); __ Mov(x4, __ StackPointer()); __ SetStackPointer(x4); @@ -8642,7 +8643,7 @@ static void PushPopJsspSimpleHelper(int reg_count, uint64_t literal_base = 0x0100001000100101UL; { - DCHECK(__ StackPointer().Is(csp)); + CHECK(__ StackPointer().Is(csp)); __ Mov(jssp, __ StackPointer()); __ SetStackPointer(jssp); @@ -8671,7 +8672,9 @@ static void PushPopJsspSimpleHelper(int reg_count, case 3: __ Push(r[2], r[1], r[0]); break; case 2: __ Push(r[1], r[0]); break; case 1: __ Push(r[0]); break; - default: DCHECK(i == 0); break; + default: + CHECK(i == 0); + break; } break; case PushPopRegList: @@ -8693,7 +8696,9 @@ static void PushPopJsspSimpleHelper(int reg_count, case 3: __ Pop(r[i], r[i+1], r[i+2]); break; case 2: __ Pop(r[i], r[i+1]); break; case 1: __ Pop(r[i]); break; - default: DCHECK(i == reg_count); break; + default: + CHECK(i == reg_count); + break; } break; case PushPopRegList: @@ -8824,7 +8829,7 @@ static void PushPopFPJsspSimpleHelper(int reg_count, uint64_t literal_base = 0x0100001000100101UL; { - DCHECK(__ StackPointer().Is(csp)); + CHECK(__ StackPointer().Is(csp)); __ Mov(jssp, __ StackPointer()); __ SetStackPointer(jssp); @@ -8855,7 +8860,9 @@ static void PushPopFPJsspSimpleHelper(int reg_count, case 3: __ Push(v[2], v[1], v[0]); break; case 2: __ Push(v[1], v[0]); break; case 1: __ Push(v[0]); break; - default: DCHECK(i == 0); break; + default: + CHECK(i == 0); + break; } break; case PushPopRegList: @@ -8877,7 +8884,9 @@ static void PushPopFPJsspSimpleHelper(int reg_count, case 3: __ Pop(v[i], v[i+1], v[i+2]); break; case 2: __ Pop(v[i], v[i+1]); break; case 1: __ Pop(v[i]); break; - default: DCHECK(i == reg_count); break; + default: + CHECK(i == reg_count); + break; } break; case PushPopRegList: @@ -9001,7 +9010,7 @@ static void PushPopJsspMixedMethodsHelper(int claim, int reg_size) { START(); { - DCHECK(__ StackPointer().Is(csp)); + CHECK(__ StackPointer().Is(csp)); __ Mov(jssp, __ StackPointer()); __ SetStackPointer(jssp); @@ -9106,7 +9115,7 @@ static void PushPopJsspWXOverlapHelper(int reg_count, int claim) { START(); { - DCHECK(__ StackPointer().Is(csp)); + CHECK(__ StackPointer().Is(csp)); __ Mov(jssp, __ StackPointer()); __ SetStackPointer(jssp); @@ -9154,7 +9163,7 @@ static void PushPopJsspWXOverlapHelper(int reg_count, int claim) { int active_w_slots = 0; for (int i = 0; active_w_slots < requested_w_slots; i++) { - DCHECK(i < reg_count); + CHECK(i < reg_count); // In order to test various arguments to PushMultipleTimes, and to try to // exercise different alignment and overlap effects, we push each // register a different number of times. @@ -9227,7 +9236,7 @@ static void PushPopJsspWXOverlapHelper(int reg_count, int claim) { } next_is_64 = !next_is_64; } - DCHECK(active_w_slots == 0); + CHECK(active_w_slots == 0); // Drop memory to restore jssp. __ Drop(claim, kByteSizeInBytes); @@ -9263,7 +9272,7 @@ static void PushPopJsspWXOverlapHelper(int reg_count, int claim) { CHECK_EQUAL_64(expected, x[i]); } } - DCHECK(slot == requested_w_slots); + CHECK(slot == requested_w_slots); TEARDOWN(); } @@ -9293,7 +9302,7 @@ TEST(push_pop_csp) { START(); - DCHECK(csp.Is(__ StackPointer())); + CHECK(csp.Is(__ StackPointer())); __ Mov(x3, 0x3333333333333333UL); __ Mov(x2, 0x2222222222222222UL); @@ -9382,7 +9391,7 @@ TEST(push_queued) { START(); - DCHECK(__ StackPointer().Is(csp)); + CHECK(__ StackPointer().Is(csp)); __ Mov(jssp, __ StackPointer()); __ SetStackPointer(jssp); @@ -9457,7 +9466,7 @@ TEST(pop_queued) { START(); - DCHECK(__ StackPointer().Is(csp)); + CHECK(__ StackPointer().Is(csp)); __ Mov(jssp, __ StackPointer()); __ SetStackPointer(jssp); @@ -10078,7 +10087,7 @@ TEST(printf) { __ Printf("%%%%%s%%%c%%\n", x2, w13); // Print the stack pointer (csp). - DCHECK(csp.Is(__ StackPointer())); + CHECK(csp.Is(__ StackPointer())); __ Printf("StackPointer(csp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n", __ StackPointer(), __ StackPointer().W()); @@ -10236,75 +10245,6 @@ TEST(printf_no_preserve) { } -// This is a V8-specific test. -static void CopyFieldsHelper(CPURegList temps) { - static const uint64_t kLiteralBase = 0x0100001000100101UL; - static const uint64_t src[] = {kLiteralBase * 1, - kLiteralBase * 2, - kLiteralBase * 3, - kLiteralBase * 4, - kLiteralBase * 5, - kLiteralBase * 6, - kLiteralBase * 7, - kLiteralBase * 8, - kLiteralBase * 9, - kLiteralBase * 10, - kLiteralBase * 11}; - static const uint64_t src_tagged = - reinterpret_cast<uint64_t>(src) + kHeapObjectTag; - - static const unsigned kTestCount = sizeof(src) / sizeof(src[0]) + 1; - uint64_t* dst[kTestCount]; - uint64_t dst_tagged[kTestCount]; - - // The first test will be to copy 0 fields. The destination (and source) - // should not be accessed in any way. - dst[0] = NULL; - dst_tagged[0] = kHeapObjectTag; - - // Allocate memory for each other test. Each test <n> will have <n> fields. - // This is intended to exercise as many paths in CopyFields as possible. - for (unsigned i = 1; i < kTestCount; i++) { - dst[i] = new uint64_t[i]; - memset(dst[i], 0, i * sizeof(kLiteralBase)); - dst_tagged[i] = reinterpret_cast<uint64_t>(dst[i]) + kHeapObjectTag; - } - - SETUP(); - START(); - - __ Mov(x0, dst_tagged[0]); - __ Mov(x1, 0); - __ CopyFields(x0, x1, temps, 0); - for (unsigned i = 1; i < kTestCount; i++) { - __ Mov(x0, dst_tagged[i]); - __ Mov(x1, src_tagged); - __ CopyFields(x0, x1, temps, i); - } - - END(); - RUN(); - TEARDOWN(); - - for (unsigned i = 1; i < kTestCount; i++) { - for (unsigned j = 0; j < i; j++) { - CHECK(src[j] == dst[i][j]); - } - delete [] dst[i]; - } -} - - -// This is a V8-specific test. -TEST(copyfields) { - INIT_V8(); - CopyFieldsHelper(CPURegList(x10)); - CopyFieldsHelper(CPURegList(x10, x11)); - CopyFieldsHelper(CPURegList(x10, x11, x12)); - CopyFieldsHelper(CPURegList(x10, x11, x12, x13)); -} - - TEST(blr_lr) { // A simple test to check that the simulator correcty handle "blr lr". INIT_V8(); @@ -10400,14 +10340,14 @@ TEST(process_nan_double) { // Make sure that NaN propagation works correctly. double sn = rawbits_to_double(0x7ff5555511111111); double qn = rawbits_to_double(0x7ffaaaaa11111111); - DCHECK(IsSignallingNaN(sn)); - DCHECK(IsQuietNaN(qn)); + CHECK(IsSignallingNaN(sn)); + CHECK(IsQuietNaN(qn)); // The input NaNs after passing through ProcessNaN. double sn_proc = rawbits_to_double(0x7ffd555511111111); double qn_proc = qn; - DCHECK(IsQuietNaN(sn_proc)); - DCHECK(IsQuietNaN(qn_proc)); + CHECK(IsQuietNaN(sn_proc)); + CHECK(IsQuietNaN(qn_proc)); SETUP(); START(); @@ -10476,14 +10416,14 @@ TEST(process_nan_float) { // Make sure that NaN propagation works correctly. float sn = rawbits_to_float(0x7f951111); float qn = rawbits_to_float(0x7fea1111); - DCHECK(IsSignallingNaN(sn)); - DCHECK(IsQuietNaN(qn)); + CHECK(IsSignallingNaN(sn)); + CHECK(IsQuietNaN(qn)); // The input NaNs after passing through ProcessNaN. float sn_proc = rawbits_to_float(0x7fd51111); float qn_proc = qn; - DCHECK(IsQuietNaN(sn_proc)); - DCHECK(IsQuietNaN(qn_proc)); + CHECK(IsQuietNaN(sn_proc)); + CHECK(IsQuietNaN(qn_proc)); SETUP(); START(); @@ -10548,8 +10488,8 @@ TEST(process_nan_float) { static void ProcessNaNsHelper(double n, double m, double expected) { - DCHECK(std::isnan(n) || std::isnan(m)); - DCHECK(std::isnan(expected)); + CHECK(std::isnan(n) || std::isnan(m)); + CHECK(std::isnan(expected)); SETUP(); START(); @@ -10587,20 +10527,20 @@ TEST(process_nans_double) { double sm = rawbits_to_double(0x7ff5555522222222); double qn = rawbits_to_double(0x7ffaaaaa11111111); double qm = rawbits_to_double(0x7ffaaaaa22222222); - DCHECK(IsSignallingNaN(sn)); - DCHECK(IsSignallingNaN(sm)); - DCHECK(IsQuietNaN(qn)); - DCHECK(IsQuietNaN(qm)); + CHECK(IsSignallingNaN(sn)); + CHECK(IsSignallingNaN(sm)); + CHECK(IsQuietNaN(qn)); + CHECK(IsQuietNaN(qm)); // The input NaNs after passing through ProcessNaN. double sn_proc = rawbits_to_double(0x7ffd555511111111); double sm_proc = rawbits_to_double(0x7ffd555522222222); double qn_proc = qn; double qm_proc = qm; - DCHECK(IsQuietNaN(sn_proc)); - DCHECK(IsQuietNaN(sm_proc)); - DCHECK(IsQuietNaN(qn_proc)); - DCHECK(IsQuietNaN(qm_proc)); + CHECK(IsQuietNaN(sn_proc)); + CHECK(IsQuietNaN(sm_proc)); + CHECK(IsQuietNaN(qn_proc)); + CHECK(IsQuietNaN(qm_proc)); // Quiet NaNs are propagated. ProcessNaNsHelper(qn, 0, qn_proc); @@ -10620,8 +10560,8 @@ TEST(process_nans_double) { static void ProcessNaNsHelper(float n, float m, float expected) { - DCHECK(std::isnan(n) || std::isnan(m)); - DCHECK(std::isnan(expected)); + CHECK(std::isnan(n) || std::isnan(m)); + CHECK(std::isnan(expected)); SETUP(); START(); @@ -10659,20 +10599,20 @@ TEST(process_nans_float) { float sm = rawbits_to_float(0x7f952222); float qn = rawbits_to_float(0x7fea1111); float qm = rawbits_to_float(0x7fea2222); - DCHECK(IsSignallingNaN(sn)); - DCHECK(IsSignallingNaN(sm)); - DCHECK(IsQuietNaN(qn)); - DCHECK(IsQuietNaN(qm)); + CHECK(IsSignallingNaN(sn)); + CHECK(IsSignallingNaN(sm)); + CHECK(IsQuietNaN(qn)); + CHECK(IsQuietNaN(qm)); // The input NaNs after passing through ProcessNaN. float sn_proc = rawbits_to_float(0x7fd51111); float sm_proc = rawbits_to_float(0x7fd52222); float qn_proc = qn; float qm_proc = qm; - DCHECK(IsQuietNaN(sn_proc)); - DCHECK(IsQuietNaN(sm_proc)); - DCHECK(IsQuietNaN(qn_proc)); - DCHECK(IsQuietNaN(qm_proc)); + CHECK(IsQuietNaN(sn_proc)); + CHECK(IsQuietNaN(sm_proc)); + CHECK(IsQuietNaN(qn_proc)); + CHECK(IsQuietNaN(qm_proc)); // Quiet NaNs are propagated. ProcessNaNsHelper(qn, 0, qn_proc); @@ -10692,7 +10632,7 @@ TEST(process_nans_float) { static void DefaultNaNHelper(float n, float m, float a) { - DCHECK(std::isnan(n) || std::isnan(m) || std::isnan(a)); + CHECK(std::isnan(n) || std::isnan(m) || std::isnan(a)); bool test_1op = std::isnan(n); bool test_2op = std::isnan(n) || std::isnan(m); @@ -10785,12 +10725,12 @@ TEST(default_nan_float) { float qn = rawbits_to_float(0x7fea1111); float qm = rawbits_to_float(0x7fea2222); float qa = rawbits_to_float(0x7feaaaaa); - DCHECK(IsSignallingNaN(sn)); - DCHECK(IsSignallingNaN(sm)); - DCHECK(IsSignallingNaN(sa)); - DCHECK(IsQuietNaN(qn)); - DCHECK(IsQuietNaN(qm)); - DCHECK(IsQuietNaN(qa)); + CHECK(IsSignallingNaN(sn)); + CHECK(IsSignallingNaN(sm)); + CHECK(IsSignallingNaN(sa)); + CHECK(IsQuietNaN(qn)); + CHECK(IsQuietNaN(qm)); + CHECK(IsQuietNaN(qa)); // - Signalling NaNs DefaultNaNHelper(sn, 0.0f, 0.0f); @@ -10820,7 +10760,7 @@ TEST(default_nan_float) { static void DefaultNaNHelper(double n, double m, double a) { - DCHECK(std::isnan(n) || std::isnan(m) || std::isnan(a)); + CHECK(std::isnan(n) || std::isnan(m) || std::isnan(a)); bool test_1op = std::isnan(n); bool test_2op = std::isnan(n) || std::isnan(m); @@ -10913,12 +10853,12 @@ TEST(default_nan_double) { double qn = rawbits_to_double(0x7ffaaaaa11111111); double qm = rawbits_to_double(0x7ffaaaaa22222222); double qa = rawbits_to_double(0x7ffaaaaaaaaaaaaa); - DCHECK(IsSignallingNaN(sn)); - DCHECK(IsSignallingNaN(sm)); - DCHECK(IsSignallingNaN(sa)); - DCHECK(IsQuietNaN(qn)); - DCHECK(IsQuietNaN(qm)); - DCHECK(IsQuietNaN(qa)); + CHECK(IsSignallingNaN(sn)); + CHECK(IsSignallingNaN(sm)); + CHECK(IsSignallingNaN(sa)); + CHECK(IsQuietNaN(qn)); + CHECK(IsQuietNaN(qm)); + CHECK(IsQuietNaN(qa)); // - Signalling NaNs DefaultNaNHelper(sn, 0.0, 0.0); @@ -11156,16 +11096,16 @@ TEST(pool_size) { for (RelocIterator it(*code, pool_mask); !it.done(); it.next()) { RelocInfo* info = it.rinfo(); if (RelocInfo::IsConstPool(info->rmode())) { - DCHECK(info->data() == constant_pool_size); + CHECK(info->data() == constant_pool_size); ++pool_count; } if (RelocInfo::IsVeneerPool(info->rmode())) { - DCHECK(info->data() == veneer_pool_size); + CHECK(info->data() == veneer_pool_size); ++pool_count; } } - DCHECK(pool_count == 2); + CHECK(pool_count == 2); TEARDOWN(); } diff --git a/deps/v8/test/cctest/test-assembler-ia32.cc b/deps/v8/test/cctest/test-assembler-ia32.cc index e62cc210eb..12733c2cdd 100644 --- a/deps/v8/test/cctest/test-assembler-ia32.cc +++ b/deps/v8/test/cctest/test-assembler-ia32.cc @@ -310,7 +310,8 @@ TEST(AssemblerIa329) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[256]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); enum { kEqual = 0, kGreater = 1, kLess = 2, kNaN = 3, kUndefined = 4 }; Label equal_l, less_l, greater_l, nan_l; __ fld_d(Operand(esp, 3 * kPointerSize)); @@ -443,6 +444,7 @@ TEST(AssemblerMultiByteNop) { void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); CHECK(args[0]->IsArray()); v8::Local<v8::Array> vec = v8::Local<v8::Array>::Cast(args[0]); @@ -456,7 +458,8 @@ void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { // Store input vector on the stack. for (unsigned i = 0; i < ELEMENT_COUNT; ++i) { - __ push(Immediate(vec->Get(i)->Int32Value())); + __ push(Immediate( + vec->Get(context, i).ToLocalChecked()->Int32Value(context).FromJust())); } // Read vector into a xmm register. @@ -490,7 +493,7 @@ TEST(StackAlignmentForSSE2) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate); global_template->Set(v8_str("do_sse2"), v8::FunctionTemplate::New(isolate, DoSSE2)); @@ -502,20 +505,21 @@ TEST(StackAlignmentForSSE2) { "}"); v8::Local<v8::Object> global_object = env->Global(); - v8::Local<v8::Function> foo = - v8::Local<v8::Function>::Cast(global_object->Get(v8_str("foo"))); + v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( + global_object->Get(env.local(), v8_str("foo")).ToLocalChecked()); int32_t vec[ELEMENT_COUNT] = { -1, 1, 1, 1 }; v8::Local<v8::Array> v8_vec = v8::Array::New(isolate, ELEMENT_COUNT); for (unsigned i = 0; i < ELEMENT_COUNT; i++) { - v8_vec->Set(i, v8_num(vec[i])); + v8_vec->Set(env.local(), i, v8_num(vec[i])).FromJust(); } v8::Local<v8::Value> args[] = { v8_vec }; - v8::Local<v8::Value> result = foo->Call(global_object, 1, args); + v8::Local<v8::Value> result = + foo->Call(env.local(), global_object, 1, args).ToLocalChecked(); // The mask should be 0b1000. - CHECK_EQ(8, result->Int32Value()); + CHECK_EQ(8, result->Int32Value(env.local()).FromJust()); } #undef ELEMENT_COUNT @@ -529,7 +533,8 @@ TEST(AssemblerIa32Extractps) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[256]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { CpuFeatureScope fscope41(&assm, SSE4_1); __ movsd(xmm1, Operand(esp, 4)); __ extractps(eax, xmm1, 0x1); @@ -560,7 +565,8 @@ TEST(AssemblerIa32SSE) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[256]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { __ movss(xmm0, Operand(esp, kPointerSize)); __ movss(xmm1, Operand(esp, 2 * kPointerSize)); @@ -597,7 +603,8 @@ TEST(AssemblerX64FMA_sd) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[1024]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { CpuFeatureScope fscope(&assm, FMA3); Label exit; @@ -825,7 +832,8 @@ TEST(AssemblerX64FMA_ss) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[1024]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { CpuFeatureScope fscope(&assm, FMA3); Label exit; @@ -1052,7 +1060,8 @@ TEST(AssemblerIa32BMI1) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[1024]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { CpuFeatureScope fscope(&assm, BMI1); Label exit; @@ -1159,7 +1168,8 @@ TEST(AssemblerIa32LZCNT) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[256]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { CpuFeatureScope fscope(&assm, LZCNT); Label exit; @@ -1206,7 +1216,8 @@ TEST(AssemblerIa32POPCNT) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[256]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { CpuFeatureScope fscope(&assm, POPCNT); Label exit; @@ -1253,7 +1264,8 @@ TEST(AssemblerIa32BMI2) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[2048]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { CpuFeatureScope fscope(&assm, BMI2); Label exit; diff --git a/deps/v8/test/cctest/test-assembler-mips.cc b/deps/v8/test/cctest/test-assembler-mips.cc index 4b4e658afb..4f986cea9b 100644 --- a/deps/v8/test/cctest/test-assembler-mips.cc +++ b/deps/v8/test/cctest/test-assembler-mips.cc @@ -47,8 +47,6 @@ typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); typedef Object* (*F2)(int x, int y, int p2, int p3, int p4); typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); -// clang-format off - #define __ assm. @@ -57,7 +55,7 @@ TEST(MIPS0) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); // Addition. __ addu(v0, a0, a1); @@ -69,7 +67,8 @@ TEST(MIPS0) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F2 f = FUNCTION_CAST<F2>(code->entry()); - int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0)); + int res = reinterpret_cast<int>( + CALL_GENERATED_CODE(isolate, f, 0xab0, 0xc, 0, 0, 0)); CHECK_EQ(static_cast<int32_t>(0xabc), res); } @@ -79,7 +78,7 @@ TEST(MIPS1) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label L, C; __ mov(a1, a0); @@ -104,7 +103,8 @@ TEST(MIPS1) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F1 f = FUNCTION_CAST<F1>(code->entry()); - int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 50, 0, 0, 0, 0)); + int res = reinterpret_cast<int>( + CALL_GENERATED_CODE(isolate, f, 50, 0, 0, 0, 0)); CHECK_EQ(1275, res); } @@ -114,7 +114,7 @@ TEST(MIPS2) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label exit, error; @@ -241,7 +241,8 @@ TEST(MIPS2) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F2 f = FUNCTION_CAST<F2>(code->entry()); - int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0)); + int res = reinterpret_cast<int>( + CALL_GENERATED_CODE(isolate, f, 0xab0, 0xc, 0, 0, 0)); CHECK_EQ(static_cast<int32_t>(0x31415926), res); } @@ -274,7 +275,7 @@ TEST(MIPS3) { // Create a function that accepts &t, and loads, manipulates, and stores // the doubles t.a ... t.f. - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label L, C; // Double precision floating point instructions. @@ -358,7 +359,7 @@ TEST(MIPS3) { t.fd = 0.0; t.fe = 0.0; t.ff = 0.0; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); // Expected double results. CHECK_EQ(1.5e14, t.a); @@ -413,7 +414,7 @@ TEST(MIPS4) { __ mtc1(t2, f4); __ mtc1(t3, f5); } else { - DCHECK(!IsMipsArchVariant(kMips32r1) && !IsMipsArchVariant(kLoongson)); + CHECK(!IsMipsArchVariant(kMips32r1) && !IsMipsArchVariant(kLoongson)); __ mfc1(t0, f4); __ mfhc1(t1, f4); __ mfc1(t2, f6); @@ -439,7 +440,7 @@ TEST(MIPS4) { t.a = 1.5e22; t.b = 2.75e11; t.c = 17.17; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(2.75e11, t.a); @@ -503,7 +504,7 @@ TEST(MIPS5) { t.b = 2.75e8; t.i = 12345678; t.j = -100000; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(12345678.0, t.a); @@ -571,7 +572,7 @@ TEST(MIPS6) { F3 f = FUNCTION_CAST<F3>(code->entry()); t.ui = 0x11223344; t.si = 0x99aabbcc; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(static_cast<int32_t>(0x11223344), t.r1); @@ -612,7 +613,7 @@ TEST(MIPS7) { // Create a function that accepts &t, and loads, manipulates, and stores // the doubles t.a ... t.f. - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label neither_is_nan, less_than, outa_here; __ ldc1(f4, MemOperand(a0, offsetof(T, a)) ); @@ -669,7 +670,7 @@ TEST(MIPS7) { t.e = 0.0; t.f = 0.0; t.result = 0; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(1.5e14, t.a); CHECK_EQ(2.75e11, t.b); @@ -703,7 +704,8 @@ TEST(MIPS8) { } T; T t; - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); // Basic word load. __ lw(t0, MemOperand(a0, offsetof(T, input)) ); @@ -760,7 +762,7 @@ TEST(MIPS8) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); t.input = 0x12345678; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0x0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0x0, 0, 0, 0); USE(dummy); CHECK_EQ(static_cast<int32_t>(0x81234567), t.result_rotr_4); CHECK_EQ(static_cast<int32_t>(0x78123456), t.result_rotr_8); @@ -787,7 +789,7 @@ TEST(MIPS9) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label exit, exit2, exit3; __ Branch(&exit, ge, a0, Operand(zero_reg)); @@ -868,7 +870,7 @@ TEST(MIPS10) { F3 f = FUNCTION_CAST<F3>(code->entry()); t.a = 2.147483646e+09; // 0x7FFFFFFE -> 0xFF80000041DFFFFF as double. t.b_word = 0x0ff00ff0; // 0x0FF00FF0 -> 0x as double. - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(static_cast<int32_t>(0x41DFFFFF), t.dbl_exp); CHECK_EQ(static_cast<int32_t>(0xFF800000), t.dbl_mant); @@ -997,7 +999,7 @@ TEST(MIPS11) { t.reg_init = 0xaabbccdd; t.mem_init = 0x11223344; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -1061,7 +1063,7 @@ TEST(MIPS12) { } T; T t; - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ mov(t6, fp); // Save frame pointer. __ mov(fp, a0); // Access struct T by fp. @@ -1127,7 +1129,7 @@ TEST(MIPS12) { t.y3 = 0XBABA; t.y4 = 0xDEDA; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(3, t.y1); @@ -1150,7 +1152,7 @@ TEST(MIPS13) { } T; T t; - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ sw(t0, MemOperand(a0, offsetof(T, cvt_small_in))); __ Cvt_d_uw(f10, t0, f4); @@ -1178,7 +1180,7 @@ TEST(MIPS13) { t.cvt_big_in = 0xFFFFFFFF; t.cvt_small_in = 333; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(t.cvt_big_out, static_cast<double>(t.cvt_big_in)); @@ -1197,6 +1199,7 @@ TEST(MIPS14) { HandleScope scope(isolate); #define ROUND_STRUCT_ELEMENT(x) \ + uint32_t x##_isNaN2008; \ int32_t x##_up_out; \ int32_t x##_down_out; \ int32_t neg_##x##_up_out; \ @@ -1227,13 +1230,15 @@ TEST(MIPS14) { #undef ROUND_STRUCT_ELEMENT - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); // Save FCSR. __ cfc1(a1, FCSR); // Disable FPU exceptions. __ ctc1(zero_reg, FCSR); #define RUN_ROUND_TEST(x) \ + __ cfc1(t0, FCSR);\ + __ sw(t0, MemOperand(a0, offsetof(T, x##_isNaN2008))); \ __ ldc1(f0, MemOperand(a0, offsetof(T, round_up_in))); \ __ x##_w_d(f0, f0); \ __ swc1(f0, MemOperand(a0, offsetof(T, x##_up_out))); \ @@ -1302,16 +1307,22 @@ TEST(MIPS14) { t.err3_in = static_cast<double>(1) + 0xFFFFFFFF; t.err4_in = NAN; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); #define GET_FPU_ERR(x) (static_cast<int>(x & kFCSRFlagMask)) +#define CHECK_NAN2008(x) (x & kFCSRNaN2008FlagMask) #define CHECK_ROUND_RESULT(type) \ CHECK(GET_FPU_ERR(t.type##_err1_out) & kFCSRInexactFlagMask); \ CHECK_EQ(0, GET_FPU_ERR(t.type##_err2_out)); \ CHECK(GET_FPU_ERR(t.type##_err3_out) & kFCSRInvalidOpFlagMask); \ CHECK(GET_FPU_ERR(t.type##_err4_out) & kFCSRInvalidOpFlagMask); \ - CHECK_EQ(kFPUInvalidResult, static_cast<uint>(t.type##_invalid_result)); + if (CHECK_NAN2008(t.type##_isNaN2008) && kArchVariant == kMips32r6) {\ + CHECK_EQ(static_cast<int32_t>(0), t.type##_invalid_result);\ + } else {\ + CHECK_EQ(static_cast<int32_t>(kFPUInvalidResult), t.type##_invalid_result);\ + } + CHECK_ROUND_RESULT(round); CHECK_ROUND_RESULT(floor); @@ -1343,7 +1354,8 @@ TEST(seleqz_selnez) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test { int a; @@ -1392,7 +1404,7 @@ TEST(seleqz_selnez) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, 1); CHECK_EQ(test.b, 0); @@ -1420,7 +1432,7 @@ TEST(seleqz_selnez) { test.f = tests_D[j]; test.i = inputs_S[i]; test.j = tests_S[j]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.g, outputs_D[i]); CHECK_EQ(test.h, 0); CHECK_EQ(test.k, outputs_S[i]); @@ -1428,7 +1440,7 @@ TEST(seleqz_selnez) { test.f = tests_D[j+1]; test.j = tests_S[j+1]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.g, 0); CHECK_EQ(test.h, outputs_D[i]); CHECK_EQ(test.k, 0); @@ -1444,7 +1456,8 @@ TEST(min_max) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double a; @@ -1497,7 +1510,7 @@ TEST(min_max) { test.e = inputse[i]; test.f = inputsf[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); if (i < kTableLength - 1) { CHECK_EQ(test.c, outputsdmin[i]); @@ -1505,10 +1518,10 @@ TEST(min_max) { CHECK_EQ(test.g, outputsfmin[i]); CHECK_EQ(test.h, outputsfmax[i]); } else { - DCHECK(std::isnan(test.c)); - DCHECK(std::isnan(test.d)); - DCHECK(std::isnan(test.g)); - DCHECK(std::isnan(test.h)); + CHECK(std::isnan(test.c)); + CHECK(std::isnan(test.d)); + CHECK(std::isnan(test.g)); + CHECK(std::isnan(test.h)); } } } @@ -1521,7 +1534,8 @@ TEST(rint_d) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double a; @@ -1613,7 +1627,7 @@ TEST(rint_d) { test.fcsr = fcsr_inputs[j]; for (int i = 0; i < kTableLength; i++) { test.a = inputs[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs[j][i]); } } @@ -1626,7 +1640,8 @@ TEST(sel) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test { double dd; @@ -1679,13 +1694,13 @@ TEST(sel) { test.ft = inputs_ft[i]; test.fd = tests_S[j]; test.fs = inputs_fs[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dd, inputs_ds[i]); CHECK_EQ(test.fd, inputs_fs[i]); test.dd = tests_D[j+1]; test.fd = tests_S[j+1]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dd, inputs_dt[i]); CHECK_EQ(test.fd, inputs_ft[i]); } @@ -1700,7 +1715,8 @@ TEST(rint_s) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test_float { float a; @@ -1792,7 +1808,7 @@ TEST(rint_s) { test.fcsr = fcsr_inputs[j]; for (int i = 0; i < kTableLength; i++) { test.a = inputs[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs[j][i]); } } @@ -1800,13 +1816,59 @@ TEST(rint_s) { } +TEST(Cvt_d_uw) { + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); + + typedef struct test_struct { + unsigned input; + uint64_t output; + } TestStruct; + + unsigned inputs[] = { + 0x0, 0xffffffff, 0x80000000, 0x7fffffff + }; + + uint64_t outputs[] = { + 0x0, 0x41efffffffe00000, + 0x41e0000000000000, 0x41dfffffffc00000 + }; + + int kTableLength = sizeof(inputs)/sizeof(inputs[0]); + + TestStruct test; + + __ lw(t1, MemOperand(a0, offsetof(TestStruct, input))); + __ Cvt_d_uw(f4, t1, f6); + __ sdc1(f4, MemOperand(a0, offsetof(TestStruct, output))); + __ jr(ra); + __ nop(); + + CodeDesc desc; + assm.GetCode(&desc); + 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 < kTableLength; i++) { + test.input = inputs[i]; + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + // Check outputs + CHECK_EQ(test.output, outputs[i]); + } +} + + TEST(mina_maxa) { if (IsMipsArchVariant(kMips32r6)) { const int kTableLength = 15; CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); const double double_nan = std::numeric_limits<double>::quiet_NaN(); const float float_nan = std::numeric_limits<float>::quiet_NaN(); @@ -1880,17 +1942,17 @@ TEST(mina_maxa) { test.b = inputsb[i]; test.c = inputsc[i]; test.d = inputsd[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); 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)); + CHECK(std::isnan(test.resd)); + CHECK(std::isnan(test.resf)); + CHECK(std::isnan(test.resd1)); + CHECK(std::isnan(test.resf1)); } } } @@ -1903,9 +1965,11 @@ TEST(trunc_l) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int64_t c; // a trunc result @@ -1931,7 +1995,15 @@ TEST(trunc_l) { -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, 2147483648.0, dFPU64InvalidResult, dFPU64InvalidResult}; + double outputsNaN2008[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, + 0, + dFPU64InvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ trunc_l_d(f8, f4); @@ -1949,8 +2021,13 @@ TEST(trunc_l) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && + kArchVariant == kMips32r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -1963,7 +2040,8 @@ TEST(movz_movn) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test_float { int64_t rt; @@ -2026,14 +2104,14 @@ TEST(movz_movn) { test.c = inputs_S[i]; test.rt = 1; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, test.bold); CHECK_EQ(test.d, test.dold); CHECK_EQ(test.b1, outputs_D[i]); CHECK_EQ(test.d1, outputs_S[i]); test.rt = 0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs_D[i]); CHECK_EQ(test.d, outputs_S[i]); CHECK_EQ(test.b1, test.bold1); @@ -2092,7 +2170,8 @@ TEST(movt_movd) { test.fcsr = 1 << (24+condition_flags[j]); } HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, srcd)) ); __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, srcf)) ); __ lw(t1, MemOperand(a0, offsetof(TestFloat, fcsr)) ); @@ -2123,13 +2202,13 @@ TEST(movt_movd) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dstf, outputs_S[i]); CHECK_EQ(test.dstd, outputs_D[i]); CHECK_EQ(test.dstf1, test.dstfold1); CHECK_EQ(test.dstd1, test.dstdold1); test.fcsr = 0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dstf, test.dstfold); CHECK_EQ(test.dstd, test.dstdold); CHECK_EQ(test.dstf1, outputs_S[i]); @@ -2145,7 +2224,7 @@ TEST(cvt_w_d) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double a; @@ -2211,7 +2290,7 @@ TEST(cvt_w_d) { test.fcsr = fcsr_inputs[j]; for (int i = 0; i < kTableLength; i++) { test.a = inputs[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs[j][i]); } } @@ -2222,9 +2301,10 @@ TEST(trunc_w) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int32_t c; // a trunc result @@ -2250,7 +2330,15 @@ TEST(trunc_w) { -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, kFPUInvalidResult, kFPUInvalidResult, kFPUInvalidResult}; + double outputsNaN2008[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, + 0, + kFPUInvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ trunc_w_d(f8, f4); @@ -2268,8 +2356,12 @@ TEST(trunc_w) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips32r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -2279,9 +2371,10 @@ TEST(round_w) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int32_t c; // a trunc result @@ -2307,7 +2400,14 @@ TEST(round_w) { -2.0, -3.0, -2.0, -3.0, -4.0, -4.0, kFPUInvalidResult, kFPUInvalidResult, kFPUInvalidResult}; + double outputsNaN2008[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, 0, + kFPUInvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ round_w_d(f8, f4); @@ -2325,8 +2425,12 @@ TEST(round_w) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips32r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -2337,9 +2441,11 @@ TEST(round_l) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int64_t c; @@ -2365,7 +2471,15 @@ TEST(round_l) { -2.0, -3.0, -2.0, -3.0, -4.0, -4.0, 2147483648.0, dFPU64InvalidResult, dFPU64InvalidResult}; + double outputsNaN2008[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, + 0, + dFPU64InvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ round_l_d(f8, f4); @@ -2383,8 +2497,13 @@ TEST(round_l) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && + kArchVariant == kMips32r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -2396,7 +2515,7 @@ TEST(sub) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { float a; @@ -2453,7 +2572,7 @@ TEST(sub) { test.b = inputft_S[i]; test.c = inputfs_D[i]; test.d = inputft_D[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.resultS, outputs_S[i]); CHECK_EQ(test.resultD, outputs_D[i]); } @@ -2469,7 +2588,7 @@ TEST(sqrt_rsqrt_recip) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { float a; @@ -2534,7 +2653,7 @@ TEST(sqrt_rsqrt_recip) { test.a = inputs_S[i]; test.c = inputs_D[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.resultS, outputs_S[i]); CHECK_EQ(test.resultD, outputs_D[i]); @@ -2569,7 +2688,7 @@ TEST(neg) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { float a; @@ -2610,7 +2729,7 @@ TEST(neg) { 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)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.resultS, outputs_S[i]); CHECK_EQ(test.resultD, outputs_D[i]); } @@ -2622,7 +2741,7 @@ TEST(mul) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { float a; @@ -2669,7 +2788,7 @@ TEST(mul) { test.b = inputft_S[i]; test.c = inputfs_D[i]; test.d = inputft_D[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.resultS, inputfs_S[i]*inputft_S[i]); CHECK_EQ(test.resultD, inputfs_D[i]*inputft_D[i]); } @@ -2681,7 +2800,7 @@ TEST(mov) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double a; @@ -2724,7 +2843,7 @@ TEST(mov) { test.a = inputs_D[i]; test.c = inputs_S[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs_D[i]); CHECK_EQ(test.d, outputs_S[i]); } @@ -2735,9 +2854,10 @@ TEST(floor_w) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int32_t c; // a floor result @@ -2763,7 +2883,15 @@ TEST(floor_w) { -3.0, -3.0, -3.0, -4.0, -4.0, -4.0, kFPUInvalidResult, kFPUInvalidResult, kFPUInvalidResult}; + double outputsNaN2008[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, + 0, + kFPUInvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ floor_w_d(f8, f4); @@ -2781,8 +2909,12 @@ TEST(floor_w) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips32r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -2793,9 +2925,11 @@ TEST(floor_l) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int64_t c; @@ -2821,7 +2955,15 @@ TEST(floor_l) { -3.0, -3.0, -3.0, -4.0, -4.0, -4.0, 2147483648.0, dFPU64InvalidResult, dFPU64InvalidResult}; + double outputsNaN2008[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, + 0, + dFPU64InvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ floor_l_d(f8, f4); @@ -2839,8 +2981,13 @@ TEST(floor_l) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && + kArchVariant == kMips32r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -2851,9 +2998,10 @@ TEST(ceil_w) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int32_t c; // a floor result @@ -2879,7 +3027,15 @@ TEST(ceil_w) { -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, kFPUInvalidResult, kFPUInvalidResult, kFPUInvalidResult}; + double outputsNaN2008[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, + 0, + kFPUInvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ ceil_w_d(f8, f4); @@ -2897,8 +3053,12 @@ TEST(ceil_w) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips32r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -2909,9 +3069,11 @@ TEST(ceil_l) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int64_t c; @@ -2937,7 +3099,15 @@ TEST(ceil_l) { -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, 2147483648.0, dFPU64InvalidResult, dFPU64InvalidResult}; + double outputsNaN2008[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, + 0, + dFPU64InvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ ceil_l_d(f8, f4); @@ -2955,8 +3125,13 @@ TEST(ceil_l) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && + kArchVariant == kMips32r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -3021,7 +3196,8 @@ TEST(jump_tables1) { #endif F1 f = FUNCTION_CAST<F1>(code->entry()); for (int i = 0; i < kNumCases; ++i) { - int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, i, 0, 0, 0, 0)); + int res = reinterpret_cast<int>( + CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0)); ::printf("f(%d) = %d\n", i, res); CHECK_EQ(values[i], res); } @@ -3090,7 +3266,8 @@ TEST(jump_tables2) { #endif F1 f = FUNCTION_CAST<F1>(code->entry()); for (int i = 0; i < kNumCases; ++i) { - int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, i, 0, 0, 0, 0)); + int res = reinterpret_cast<int>( + CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0)); ::printf("f(%d) = %d\n", i, res); CHECK_EQ(values[i], res); } @@ -3166,7 +3343,8 @@ TEST(jump_tables3) { #endif F1 f = FUNCTION_CAST<F1>(code->entry()); for (int i = 0; i < kNumCases; ++i) { - Handle<Object> result(CALL_GENERATED_CODE(f, i, 0, 0, 0, 0), isolate); + Handle<Object> result( + CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0), isolate); #ifdef OBJECT_PRINT ::printf("f(%d) = ", i); result->Print(std::cout); @@ -3214,7 +3392,7 @@ TEST(BITSWAP) { F3 f = FUNCTION_CAST<F3>(code->entry()); t.r1 = 0x781A15C3; t.r2 = 0x8B71FCDE; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(static_cast<int32_t>(0x1E58A8C3), t.r1); @@ -3255,7 +3433,8 @@ TEST(class_fmt) { // Create a function that accepts &t, and loads, manipulates, and stores // the doubles t.a ... t.f. - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); __ ldc1(f4, MemOperand(a0, offsetof(T, dSignalingNan))); __ class_d(f6, f4); @@ -3370,7 +3549,7 @@ TEST(class_fmt) { t.fPosSubnorm = FLT_MIN / 20.0; t.fPosZero = +0.0; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); // Expected double results. CHECK_EQ(bit_cast<int64_t>(t.dSignalingNan), 0x001); @@ -3403,7 +3582,7 @@ TEST(ABS) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { int64_t fir; @@ -3440,34 +3619,34 @@ TEST(ABS) { F3 f = FUNCTION_CAST<F3>(code->entry()); test.a = -2.0; test.b = -2.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, 2.0); CHECK_EQ(test.b, 2.0); test.a = 2.0; test.b = 2.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, 2.0); CHECK_EQ(test.b, 2.0); // Testing biggest positive number test.a = std::numeric_limits<double>::max(); test.b = std::numeric_limits<float>::max(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, std::numeric_limits<double>::max()); CHECK_EQ(test.b, std::numeric_limits<float>::max()); // Testing smallest negative number test.a = -std::numeric_limits<double>::max(); // lowest() test.b = -std::numeric_limits<float>::max(); // lowest() - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, std::numeric_limits<double>::max()); CHECK_EQ(test.b, std::numeric_limits<float>::max()); // Testing smallest positive number test.a = -std::numeric_limits<double>::min(); test.b = -std::numeric_limits<float>::min(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, std::numeric_limits<double>::min()); CHECK_EQ(test.b, std::numeric_limits<float>::min()); @@ -3476,7 +3655,7 @@ TEST(ABS) { / std::numeric_limits<double>::min(); test.b = -std::numeric_limits<float>::max() / std::numeric_limits<float>::min(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, std::numeric_limits<double>::max() / std::numeric_limits<double>::min()); CHECK_EQ(test.b, std::numeric_limits<float>::max() @@ -3484,13 +3663,13 @@ TEST(ABS) { test.a = std::numeric_limits<double>::quiet_NaN(); test.b = std::numeric_limits<float>::quiet_NaN(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(std::isnan(test.a), true); CHECK_EQ(std::isnan(test.b), true); test.a = std::numeric_limits<double>::signaling_NaN(); test.b = std::numeric_limits<float>::signaling_NaN(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(std::isnan(test.a), true); CHECK_EQ(std::isnan(test.b), true); } @@ -3500,7 +3679,7 @@ TEST(ADD_FMT) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double a; @@ -3535,7 +3714,7 @@ TEST(ADD_FMT) { test.b = 3.0; test.fa = 2.0; test.fb = 3.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.c, 5.0); CHECK_EQ(test.fc, 5.0); @@ -3543,7 +3722,7 @@ TEST(ADD_FMT) { test.b = -std::numeric_limits<double>::max(); // lowest() test.fa = std::numeric_limits<float>::max(); test.fb = -std::numeric_limits<float>::max(); // lowest() - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.c, 0.0); CHECK_EQ(test.fc, 0.0); @@ -3551,7 +3730,7 @@ TEST(ADD_FMT) { test.b = std::numeric_limits<double>::max(); test.fa = std::numeric_limits<float>::max(); test.fb = std::numeric_limits<float>::max(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(std::isfinite(test.c), false); CHECK_EQ(std::isfinite(test.fc), false); @@ -3559,7 +3738,7 @@ TEST(ADD_FMT) { test.b = std::numeric_limits<double>::signaling_NaN(); test.fa = 5.0; test.fb = std::numeric_limits<float>::signaling_NaN(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(std::isnan(test.c), true); CHECK_EQ(std::isnan(test.fc), true); } @@ -3570,7 +3749,8 @@ TEST(C_COND_FMT) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double dOp1; @@ -3689,7 +3869,7 @@ TEST(C_COND_FMT) { test.dOp2 = 3.0; test.fOp1 = 2.0; test.fOp2 = 3.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dF, 0U); CHECK_EQ(test.dUn, 0U); CHECK_EQ(test.dEq, 0U); @@ -3711,7 +3891,7 @@ TEST(C_COND_FMT) { test.dOp2 = std::numeric_limits<double>::min(); test.fOp1 = std::numeric_limits<float>::min(); test.fOp2 = -std::numeric_limits<float>::max(); // lowest() - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dF, 0U); CHECK_EQ(test.dUn, 0U); CHECK_EQ(test.dEq, 0U); @@ -3733,7 +3913,7 @@ TEST(C_COND_FMT) { test.dOp2 = -std::numeric_limits<double>::max(); // lowest() test.fOp1 = std::numeric_limits<float>::max(); test.fOp2 = std::numeric_limits<float>::max(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dF, 0U); CHECK_EQ(test.dUn, 0U); CHECK_EQ(test.dEq, 1U); @@ -3755,7 +3935,7 @@ TEST(C_COND_FMT) { test.dOp2 = 0.0; test.fOp1 = std::numeric_limits<float>::quiet_NaN(); test.fOp2 = 0.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dF, 0U); CHECK_EQ(test.dUn, 1U); CHECK_EQ(test.dEq, 0U); @@ -3781,7 +3961,8 @@ TEST(CMP_COND_FMT) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double dOp1; @@ -3894,7 +4075,7 @@ TEST(CMP_COND_FMT) { test.dOp2 = 3.0; test.fOp1 = 2.0; test.fOp2 = 3.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse); @@ -3919,7 +4100,7 @@ TEST(CMP_COND_FMT) { test.dOp2 = std::numeric_limits<double>::min(); test.fOp1 = std::numeric_limits<float>::min(); test.fOp2 = -std::numeric_limits<float>::max(); // lowest() - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse); @@ -3944,7 +4125,7 @@ TEST(CMP_COND_FMT) { test.dOp2 = -std::numeric_limits<double>::max(); // lowest() test.fOp1 = std::numeric_limits<float>::max(); test.fOp2 = std::numeric_limits<float>::max(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dEq), dTrue); @@ -3969,7 +4150,7 @@ TEST(CMP_COND_FMT) { test.dOp2 = 0.0; test.fOp1 = std::numeric_limits<float>::quiet_NaN(); test.fOp2 = 0.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dUn), dTrue); CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse); @@ -3997,7 +4178,7 @@ TEST(CVT) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { float cvt_d_s_in; @@ -4040,7 +4221,8 @@ TEST(CVT) { GENERATE_CVT_TEST(cvt_d_s, lw, sd) GENERATE_CVT_TEST(cvt_d_w, lw, sd) - if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { GENERATE_CVT_TEST(cvt_d_l, ld, sd) } @@ -4051,7 +4233,8 @@ TEST(CVT) { GENERATE_CVT_TEST(cvt_s_d, ld, sw) GENERATE_CVT_TEST(cvt_s_w, lw, sw) - if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { GENERATE_CVT_TEST(cvt_s_l, ld, sw) } @@ -4081,10 +4264,11 @@ TEST(CVT) { test.cvt_w_s_in = -0.51; test.cvt_w_d_in = -0.51; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); - if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); } if (IsFp64Mode()) { @@ -4093,7 +4277,8 @@ TEST(CVT) { } CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in)); CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in)); - if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in)); } CHECK_EQ(test.cvt_w_s_out, -1); @@ -4111,10 +4296,11 @@ TEST(CVT) { test.cvt_w_s_in = 0.49; test.cvt_w_d_in = 0.49; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); - if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); } if (IsFp64Mode()) { @@ -4123,7 +4309,8 @@ TEST(CVT) { } CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in)); CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in)); - if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in)); } CHECK_EQ(test.cvt_w_s_out, 0); @@ -4140,10 +4327,11 @@ TEST(CVT) { test.cvt_w_s_in = std::numeric_limits<float>::max(); test.cvt_w_d_in = std::numeric_limits<double>::max(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); - if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); } if (IsFp64Mode()) { @@ -4152,7 +4340,8 @@ TEST(CVT) { } CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in)); CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in)); - if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in)); } CHECK_EQ(test.cvt_w_s_out, std::numeric_limits<int32_t>::max()); @@ -4170,10 +4359,11 @@ TEST(CVT) { test.cvt_w_s_in = -std::numeric_limits<float>::max(); // lowest() test.cvt_w_d_in = -std::numeric_limits<double>::max(); // lowest() - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); - if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); } // The returned value when converting from fixed-point to float-point @@ -4187,7 +4377,8 @@ TEST(CVT) { } CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in)); CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in)); - if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in)); } CHECK(test.cvt_w_s_out == std::numeric_limits<int32_t>::min() || @@ -4207,10 +4398,11 @@ TEST(CVT) { test.cvt_w_s_in = std::numeric_limits<float>::min(); test.cvt_w_d_in = std::numeric_limits<double>::min(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); - if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); } if (IsFp64Mode()) { @@ -4219,7 +4411,8 @@ TEST(CVT) { } CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in)); CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in)); - if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in)); } CHECK_EQ(test.cvt_w_s_out, 0); @@ -4231,7 +4424,7 @@ TEST(DIV_FMT) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test { double dOp1; @@ -4274,7 +4467,7 @@ TEST(DIV_FMT) { F3 f = FUNCTION_CAST<F3>(code->entry()); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); const int test_size = 3; @@ -4315,7 +4508,7 @@ TEST(DIV_FMT) { test.fOp1 = fOp1[i]; test.fOp2 = fOp2[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dRes, dRes[i]); CHECK_EQ(test.fRes, fRes[i]); } @@ -4325,7 +4518,7 @@ TEST(DIV_FMT) { test.fOp1 = FLT_MAX; test.fOp2 = -0.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(false, std::isfinite(test.dRes)); CHECK_EQ(false, std::isfinite(test.fRes)); @@ -4334,7 +4527,7 @@ TEST(DIV_FMT) { test.fOp1 = 0.0; test.fOp2 = -0.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(true, std::isnan(test.dRes)); CHECK_EQ(true, std::isnan(test.fRes)); @@ -4343,7 +4536,7 @@ TEST(DIV_FMT) { test.fOp1 = std::numeric_limits<float>::quiet_NaN(); test.fOp2 = -5.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(true, std::isnan(test.dRes)); CHECK_EQ(true, std::isnan(test.fRes)); } @@ -4353,7 +4546,7 @@ uint32_t run_align(uint32_t rs_value, uint32_t rt_value, uint8_t bp) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ align(v0, a0, a1, bp); __ jr(ra); @@ -4366,10 +4559,8 @@ uint32_t run_align(uint32_t rs_value, uint32_t rt_value, uint8_t bp) { F2 f = FUNCTION_CAST<F2>(code->entry()); - uint32_t res = - reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, rs_value, - rt_value, - 0, 0, 0)); + uint32_t res = reinterpret_cast<uint32_t>(CALL_GENERATED_CODE( + isolate, f, rs_value, rt_value, 0, 0, 0)); return res; } @@ -4408,7 +4599,7 @@ uint32_t run_aluipc(int16_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ aluipc(v0, offset); __ jr(ra); @@ -4422,8 +4613,8 @@ uint32_t run_aluipc(int16_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); PC = (uint32_t) f; // Set the program counter. - uint32_t res = - reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint32_t res = reinterpret_cast<uint32_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -4462,7 +4653,7 @@ uint32_t run_auipc(int16_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ auipc(v0, offset); __ jr(ra); @@ -4476,8 +4667,8 @@ uint32_t run_auipc(int16_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); PC = (uint32_t) f; // Set the program counter. - uint32_t res = - reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint32_t res = reinterpret_cast<uint32_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -4516,7 +4707,7 @@ uint32_t run_lwpc(int offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); // 256k instructions; 2^8k // addiu t7, t0, 0xffff; (0x250fffff) @@ -4551,8 +4742,8 @@ uint32_t run_lwpc(int offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - uint32_t res = - reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint32_t res = reinterpret_cast<uint32_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -4592,7 +4783,7 @@ uint32_t run_jic(int16_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label get_program_counter, stop_execution; __ push(ra); @@ -4635,8 +4826,8 @@ uint32_t run_jic(int16_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - uint32_t res = - reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint32_t res = reinterpret_cast<uint32_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -4673,7 +4864,7 @@ uint64_t run_beqzc(int32_t value, int32_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label stop_execution; __ li(v0, 0); @@ -4707,8 +4898,8 @@ uint64_t run_beqzc(int32_t value, int32_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - uint32_t res = - reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, value, 0, 0, 0, 0)); + uint32_t res = reinterpret_cast<uint32_t>( + CALL_GENERATED_CODE(isolate, f, value, 0, 0, 0, 0)); return res; } @@ -4746,7 +4937,7 @@ uint32_t run_jialc(int16_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label main_block, get_program_counter; __ push(ra); @@ -4801,8 +4992,8 @@ uint32_t run_jialc(int16_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - uint32_t res = - reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint32_t res = reinterpret_cast<uint32_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -4838,7 +5029,7 @@ uint64_t run_addiupc(int32_t imm19) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ addiupc(v0, imm19); __ jr(ra); @@ -4852,8 +5043,8 @@ uint64_t run_addiupc(int32_t imm19) { F2 f = FUNCTION_CAST<F2>(code->entry()); PC = (uint32_t) f; // Set the program counter. - uint32_t rs = - reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, imm19, 0, 0, 0, 0)); + uint32_t rs = reinterpret_cast<uint32_t>( + CALL_GENERATED_CODE(isolate, f, imm19, 0, 0, 0, 0)); return rs; } @@ -4892,7 +5083,7 @@ int32_t run_bc(int32_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label continue_1, stop_execution; __ push(ra); @@ -4900,9 +5091,8 @@ int32_t run_bc(int32_t offset) { __ li(t8, 0); __ li(t9, 2); // A condition for stopping execution. - uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1 for (int32_t i = -100; i <= -11; ++i) { - __ dd(instruction_addiu); + __ addiu(v0, v0, 1); } __ addiu(t8, t8, 1); // -10 @@ -4921,7 +5111,7 @@ int32_t run_bc(int32_t offset) { __ bc(offset); // -1 for (int32_t i = 0; i <= 99; ++i) { - __ dd(instruction_addiu); + __ addiu(v0, v0, 1); } __ pop(ra); @@ -4935,8 +5125,8 @@ int32_t run_bc(int32_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - int32_t res = - reinterpret_cast<int32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + int32_t res = reinterpret_cast<int32_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -4973,7 +5163,7 @@ int32_t run_balc(int32_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label continue_1, stop_execution; __ push(ra); @@ -5017,13 +5207,71 @@ int32_t run_balc(int32_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - int32_t res = - reinterpret_cast<int32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + int32_t res = reinterpret_cast<int32_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } +uint32_t run_aui(uint32_t rs, uint16_t offset) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); + + __ li(t0, rs); + __ aui(v0, t0, offset); + __ 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(isolate, f, 0, 0, 0, 0, 0)); + + return res; +} + + +TEST(r6_aui) { + if (IsMipsArchVariant(kMips32r6)) { + CcTest::InitializeVM(); + + struct TestCaseAui { + uint32_t rs; + uint16_t offset; + uint32_t ref_res; + }; + + struct TestCaseAui tc[] = { + // input, offset, result + {0xfffeffff, 1, 0xffffffff}, + {0xffffffff, 0, 0xffffffff}, + {0, 0xffff, 0xffff0000}, + {0x0008ffff, 0xfff7, 0xffffffff}, + {32767, 32767, 0x7fff7fff}, + // overflow cases + {0xffffffff, 0x1, 0x0000ffff}, + {0xffffffff, 0xffff, 0xfffeffff}, + }; + + size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAui); + for (size_t i = 0; i < nr_test_cases; ++i) { + PC = 0; + uint32_t res = run_aui(tc[i].rs, tc[i].offset); + CHECK_EQ(tc[i].ref_res, res); + } + } +} + + TEST(r6_balc) { if (IsMipsArchVariant(kMips32r6)) { CcTest::InitializeVM(); @@ -5054,7 +5302,7 @@ uint32_t run_bal(int16_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ mov(t0, ra); __ bal(offset); // Equivalent for "BGEZAL zero_reg, offset". @@ -5075,8 +5323,8 @@ uint32_t run_bal(int16_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - uint32_t res = - reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint32_t res = reinterpret_cast<uint32_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -5102,6 +5350,78 @@ TEST(bal) { } +static uint32_t run_lsa(uint32_t rt, uint32_t rs, int8_t sa) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + MacroAssembler assm(isolate, nullptr, 0, + v8::internal::CodeObjectRequired::kYes); + + __ lsa(v0, a0, a1, sa); + __ jr(ra); + __ nop(); + + CodeDesc desc; + assm.GetCode(&desc); + Handle<Code> code = isolate->factory()->NewCode( + desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); + + F1 f = FUNCTION_CAST<F1>(code->entry()); + + uint32_t res = reinterpret_cast<uint32_t>( + CALL_GENERATED_CODE(isolate, f, rt, rs, 0, 0, 0)); + + return res; +} + + +TEST(lsa) { + if (!IsMipsArchVariant(kMips32r6)) return; + + CcTest::InitializeVM(); + struct TestCaseLsa { + int32_t rt; + int32_t rs; + uint8_t sa; + uint32_t expected_res; + }; + + struct TestCaseLsa tc[] = { + // rt, rs, sa, expected_res + {0x4, 0x1, 1, 0x6}, + {0x4, 0x1, 2, 0x8}, + {0x4, 0x1, 3, 0xc}, + {0x4, 0x1, 4, 0x14}, + {0x0, 0x1, 1, 0x2}, + {0x0, 0x1, 2, 0x4}, + {0x0, 0x1, 3, 0x8}, + {0x0, 0x1, 4, 0x10}, + {0x4, 0x0, 1, 0x4}, + {0x4, 0x0, 2, 0x4}, + {0x4, 0x0, 3, 0x4}, + {0x4, 0x0, 4, 0x4}, + {0x4, INT32_MAX, 1, 0x2}, // Shift overflow. + {0x4, INT32_MAX >> 1, 2, 0x0}, // Shift overflow. + {0x4, INT32_MAX >> 2, 3, 0xfffffffc}, // Shift overflow. + {0x4, INT32_MAX >> 3, 4, 0xfffffff4}, // Shift overflow. + {INT32_MAX - 1, 0x1, 1, 0x80000000}, // Signed adition overflow. + {INT32_MAX - 3, 0x1, 2, 0x80000000}, // Signed addition overflow. + {INT32_MAX - 7, 0x1, 3, 0x80000000}, // Signed addition overflow. + {INT32_MAX - 15, 0x1, 4, 0x80000000}, // Signed addition overflow. + {-2, 0x1, 1, 0x0}, // Addition overflow. + {-4, 0x1, 2, 0x0}, // Addition overflow. + {-8, 0x1, 3, 0x0}, // Addition overflow. + {-16, 0x1, 4, 0x0}}; // Addition overflow. + + size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa); + for (size_t i = 0; i < nr_test_cases; ++i) { + uint32_t res = run_lsa(tc[i].rt, tc[i].rs, tc[i].sa); + PrintF("0x%x =? 0x%x == lsa(v0, %x, %x, %hhu)\n", tc[i].expected_res, res, + tc[i].rt, tc[i].rs, tc[i].sa); + CHECK_EQ(tc[i].expected_res, res); + } +} + + TEST(Trampoline) { // Private member of Assembler class. static const int kMaxBranchOffset = (1 << (18 - 1)) - 1; @@ -5110,7 +5430,8 @@ TEST(Trampoline) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, nullptr, 0); + MacroAssembler assm(isolate, nullptr, 0, + v8::internal::CodeObjectRequired::kYes); Label done; size_t nr_calls = kMaxBranchOffset / (2 * Instruction::kInstrSize) + 2; @@ -5127,10 +5448,9 @@ TEST(Trampoline) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F2 f = FUNCTION_CAST<F2>(code->entry()); - int32_t res = - reinterpret_cast<int32_t>(CALL_GENERATED_CODE(f, 42, 42, 0, 0, 0)); + int32_t res = reinterpret_cast<int32_t>( + CALL_GENERATED_CODE(isolate, f, 42, 42, 0, 0, 0)); CHECK_EQ(res, 0); } - #undef __ diff --git a/deps/v8/test/cctest/test-assembler-mips64.cc b/deps/v8/test/cctest/test-assembler-mips64.cc index d13a8b46a3..988083cadc 100644 --- a/deps/v8/test/cctest/test-assembler-mips64.cc +++ b/deps/v8/test/cctest/test-assembler-mips64.cc @@ -47,8 +47,6 @@ typedef Object* (*F2)(int x, int y, int p2, int p3, int p4); typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); typedef Object* (*F4)(int64_t x, int64_t y, int64_t p2, int64_t p3, int64_t p4); -// clang-format off - #define __ assm. @@ -57,7 +55,7 @@ TEST(MIPS0) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); // Addition. __ addu(v0, a0, a1); @@ -69,8 +67,8 @@ TEST(MIPS0) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F2 f = FUNCTION_CAST<F2>(code->entry()); - int64_t res = - reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0)); + int64_t res = reinterpret_cast<int64_t>( + CALL_GENERATED_CODE(isolate, f, 0xab0, 0xc, 0, 0, 0)); CHECK_EQ(0xabcL, res); } @@ -80,7 +78,7 @@ TEST(MIPS1) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label L, C; __ mov(a1, a0); @@ -105,8 +103,8 @@ TEST(MIPS1) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F1 f = FUNCTION_CAST<F1>(code->entry()); - int64_t res = - reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 50, 0, 0, 0, 0)); + int64_t res = reinterpret_cast<int64_t>( + CALL_GENERATED_CODE(isolate, f, 50, 0, 0, 0, 0)); CHECK_EQ(1275L, res); } @@ -116,7 +114,7 @@ TEST(MIPS2) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label exit, error; @@ -251,8 +249,8 @@ TEST(MIPS2) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F2 f = FUNCTION_CAST<F2>(code->entry()); - int64_t res = - reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 0xab0, 0xc, 0, 0, 0)); + int64_t res = reinterpret_cast<int64_t>( + CALL_GENERATED_CODE(isolate, f, 0xab0, 0xc, 0, 0, 0)); CHECK_EQ(0x31415926L, res); } @@ -286,7 +284,7 @@ TEST(MIPS3) { // Create a function that accepts &t, and loads, manipulates, and stores // the doubles t.a ... t.f. - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label L, C; // Double precision floating point instructions. @@ -370,7 +368,7 @@ TEST(MIPS3) { t.fd = 0.0; t.fe = 0.0; t.ff = 0.0; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); // Expected double results. CHECK_EQ(1.5e14, t.a); @@ -452,7 +450,7 @@ TEST(MIPS4) { t.b = 2.75e11; t.c = 17.17; t.d = -2.75e11; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(2.75e11, t.a); @@ -518,7 +516,7 @@ TEST(MIPS5) { t.b = 2.75e8; t.i = 12345678; t.j = -100000; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(12345678.0, t.a); @@ -586,7 +584,7 @@ TEST(MIPS6) { F3 f = FUNCTION_CAST<F3>(code->entry()); t.ui = 0x11223344; t.si = 0x99aabbcc; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(static_cast<int32_t>(0x11223344), t.r1); @@ -625,7 +623,7 @@ TEST(MIPS7) { // Create a function that accepts &t, and loads, manipulates, and stores // the doubles t.a ... t.f. - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label neither_is_nan, less_than, outa_here; __ ldc1(f4, MemOperand(a0, offsetof(T, a)) ); @@ -679,7 +677,7 @@ TEST(MIPS7) { t.e = 0.0; t.f = 0.0; t.result = 0; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(1.5e14, t.a); CHECK_EQ(2.75e11, t.b); @@ -713,7 +711,8 @@ TEST(MIPS8) { } T; T t; - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); // Basic word load. __ lw(a4, MemOperand(a0, offsetof(T, input)) ); @@ -770,7 +769,7 @@ TEST(MIPS8) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); t.input = 0x12345678; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0x0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0x0, 0, 0, 0); USE(dummy); CHECK_EQ(static_cast<int32_t>(0x81234567), t.result_rotr_4); CHECK_EQ(static_cast<int32_t>(0x78123456), t.result_rotr_8); @@ -797,7 +796,7 @@ TEST(MIPS9) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label exit, exit2, exit3; __ Branch(&exit, ge, a0, Operand(zero_reg)); @@ -896,7 +895,7 @@ TEST(MIPS10) { t.a = 2.147483647e9; // 0x7fffffff -> 0x41DFFFFFFFC00000 as double. t.b_long_hi = 0x000000ff; // 0xFF00FF00FF -> 0x426FE01FE01FE000 as double. t.b_long_lo = 0x00ff00ff; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(static_cast<int32_t>(0x41DFFFFF), t.dbl_exp); @@ -1031,7 +1030,7 @@ TEST(MIPS11) { t.reg_init = 0xaabbccdd; t.mem_init = 0x11223344; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); if (kArchEndian == kLittle) { @@ -1094,7 +1093,7 @@ TEST(MIPS12) { } T; T t; - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ mov(t2, fp); // Save frame pointer. __ mov(fp, a0); // Access struct T by fp. @@ -1160,7 +1159,7 @@ TEST(MIPS12) { t.y3 = 0XBABA; t.y4 = 0xDEDA; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(3, t.y1); @@ -1183,17 +1182,17 @@ TEST(MIPS13) { } T; T t; - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ sw(a4, MemOperand(a0, offsetof(T, cvt_small_in))); - __ Cvt_d_uw(f10, a4, f4); + __ Cvt_d_uw(f10, a4); __ sdc1(f10, MemOperand(a0, offsetof(T, cvt_small_out))); __ Trunc_uw_d(f10, f10, f4); __ swc1(f10, MemOperand(a0, offsetof(T, trunc_small_out))); __ sw(a4, MemOperand(a0, offsetof(T, cvt_big_in))); - __ Cvt_d_uw(f8, a4, f4); + __ Cvt_d_uw(f8, a4); __ sdc1(f8, MemOperand(a0, offsetof(T, cvt_big_out))); __ Trunc_uw_d(f8, f8, f4); @@ -1211,7 +1210,7 @@ TEST(MIPS13) { t.cvt_big_in = 0xFFFFFFFF; t.cvt_small_in = 333; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(t.cvt_big_out, static_cast<double>(t.cvt_big_in)); @@ -1230,6 +1229,7 @@ TEST(MIPS14) { HandleScope scope(isolate); #define ROUND_STRUCT_ELEMENT(x) \ + uint32_t x##_isNaN2008; \ int32_t x##_up_out; \ int32_t x##_down_out; \ int32_t neg_##x##_up_out; \ @@ -1260,13 +1260,15 @@ TEST(MIPS14) { #undef ROUND_STRUCT_ELEMENT - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); // Save FCSR. __ cfc1(a1, FCSR); // Disable FPU exceptions. __ ctc1(zero_reg, FCSR); #define RUN_ROUND_TEST(x) \ + __ cfc1(t0, FCSR);\ + __ sw(t0, MemOperand(a0, offsetof(T, x##_isNaN2008))); \ __ ldc1(f0, MemOperand(a0, offsetof(T, round_up_in))); \ __ x##_w_d(f0, f0); \ __ swc1(f0, MemOperand(a0, offsetof(T, x##_up_out))); \ @@ -1335,16 +1337,21 @@ TEST(MIPS14) { t.err3_in = static_cast<double>(1) + 0xFFFFFFFF; t.err4_in = NAN; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); #define GET_FPU_ERR(x) (static_cast<int>(x & kFCSRFlagMask)) +#define CHECK_NAN2008(x) (x & kFCSRNaN2008FlagMask) #define CHECK_ROUND_RESULT(type) \ CHECK(GET_FPU_ERR(t.type##_err1_out) & kFCSRInexactFlagMask); \ CHECK_EQ(0, GET_FPU_ERR(t.type##_err2_out)); \ CHECK(GET_FPU_ERR(t.type##_err3_out) & kFCSRInvalidOpFlagMask); \ CHECK(GET_FPU_ERR(t.type##_err4_out) & kFCSRInvalidOpFlagMask); \ - CHECK_EQ(static_cast<int32_t>(kFPUInvalidResult), t.type##_invalid_result); + if (CHECK_NAN2008(t.type##_isNaN2008) && kArchVariant == kMips64r6) { \ + CHECK_EQ(static_cast<int32_t>(0), t.type##_invalid_result);\ + } else { \ + CHECK_EQ(static_cast<int32_t>(kFPUInvalidResult), t.type##_invalid_result);\ + } CHECK_ROUND_RESULT(round); CHECK_ROUND_RESULT(floor); @@ -1453,7 +1460,7 @@ TEST(MIPS16) { t.r4 = 0x4444444444444444; t.r5 = 0x5555555555555555; t.r6 = 0x6666666666666666; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); // Unsigned data, 32 & 64. @@ -1476,7 +1483,8 @@ TEST(seleqz_selnez) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test { int a; @@ -1525,7 +1533,7 @@ TEST(seleqz_selnez) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, 1); CHECK_EQ(test.b, 0); @@ -1553,7 +1561,7 @@ TEST(seleqz_selnez) { test.f = tests_D[j]; test.i = inputs_S[i]; test.j = tests_S[j]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.g, outputs_D[i]); CHECK_EQ(test.h, 0); CHECK_EQ(test.k, outputs_S[i]); @@ -1561,7 +1569,7 @@ TEST(seleqz_selnez) { test.f = tests_D[j+1]; test.j = tests_S[j+1]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.g, 0); CHECK_EQ(test.h, outputs_D[i]); CHECK_EQ(test.k, 0); @@ -1578,7 +1586,8 @@ TEST(min_max) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double a; @@ -1631,7 +1640,7 @@ TEST(min_max) { test.e = inputse[i]; test.f = inputsf[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); if (i < kTableLength - 1) { CHECK_EQ(test.c, outputsdmin[i]); @@ -1639,10 +1648,10 @@ TEST(min_max) { CHECK_EQ(test.g, outputsfmin[i]); CHECK_EQ(test.h, outputsfmax[i]); } else { - DCHECK(std::isnan(test.c)); - DCHECK(std::isnan(test.d)); - DCHECK(std::isnan(test.g)); - DCHECK(std::isnan(test.h)); + CHECK(std::isnan(test.c)); + CHECK(std::isnan(test.d)); + CHECK(std::isnan(test.g)); + CHECK(std::isnan(test.h)); } } } @@ -1655,7 +1664,8 @@ TEST(rint_d) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double a; @@ -1745,7 +1755,7 @@ TEST(rint_d) { test.fcsr = fcsr_inputs[j]; for (int i = 0; i < kTableLength; i++) { test.a = inputs[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs[j][i]); } } @@ -1758,7 +1768,8 @@ TEST(sel) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test { double dd; @@ -1811,13 +1822,13 @@ TEST(sel) { test.ft = inputs_ft[i]; test.fd = tests_S[j]; test.fs = inputs_fs[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dd, inputs_ds[i]); CHECK_EQ(test.fd, inputs_fs[i]); test.dd = tests_D[j+1]; test.fd = tests_S[j+1]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dd, inputs_dt[i]); CHECK_EQ(test.fd, inputs_ft[i]); } @@ -1832,7 +1843,8 @@ TEST(rint_s) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test_float { float a; @@ -1924,7 +1936,7 @@ TEST(rint_s) { test.fcsr = fcsr_inputs[j]; for (int i = 0; i < kTableLength; i++) { test.a = inputs[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs[j][i]); } } @@ -1938,7 +1950,8 @@ TEST(mina_maxa) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); const double double_nan = std::numeric_limits<double>::quiet_NaN(); const float float_nan = std::numeric_limits<float>::quiet_NaN(); @@ -2012,7 +2025,7 @@ TEST(mina_maxa) { test.b = inputsb[i]; test.c = inputsc[i]; test.d = inputsd[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); if (i < kTableLength - 1) { CHECK_EQ(test.resd, resd[i]); @@ -2020,10 +2033,10 @@ TEST(mina_maxa) { 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)); + CHECK(std::isnan(test.resd)); + CHECK(std::isnan(test.resf)); + CHECK(std::isnan(test.resd1)); + CHECK(std::isnan(test.resf1)); } } } @@ -2037,9 +2050,11 @@ TEST(trunc_l) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int64_t c; // a trunc result @@ -2065,7 +2080,14 @@ TEST(trunc_l) { -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, 2147483648.0, dFPU64InvalidResult, dFPU64InvalidResult}; + double outputsNaN2008[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, + dFPU64InvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ trunc_l_d(f8, f4); @@ -2083,8 +2105,13 @@ TEST(trunc_l) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && + kArchVariant == kMips64r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -2097,7 +2124,8 @@ TEST(movz_movn) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test_float { int64_t rt; @@ -2160,14 +2188,14 @@ TEST(movz_movn) { test.c = inputs_S[i]; test.rt = 1; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, test.bold); CHECK_EQ(test.d, test.dold); CHECK_EQ(test.b1, outputs_D[i]); CHECK_EQ(test.d1, outputs_S[i]); test.rt = 0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs_D[i]); CHECK_EQ(test.d, outputs_S[i]); CHECK_EQ(test.b1, test.bold1); @@ -2225,7 +2253,8 @@ TEST(movt_movd) { test.fcsr = 1 << (24+condition_flags[j]); } HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, srcd)) ); __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, srcf)) ); __ lw(t1, MemOperand(a0, offsetof(TestFloat, fcsr)) ); @@ -2256,13 +2285,13 @@ TEST(movt_movd) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dstf, outputs_S[i]); CHECK_EQ(test.dstd, outputs_D[i]); CHECK_EQ(test.dstf1, test.dstfold1); CHECK_EQ(test.dstd1, test.dstdold1); test.fcsr = 0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dstf, test.dstfold); CHECK_EQ(test.dstd, test.dstdold); CHECK_EQ(test.dstf1, outputs_S[i]); @@ -2279,7 +2308,7 @@ TEST(cvt_w_d) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double a; @@ -2345,7 +2374,7 @@ TEST(cvt_w_d) { test.fcsr = fcsr_inputs[j]; for (int i = 0; i < kTableLength; i++) { test.a = inputs[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs[j][i]); } } @@ -2356,9 +2385,10 @@ TEST(trunc_w) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int32_t c; // a trunc result @@ -2384,7 +2414,15 @@ TEST(trunc_w) { -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, kFPUInvalidResult, kFPUInvalidResult, kFPUInvalidResult}; + double outputsNaN2008[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, + 0, + kFPUInvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ trunc_w_d(f8, f4); @@ -2402,8 +2440,12 @@ TEST(trunc_w) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips64r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -2413,9 +2455,10 @@ TEST(round_w) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int32_t c; // a trunc result @@ -2441,7 +2484,14 @@ TEST(round_w) { -2.0, -3.0, -2.0, -3.0, -4.0, -4.0, kFPUInvalidResult, kFPUInvalidResult, kFPUInvalidResult}; + double outputsNaN2008[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, 0, + kFPUInvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ round_w_d(f8, f4); @@ -2459,8 +2509,12 @@ TEST(round_w) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips64r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -2470,9 +2524,11 @@ TEST(round_l) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int64_t c; @@ -2498,7 +2554,15 @@ TEST(round_l) { -2.0, -3.0, -2.0, -3.0, -4.0, -4.0, 2147483648.0, dFPU64InvalidResult, dFPU64InvalidResult}; + double outputsNaN2008[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, + 0, + dFPU64InvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ round_l_d(f8, f4); @@ -2516,9 +2580,13 @@ TEST(round_l) { for (int i = 0; i < kTableLength; i++) { test.a = inputs_D[i]; test.b = inputs_S[i]; - std::cout<< i<< "\n"; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && + kArchVariant == kMips64r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -2529,7 +2597,7 @@ TEST(sub) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { float a; @@ -2586,7 +2654,7 @@ TEST(sub) { test.b = inputft_S[i]; test.c = inputfs_D[i]; test.d = inputft_D[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.resultS, outputs_S[i]); CHECK_EQ(test.resultD, outputs_D[i]); } @@ -2602,7 +2670,7 @@ TEST(sqrt_rsqrt_recip) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { float a; @@ -2661,7 +2729,7 @@ TEST(sqrt_rsqrt_recip) { test.a = inputs_S[i]; test.c = inputs_D[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.resultS, outputs_S[i]); CHECK_EQ(test.resultD, outputs_D[i]); @@ -2694,7 +2762,7 @@ TEST(neg) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { float a; @@ -2735,7 +2803,7 @@ TEST(neg) { 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)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.resultS, outputs_S[i]); CHECK_EQ(test.resultD, outputs_D[i]); } @@ -2748,7 +2816,7 @@ TEST(mul) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { float a; @@ -2795,7 +2863,7 @@ TEST(mul) { test.b = inputft_S[i]; test.c = inputfs_D[i]; test.d = inputft_D[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.resultS, inputfs_S[i]*inputft_S[i]); CHECK_EQ(test.resultD, inputfs_D[i]*inputft_D[i]); } @@ -2807,7 +2875,7 @@ TEST(mov) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double a; @@ -2849,7 +2917,7 @@ TEST(mov) { test.a = inputs_D[i]; test.c = inputs_S[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.b, outputs_D[i]); CHECK_EQ(test.d, outputs_S[i]); } @@ -2860,9 +2928,10 @@ TEST(floor_w) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int32_t c; // a floor result @@ -2888,7 +2957,15 @@ TEST(floor_w) { -3.0, -3.0, -3.0, -4.0, -4.0, -4.0, kFPUInvalidResult, kFPUInvalidResult, kFPUInvalidResult}; + double outputsNaN2008[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, + 0, + kFPUInvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ floor_w_d(f8, f4); @@ -2906,8 +2983,12 @@ TEST(floor_w) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips64r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -2917,9 +2998,11 @@ TEST(floor_l) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int64_t c; @@ -2945,7 +3028,15 @@ TEST(floor_l) { -3.0, -3.0, -3.0, -4.0, -4.0, -4.0, 2147483648.0, dFPU64InvalidResult, dFPU64InvalidResult}; + double outputsNaN2008[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, + 0, + dFPU64InvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ floor_l_d(f8, f4); @@ -2963,8 +3054,13 @@ TEST(floor_l) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && + kArchVariant == kMips64r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -2974,9 +3070,10 @@ TEST(ceil_w) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int32_t c; // a floor result @@ -3002,7 +3099,15 @@ TEST(ceil_w) { -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, kFPUInvalidResult, kFPUInvalidResult, kFPUInvalidResult}; + double outputsNaN2008[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, + 0, + kFPUInvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ ceil_w_d(f8, f4); @@ -3020,8 +3125,12 @@ TEST(ceil_w) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && kArchVariant == kMips64r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -3031,9 +3140,11 @@ TEST(ceil_l) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult); typedef struct test_float { + uint32_t isNaN2008; double a; float b; int64_t c; @@ -3059,7 +3170,15 @@ TEST(ceil_l) { -2.0, -2.0, -2.0, -3.0, -3.0, -3.0, 2147483648.0, dFPU64InvalidResult, dFPU64InvalidResult}; + double outputsNaN2008[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, + 0, + dFPU64InvalidResult}; + __ cfc1(t1, FCSR); + __ sw(t1, MemOperand(a0, offsetof(Test, isNaN2008))); __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) ); __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) ); __ ceil_l_d(f8, f4); @@ -3077,8 +3196,13 @@ TEST(ceil_l) { 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)); - CHECK_EQ(test.c, outputs[i]); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); + if ((test.isNaN2008 & kFCSRNaN2008FlagMask) && + kArchVariant == kMips64r6) { + CHECK_EQ(test.c, outputsNaN2008[i]); + } else { + CHECK_EQ(test.c, outputs[i]); + } CHECK_EQ(test.d, test.c); } } @@ -3098,23 +3222,20 @@ TEST(jump_tables1) { __ daddiu(sp, sp, -8); __ sd(ra, MemOperand(sp)); - if ((assm.pc_offset() & 7) == 0) { - __ nop(); - } + __ Align(8); Label done; { - __ BlockTrampolinePoolFor(kNumCases * 2 + 7); + __ BlockTrampolinePoolFor(kNumCases * 2 + 6); PredictableCodeSizeScope predictable( - &assm, (kNumCases * 2 + 7) * Assembler::kInstrSize); + &assm, (kNumCases * 2 + 6) * Assembler::kInstrSize); Label here; __ bal(&here); - __ nop(); + __ dsll(at, a0, 3); // In delay slot. __ bind(&here); - __ dsll(at, a0, 3); __ daddu(at, at, ra); - __ ld(at, MemOperand(at, 5 * Assembler::kInstrSize)); + __ ld(at, MemOperand(at, 4 * Assembler::kInstrSize)); __ jr(at); __ nop(); for (int i = 0; i < kNumCases; ++i) { @@ -3146,7 +3267,7 @@ TEST(jump_tables1) { F1 f = FUNCTION_CAST<F1>(code->entry()); for (int i = 0; i < kNumCases; ++i) { int64_t res = reinterpret_cast<int64_t>( - CALL_GENERATED_CODE(f, i, 0, 0, 0, 0)); + CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0)); ::printf("f(%d) = %" PRId64 "\n", i, res); CHECK_EQ(values[i], static_cast<int>(res)); } @@ -3180,22 +3301,19 @@ TEST(jump_tables2) { __ nop(); } - if ((assm.pc_offset() & 7) == 0) { - __ nop(); - } + __ Align(8); __ bind(&dispatch); { - __ BlockTrampolinePoolFor(kNumCases * 2 + 7); + __ BlockTrampolinePoolFor(kNumCases * 2 + 6); PredictableCodeSizeScope predictable( - &assm, (kNumCases * 2 + 7) * Assembler::kInstrSize); + &assm, (kNumCases * 2 + 6) * Assembler::kInstrSize); Label here; __ bal(&here); - __ nop(); + __ dsll(at, a0, 3); // In delay slot. __ bind(&here); - __ dsll(at, a0, 3); __ daddu(at, at, ra); - __ ld(at, MemOperand(at, 5 * Assembler::kInstrSize)); + __ ld(at, MemOperand(at, 4 * Assembler::kInstrSize)); __ jr(at); __ nop(); for (int i = 0; i < kNumCases; ++i) { @@ -3219,7 +3337,7 @@ TEST(jump_tables2) { F1 f = FUNCTION_CAST<F1>(code->entry()); for (int i = 0; i < kNumCases; ++i) { int64_t res = reinterpret_cast<int64_t>( - CALL_GENERATED_CODE(f, i, 0, 0, 0, 0)); + CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0)); ::printf("f(%d) = %" PRId64 "\n", i, res); CHECK_EQ(values[i], res); } @@ -3248,6 +3366,7 @@ TEST(jump_tables3) { Label done, dispatch; __ b(&dispatch); + __ nop(); for (int i = 0; i < kNumCases; ++i) { @@ -3262,23 +3381,19 @@ TEST(jump_tables3) { __ nop(); } - __ stop("chk"); - if ((assm.pc_offset() & 7) == 0) { - __ nop(); - } + __ Align(8); __ bind(&dispatch); { - __ BlockTrampolinePoolFor(kNumCases * 2 + 7); + __ BlockTrampolinePoolFor(kNumCases * 2 + 6); PredictableCodeSizeScope predictable( - &assm, (kNumCases * 2 + 7) * Assembler::kInstrSize); + &assm, (kNumCases * 2 + 6) * Assembler::kInstrSize); Label here; __ bal(&here); - __ nop(); + __ dsll(at, a0, 3); // In delay slot. __ bind(&here); - __ dsll(at, a0, 3); __ daddu(at, at, ra); - __ ld(at, MemOperand(at, 5 * Assembler::kInstrSize)); + __ ld(at, MemOperand(at, 4 * Assembler::kInstrSize)); __ jr(at); __ nop(); for (int i = 0; i < kNumCases; ++i) { @@ -3301,7 +3416,8 @@ TEST(jump_tables3) { #endif F1 f = FUNCTION_CAST<F1>(code->entry()); for (int i = 0; i < kNumCases; ++i) { - Handle<Object> result(CALL_GENERATED_CODE(f, i, 0, 0, 0, 0), isolate); + Handle<Object> result( + CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0), isolate); #ifdef OBJECT_PRINT ::printf("f(%d) = ", i); result->Print(std::cout); @@ -3375,7 +3491,7 @@ TEST(BITSWAP) { t.r4 = 0xFF8017FF8B71FCDE; t.r5 = 0x10C021098B71FCDE; t.r6 = 0xFB8017FF781A15C3; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(static_cast<int64_t>(0x000000001E58A8C3L), t.r1); @@ -3420,7 +3536,8 @@ TEST(class_fmt) { // Create a function that accepts &t, and loads, manipulates, and stores // the doubles t.a ... t.f. - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); __ ldc1(f4, MemOperand(a0, offsetof(T, dSignalingNan))); __ class_d(f6, f4); @@ -3536,7 +3653,7 @@ TEST(class_fmt) { t.fPosSubnorm = FLT_MIN / 20.0; t.fPosZero = +0.0; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); // Expected double results. CHECK_EQ(bit_cast<int64_t>(t.dSignalingNan), 0x001); @@ -3569,7 +3686,7 @@ TEST(ABS) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { int64_t fir; @@ -3607,34 +3724,34 @@ TEST(ABS) { F3 f = FUNCTION_CAST<F3>(code->entry()); test.a = -2.0; test.b = -2.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, 2.0); CHECK_EQ(test.b, 2.0); test.a = 2.0; test.b = 2.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, 2.0); CHECK_EQ(test.b, 2.0); // Testing biggest positive number test.a = std::numeric_limits<double>::max(); test.b = std::numeric_limits<float>::max(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, std::numeric_limits<double>::max()); CHECK_EQ(test.b, std::numeric_limits<float>::max()); // Testing smallest negative number test.a = -std::numeric_limits<double>::max(); // lowest() test.b = -std::numeric_limits<float>::max(); // lowest() - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, std::numeric_limits<double>::max()); CHECK_EQ(test.b, std::numeric_limits<float>::max()); // Testing smallest positive number test.a = -std::numeric_limits<double>::min(); test.b = -std::numeric_limits<float>::min(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, std::numeric_limits<double>::min()); CHECK_EQ(test.b, std::numeric_limits<float>::min()); @@ -3643,7 +3760,7 @@ TEST(ABS) { / std::numeric_limits<double>::min(); test.b = -std::numeric_limits<float>::max() / std::numeric_limits<float>::min(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.a, std::numeric_limits<double>::max() / std::numeric_limits<double>::min()); CHECK_EQ(test.b, std::numeric_limits<float>::max() @@ -3651,13 +3768,13 @@ TEST(ABS) { test.a = std::numeric_limits<double>::quiet_NaN(); test.b = std::numeric_limits<float>::quiet_NaN(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(std::isnan(test.a), true); CHECK_EQ(std::isnan(test.b), true); test.a = std::numeric_limits<double>::signaling_NaN(); test.b = std::numeric_limits<float>::signaling_NaN(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(std::isnan(test.a), true); CHECK_EQ(std::isnan(test.b), true); } @@ -3667,7 +3784,7 @@ TEST(ADD_FMT) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double a; @@ -3702,7 +3819,7 @@ TEST(ADD_FMT) { test.b = 3.0; test.fa = 2.0; test.fb = 3.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.c, 5.0); CHECK_EQ(test.fc, 5.0); @@ -3710,7 +3827,7 @@ TEST(ADD_FMT) { test.b = -std::numeric_limits<double>::max(); // lowest() test.fa = std::numeric_limits<float>::max(); test.fb = -std::numeric_limits<float>::max(); // lowest() - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.c, 0.0); CHECK_EQ(test.fc, 0.0); @@ -3718,7 +3835,7 @@ TEST(ADD_FMT) { test.b = std::numeric_limits<double>::max(); test.fa = std::numeric_limits<float>::max(); test.fb = std::numeric_limits<float>::max(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(std::isfinite(test.c), false); CHECK_EQ(std::isfinite(test.fc), false); @@ -3726,7 +3843,7 @@ TEST(ADD_FMT) { test.b = std::numeric_limits<double>::signaling_NaN(); test.fa = 5.0; test.fb = std::numeric_limits<float>::signaling_NaN(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(std::isnan(test.c), true); CHECK_EQ(std::isnan(test.fc), true); } @@ -3737,7 +3854,8 @@ TEST(C_COND_FMT) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double dOp1; @@ -3856,7 +3974,7 @@ TEST(C_COND_FMT) { test.dOp2 = 3.0; test.fOp1 = 2.0; test.fOp2 = 3.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dF, 0U); CHECK_EQ(test.dUn, 0U); CHECK_EQ(test.dEq, 0U); @@ -3878,7 +3996,7 @@ TEST(C_COND_FMT) { test.dOp2 = std::numeric_limits<double>::min(); test.fOp1 = std::numeric_limits<float>::min(); test.fOp2 = -std::numeric_limits<float>::max(); // lowest() - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dF, 0U); CHECK_EQ(test.dUn, 0U); CHECK_EQ(test.dEq, 0U); @@ -3900,7 +4018,7 @@ TEST(C_COND_FMT) { test.dOp2 = -std::numeric_limits<double>::max(); // lowest() test.fOp1 = std::numeric_limits<float>::max(); test.fOp2 = std::numeric_limits<float>::max(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dF, 0U); CHECK_EQ(test.dUn, 0U); CHECK_EQ(test.dEq, 1U); @@ -3922,7 +4040,7 @@ TEST(C_COND_FMT) { test.dOp2 = 0.0; test.fOp1 = std::numeric_limits<float>::quiet_NaN(); test.fOp2 = 0.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dF, 0U); CHECK_EQ(test.dUn, 1U); CHECK_EQ(test.dEq, 0U); @@ -3948,7 +4066,8 @@ TEST(CMP_COND_FMT) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); typedef struct test_float { double dOp1; @@ -4061,7 +4180,7 @@ TEST(CMP_COND_FMT) { test.dOp2 = 3.0; test.fOp1 = 2.0; test.fOp2 = 3.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse); @@ -4086,7 +4205,7 @@ TEST(CMP_COND_FMT) { test.dOp2 = std::numeric_limits<double>::min(); test.fOp1 = std::numeric_limits<float>::min(); test.fOp2 = -std::numeric_limits<float>::max(); // lowest() - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse); @@ -4111,7 +4230,7 @@ TEST(CMP_COND_FMT) { test.dOp2 = -std::numeric_limits<double>::max(); // lowest() test.fOp1 = std::numeric_limits<float>::max(); test.fOp2 = std::numeric_limits<float>::max(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dEq), dTrue); @@ -4136,7 +4255,7 @@ TEST(CMP_COND_FMT) { test.dOp2 = 0.0; test.fOp1 = std::numeric_limits<float>::quiet_NaN(); test.fOp2 = 0.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse); CHECK_EQ(bit_cast<uint64_t>(test.dUn), dTrue); CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse); @@ -4164,7 +4283,7 @@ TEST(CVT) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test_float { float cvt_d_s_in; @@ -4242,7 +4361,7 @@ TEST(CVT) { test.cvt_w_s_in = -0.51; test.cvt_w_d_in = -0.51; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); @@ -4266,7 +4385,7 @@ TEST(CVT) { test.cvt_w_s_in = 0.49; test.cvt_w_d_in = 0.49; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); @@ -4289,7 +4408,7 @@ TEST(CVT) { test.cvt_w_s_in = std::numeric_limits<float>::max(); test.cvt_w_d_in = std::numeric_limits<double>::max(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); @@ -4313,7 +4432,7 @@ TEST(CVT) { test.cvt_w_s_in = -std::numeric_limits<float>::max(); // lowest() test.cvt_w_d_in = -std::numeric_limits<double>::max(); // lowest() - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); @@ -4344,7 +4463,7 @@ TEST(CVT) { test.cvt_w_s_in = std::numeric_limits<float>::min(); test.cvt_w_d_in = std::numeric_limits<double>::min(); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in)); CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in)); CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in)); @@ -4362,7 +4481,7 @@ TEST(DIV_FMT) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); typedef struct test { double dOp1; @@ -4403,7 +4522,7 @@ TEST(DIV_FMT) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F3 f = FUNCTION_CAST<F3>(code->entry()); - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); const int test_size = 3; @@ -4444,7 +4563,7 @@ TEST(DIV_FMT) { test.fOp1 = fOp1[i]; test.fOp2 = fOp2[i]; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(test.dRes, dRes[i]); CHECK_EQ(test.fRes, fRes[i]); } @@ -4454,7 +4573,7 @@ TEST(DIV_FMT) { test.fOp1 = FLT_MAX; test.fOp2 = -0.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(false, std::isfinite(test.dRes)); CHECK_EQ(false, std::isfinite(test.fRes)); @@ -4463,7 +4582,7 @@ TEST(DIV_FMT) { test.fOp1 = 0.0; test.fOp2 = -0.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(true, std::isnan(test.dRes)); CHECK_EQ(true, std::isnan(test.fRes)); @@ -4472,7 +4591,7 @@ TEST(DIV_FMT) { test.fOp1 = std::numeric_limits<float>::quiet_NaN(); test.fOp2 = -5.0; - (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0)); + (CALL_GENERATED_CODE(isolate, f, &test, 0, 0, 0, 0)); CHECK_EQ(true, std::isnan(test.dRes)); CHECK_EQ(true, std::isnan(test.fRes)); } @@ -4482,7 +4601,7 @@ uint64_t run_align(uint64_t rs_value, uint64_t rt_value, uint8_t bp) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ align(v0, a0, a1, bp); __ jr(ra); @@ -4493,12 +4612,10 @@ uint64_t run_align(uint64_t rs_value, uint64_t rt_value, uint8_t bp) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); - F2 f = FUNCTION_CAST<F2>(code->entry()); + F4 f = FUNCTION_CAST<F4>(code->entry()); - uint64_t res = - reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs_value, - rt_value, - 0, 0, 0)); + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, rs_value, rt_value, 0, 0, 0)); return res; } @@ -4537,7 +4654,7 @@ uint64_t run_dalign(uint64_t rs_value, uint64_t rt_value, uint8_t bp) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ dalign(v0, a0, a1, bp); __ jr(ra); @@ -4549,10 +4666,8 @@ uint64_t run_dalign(uint64_t rs_value, uint64_t rt_value, uint8_t bp) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F4 f = FUNCTION_CAST<F4>(code->entry()); - uint64_t res = - reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs_value, - rt_value, - 0, 0, 0)); + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, rs_value, rt_value, 0, 0, 0)); return res; } @@ -4597,7 +4712,7 @@ uint64_t run_aluipc(int16_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ aluipc(v0, offset); __ jr(ra); @@ -4611,8 +4726,8 @@ uint64_t run_aluipc(int16_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); PC = (uint64_t) f; // Set the program counter. - uint64_t res = - reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -4651,7 +4766,7 @@ uint64_t run_auipc(int16_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ auipc(v0, offset); __ jr(ra); @@ -4665,8 +4780,8 @@ uint64_t run_auipc(int16_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); PC = (uint64_t) f; // Set the program counter. - uint64_t res = - reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -4701,11 +4816,192 @@ TEST(r6_auipc) { } +uint64_t run_aui(uint64_t rs, uint16_t offset) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); + + __ li(t0, rs); + __ aui(v0, t0, offset); + __ 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(isolate, f, 0, 0, 0, 0, 0)); + + return res; +} + + +uint64_t run_daui(uint64_t rs, uint16_t offset) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); + + __ li(t0, rs); + __ daui(v0, t0, offset); + __ 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(isolate, f, 0, 0, 0, 0, 0)); + + return res; +} + + +uint64_t run_dahi(uint64_t rs, uint16_t offset) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); + + __ li(v0, rs); + __ dahi(v0, offset); + __ 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(isolate, f, 0, 0, 0, 0, 0)); + + return res; +} + + +uint64_t run_dati(uint64_t rs, uint16_t offset) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); + + __ li(v0, rs); + __ dati(v0, offset); + __ 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(isolate, f, 0, 0, 0, 0, 0)); + + return res; +} + + +TEST(r6_aui_family) { + if (kArchVariant == kMips64r6) { + CcTest::InitializeVM(); + + struct TestCaseAui { + uint64_t rs; + uint16_t offset; + uint64_t ref_res; + }; + + // AUI test cases. + struct TestCaseAui aui_tc[] = { + {0xfffeffff, 0x1, 0xffffffffffffffff}, + {0xffffffff, 0x0, 0xffffffffffffffff}, + {0, 0xffff, 0xffffffffffff0000}, + {0x0008ffff, 0xfff7, 0xffffffffffffffff}, + {32767, 32767, 0x000000007fff7fff}, + {0x00000000ffffffff, 0x1, 0x000000000000ffff}, + {0xffffffff, 0xffff, 0xfffffffffffeffff}, + }; + + size_t nr_test_cases = sizeof(aui_tc) / sizeof(TestCaseAui); + for (size_t i = 0; i < nr_test_cases; ++i) { + uint64_t res = run_aui(aui_tc[i].rs, aui_tc[i].offset); + CHECK_EQ(aui_tc[i].ref_res, res); + } + + // DAUI test cases. + struct TestCaseAui daui_tc[] = { + {0xfffffffffffeffff, 0x1, 0xffffffffffffffff}, + {0xffffffffffffffff, 0x0, 0xffffffffffffffff}, + {0, 0xffff, 0xffffffffffff0000}, + {0x0008ffff, 0xfff7, 0xffffffffffffffff}, + {32767, 32767, 0x000000007fff7fff}, + {0x00000000ffffffff, 0x1, 0x000000010000ffff}, + {0xffffffff, 0xffff, 0x00000000fffeffff}, + }; + + nr_test_cases = sizeof(daui_tc) / sizeof(TestCaseAui); + for (size_t i = 0; i < nr_test_cases; ++i) { + uint64_t res = run_daui(daui_tc[i].rs, daui_tc[i].offset); + CHECK_EQ(daui_tc[i].ref_res, res); + } + + // DATI test cases. + struct TestCaseAui dati_tc[] = { + {0xfffffffffffeffff, 0x1, 0x0000fffffffeffff}, + {0xffffffffffffffff, 0x0, 0xffffffffffffffff}, + {0, 0xffff, 0xffff000000000000}, + {0x0008ffff, 0xfff7, 0xfff700000008ffff}, + {32767, 32767, 0x7fff000000007fff}, + {0x00000000ffffffff, 0x1, 0x00010000ffffffff}, + {0xffffffffffff, 0xffff, 0xffffffffffffffff}, + }; + + nr_test_cases = sizeof(dati_tc) / sizeof(TestCaseAui); + for (size_t i = 0; i < nr_test_cases; ++i) { + uint64_t res = run_dati(dati_tc[i].rs, dati_tc[i].offset); + CHECK_EQ(dati_tc[i].ref_res, res); + } + + // DAHI test cases. + struct TestCaseAui dahi_tc[] = { + {0xfffffffeffffffff, 0x1, 0xffffffffffffffff}, + {0xffffffffffffffff, 0x0, 0xffffffffffffffff}, + {0, 0xffff, 0xffffffff00000000}, + }; + + nr_test_cases = sizeof(dahi_tc) / sizeof(TestCaseAui); + for (size_t i = 0; i < nr_test_cases; ++i) { + uint64_t res = run_dahi(dahi_tc[i].rs, dahi_tc[i].offset); + CHECK_EQ(dahi_tc[i].ref_res, res); + } + } +} + + uint64_t run_lwpc(int offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); // 256k instructions; 2^8k // addiu t3, a4, 0xffff; (0x250fffff) @@ -4740,8 +5036,8 @@ uint64_t run_lwpc(int offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - uint64_t res = - reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -4781,7 +5077,7 @@ uint64_t run_lwupc(int offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); // 256k instructions; 2^8k // addiu t3, a4, 0xffff; (0x250fffff) @@ -4816,8 +5112,8 @@ uint64_t run_lwupc(int offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - uint64_t res = - reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -4857,7 +5153,7 @@ uint64_t run_jic(int16_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label get_program_counter, stop_execution; __ push(ra); @@ -4900,8 +5196,8 @@ uint64_t run_jic(int16_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - uint64_t res = - reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -4938,7 +5234,7 @@ uint64_t run_beqzc(int32_t value, int32_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label stop_execution; __ li(v0, 0); @@ -4972,8 +5268,8 @@ uint64_t run_beqzc(int32_t value, int32_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - uint64_t res = - reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, value, 0, 0, 0, 0)); + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, value, 0, 0, 0, 0)); return res; } @@ -5011,7 +5307,7 @@ uint64_t run_jialc(int16_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label main_block, get_program_counter; __ push(ra); @@ -5066,8 +5362,8 @@ uint64_t run_jialc(int16_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - uint64_t res = - reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -5105,7 +5401,7 @@ uint64_t run_addiupc(int32_t imm19) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ addiupc(v0, imm19); __ jr(ra); @@ -5119,8 +5415,8 @@ uint64_t run_addiupc(int32_t imm19) { F2 f = FUNCTION_CAST<F2>(code->entry()); PC = (uint64_t) f; // Set the program counter. - uint64_t res = - reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -5159,7 +5455,7 @@ uint64_t run_ldpc(int offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); // 256k instructions; 2 * 2^7k = 2^8k // addiu t3, a4, 0xffff; (0x250fffff) @@ -5194,8 +5490,8 @@ uint64_t run_ldpc(int offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - uint64_t res = - reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -5234,7 +5530,7 @@ int64_t run_bc(int32_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label continue_1, stop_execution; __ push(ra); @@ -5242,9 +5538,8 @@ int64_t run_bc(int32_t offset) { __ li(t8, 0); __ li(t9, 2); // Condition for the stopping execution. - uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1 for (int32_t i = -100; i <= -11; ++i) { - __ dd(instruction_addiu); + __ addiu(v0, v0, 1); } __ addiu(t8, t8, 1); // -10 @@ -5263,7 +5558,7 @@ int64_t run_bc(int32_t offset) { __ bc(offset); // -1 for (int32_t i = 0; i <= 99; ++i) { - __ dd(instruction_addiu); + __ addiu(v0, v0, 1); } __ pop(ra); @@ -5277,8 +5572,8 @@ int64_t run_bc(int32_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - int64_t res = - reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + int64_t res = reinterpret_cast<int64_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -5315,7 +5610,7 @@ int64_t run_balc(int32_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); Label continue_1, stop_execution; __ push(ra); @@ -5359,8 +5654,8 @@ int64_t run_balc(int32_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - int64_t res = - reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + int64_t res = reinterpret_cast<int64_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -5396,7 +5691,7 @@ 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); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ dsll(v0, a0, sa_value); __ jr(ra); @@ -5407,10 +5702,10 @@ uint64_t run_dsll(uint64_t rt_value, uint16_t sa_value) { Handle<Code> code = isolate->factory()->NewCode( desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); - F2 f = FUNCTION_CAST<F2>(code->entry()); + F4 f = FUNCTION_CAST<F4>(code->entry()); - uint64_t res = - reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rt_value, 0, 0, 0, 0)); + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, rt_value, 0, 0, 0, 0)); return res; } @@ -5444,7 +5739,7 @@ uint64_t run_bal(int16_t offset) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, NULL, 0); + MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); __ mov(t0, ra); __ bal(offset); // Equivalent for "BGEZAL zero_reg, offset". @@ -5465,8 +5760,8 @@ uint64_t run_bal(int16_t offset) { F2 f = FUNCTION_CAST<F2>(code->entry()); - uint64_t res = - reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); return res; } @@ -5500,7 +5795,8 @@ TEST(Trampoline) { Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assm(isolate, nullptr, 0); + MacroAssembler assm(isolate, nullptr, 0, + v8::internal::CodeObjectRequired::kYes); Label done; size_t nr_calls = kMaxBranchOffset / (2 * Instruction::kInstrSize) + 2; @@ -5517,8 +5813,8 @@ TEST(Trampoline) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); F2 f = FUNCTION_CAST<F2>(code->entry()); - int64_t res = - reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 42, 42, 0, 0, 0)); + int64_t res = reinterpret_cast<int64_t>( + CALL_GENERATED_CODE(isolate, f, 42, 42, 0, 0, 0)); CHECK_EQ(res, 0); } diff --git a/deps/v8/test/cctest/test-assembler-ppc.cc b/deps/v8/test/cctest/test-assembler-ppc.cc index b2dca6a9fc..d29a59d91d 100644 --- a/deps/v8/test/cctest/test-assembler-ppc.cc +++ b/deps/v8/test/cctest/test-assembler-ppc.cc @@ -48,7 +48,7 @@ typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4); // Simple add parameter 1 to parameter 2 and return TEST(0) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); @@ -66,8 +66,8 @@ TEST(0) { code->Print(); #endif F2 f = FUNCTION_CAST<F2>(code->entry()); - intptr_t res = - reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(f, 3, 4, 0, 0, 0)); + intptr_t res = reinterpret_cast<intptr_t>( + CALL_GENERATED_CODE(isolate, f, 3, 4, 0, 0, 0)); ::printf("f() = %" V8PRIdPTR "\n", res); CHECK_EQ(7, static_cast<int>(res)); } @@ -76,7 +76,7 @@ TEST(0) { // Loop 100 times, adding loop counter to result TEST(1) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); @@ -105,8 +105,8 @@ TEST(1) { code->Print(); #endif F1 f = FUNCTION_CAST<F1>(code->entry()); - intptr_t res = - reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(f, 100, 0, 0, 0, 0)); + intptr_t res = reinterpret_cast<intptr_t>( + CALL_GENERATED_CODE(isolate, f, 100, 0, 0, 0, 0)); ::printf("f() = %" V8PRIdPTR "\n", res); CHECK_EQ(5050, static_cast<int>(res)); } @@ -114,7 +114,7 @@ TEST(1) { TEST(2) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); @@ -156,8 +156,8 @@ TEST(2) { code->Print(); #endif F1 f = FUNCTION_CAST<F1>(code->entry()); - intptr_t res = - reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(f, 10, 0, 0, 0, 0)); + intptr_t res = reinterpret_cast<intptr_t>( + CALL_GENERATED_CODE(isolate, f, 10, 0, 0, 0, 0)); ::printf("f() = %" V8PRIdPTR "\n", res); CHECK_EQ(3628800, static_cast<int>(res)); } @@ -165,7 +165,7 @@ TEST(2) { TEST(3) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -175,7 +175,7 @@ TEST(3) { } T; T t; - Assembler assm(Isolate::Current(), NULL, 0); + Assembler assm(CcTest::i_isolate(), NULL, 0); Label L, C; __ function_descriptor(); @@ -232,8 +232,8 @@ TEST(3) { t.i = 100000; t.c = 10; t.s = 1000; - intptr_t res = - reinterpret_cast<intptr_t>(CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0)); + intptr_t res = reinterpret_cast<intptr_t>( + CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0)); ::printf("f() = %" V8PRIdPTR "\n", res); CHECK_EQ(101010, static_cast<int>(res)); CHECK_EQ(100000 / 2, t.i); @@ -245,7 +245,7 @@ TEST(3) { TEST(4) { // Test the VFP floating point instructions. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -267,7 +267,7 @@ TEST(4) { // Create a function that accepts &t, and loads, manipulates, and stores // the doubles and floats. - Assembler assm(Isolate::Current(), NULL, 0); + Assembler assm(CcTest::i_isolate(), NULL, 0); Label L, C; if (CpuFeatures::IsSupported(VFP3)) { @@ -358,7 +358,7 @@ TEST(4) { t.n = 123.456; t.x = 4.5; t.y = 9.0; - Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); USE(dummy); CHECK_EQ(4.5, t.y); CHECK_EQ(9.0, t.x); @@ -380,7 +380,7 @@ TEST(4) { TEST(5) { // Test the ARMv7 bitfield instructions. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); @@ -407,7 +407,7 @@ TEST(5) { #endif F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry()); int res = reinterpret_cast<int>( - CALL_GENERATED_CODE(f, 0xAAAAAAAA, 0, 0, 0, 0)); + CALL_GENERATED_CODE(isolate, f, 0xAAAAAAAA, 0, 0, 0, 0)); ::printf("f() = %d\n", res); CHECK_EQ(-7, res); } @@ -417,7 +417,7 @@ TEST(5) { TEST(6) { // Test saturating instructions. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); @@ -443,7 +443,7 @@ TEST(6) { #endif F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry()); int res = reinterpret_cast<int>( - CALL_GENERATED_CODE(f, 0xFFFF, 0, 0, 0, 0)); + CALL_GENERATED_CODE(isolate, f, 0xFFFF, 0, 0, 0, 0)); ::printf("f() = %d\n", res); CHECK_EQ(382, res); } @@ -460,7 +460,7 @@ static void TestRoundingMode(VCVTTypes types, int expected, bool expected_exception = false) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); @@ -519,7 +519,7 @@ static void TestRoundingMode(VCVTTypes types, #endif F1 f = FUNCTION_CAST<F1>(Code::cast(code)->entry()); int res = reinterpret_cast<int>( - CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); ::printf("res = %d\n", res); CHECK_EQ(expected, res); } @@ -639,7 +639,7 @@ TEST(7) { TEST(8) { // Test VFP multi load/store with ia_w. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -724,7 +724,7 @@ TEST(8) { f.g = 7.0; f.h = 8.0; - Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, fn, &d, &f, 0, 0, 0); USE(dummy); CHECK_EQ(7.7, d.a); @@ -751,7 +751,7 @@ TEST(8) { TEST(9) { // Test VFP multi load/store with ia. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -840,7 +840,7 @@ TEST(9) { f.g = 7.0; f.h = 8.0; - Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, fn, &d, &f, 0, 0, 0); USE(dummy); CHECK_EQ(7.7, d.a); @@ -867,7 +867,7 @@ TEST(9) { TEST(10) { // Test VFP multi load/store with db_w. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -952,7 +952,7 @@ TEST(10) { f.g = 7.0; f.h = 8.0; - Object* dummy = CALL_GENERATED_CODE(fn, &d, &f, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, fn, &d, &f, 0, 0, 0); USE(dummy); CHECK_EQ(7.7, d.a); @@ -979,7 +979,7 @@ TEST(10) { TEST(11) { // Test instructions using the carry flag. CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); typedef struct { @@ -1032,7 +1032,7 @@ TEST(11) { Code::cast(code)->Print(); #endif F3 f = FUNCTION_CAST<F3>(Code::cast(code)->entry()); - Object* dummy = CALL_GENERATED_CODE(f, &i, 0, 0, 0, 0); + Object* dummy = CALL_GENERATED_CODE(isolate, f, &i, 0, 0, 0, 0); USE(dummy); CHECK_EQ(0xabcd0001, i.a); @@ -1045,7 +1045,7 @@ TEST(11) { TEST(12) { // Test chaining of label usages within instructions (issue 1644). CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); Assembler assm(isolate, NULL, 0); diff --git a/deps/v8/test/cctest/test-assembler-x64.cc b/deps/v8/test/cctest/test-assembler-x64.cc index cc87c4ebf6..66199fb540 100644 --- a/deps/v8/test/cctest/test-assembler-x64.cc +++ b/deps/v8/test/cctest/test-assembler-x64.cc @@ -591,6 +591,7 @@ TEST(AssemblerMultiByteNop) { void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); byte buffer[1024]; CHECK(args[0]->IsArray()); @@ -605,9 +606,15 @@ void DoSSE2(const v8::FunctionCallbackInfo<v8::Value>& args) { // Store input vector on the stack. for (unsigned i = 0; i < ELEMENT_COUNT; i++) { - __ movl(rax, Immediate(vec->Get(i)->Int32Value())); + __ movl(rax, Immediate(vec->Get(context, i) + .ToLocalChecked() + ->Int32Value(context) + .FromJust())); __ shlq(rax, Immediate(0x20)); - __ orq(rax, Immediate(vec->Get(++i)->Int32Value())); + __ orq(rax, Immediate(vec->Get(context, ++i) + .ToLocalChecked() + ->Int32Value(context) + .FromJust())); __ pushq(rax); } @@ -641,7 +648,7 @@ TEST(StackAlignmentForSSE2) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate); global_template->Set(v8_str("do_sse2"), v8::FunctionTemplate::New(isolate, DoSSE2)); @@ -653,20 +660,21 @@ TEST(StackAlignmentForSSE2) { "}"); v8::Local<v8::Object> global_object = env->Global(); - v8::Local<v8::Function> foo = - v8::Local<v8::Function>::Cast(global_object->Get(v8_str("foo"))); + v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( + global_object->Get(env.local(), v8_str("foo")).ToLocalChecked()); int32_t vec[ELEMENT_COUNT] = { -1, 1, 1, 1 }; v8::Local<v8::Array> v8_vec = v8::Array::New(isolate, ELEMENT_COUNT); for (unsigned i = 0; i < ELEMENT_COUNT; i++) { - v8_vec->Set(i, v8_num(vec[i])); + v8_vec->Set(env.local(), i, v8_num(vec[i])).FromJust(); } v8::Local<v8::Value> args[] = { v8_vec }; - v8::Local<v8::Value> result = foo->Call(global_object, 1, args); + v8::Local<v8::Value> result = + foo->Call(env.local(), global_object, 1, args).ToLocalChecked(); // The mask should be 0b1000. - CHECK_EQ(8, result->Int32Value()); + CHECK_EQ(8, result->Int32Value(env.local()).FromJust()); } #undef ELEMENT_COUNT @@ -710,7 +718,8 @@ TEST(AssemblerX64SSE) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[256]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { __ shufps(xmm0, xmm0, 0x0); // brocast first argument __ shufps(xmm1, xmm1, 0x0); // brocast second argument @@ -747,7 +756,8 @@ TEST(AssemblerX64FMA_sd) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[1024]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { CpuFeatureScope fscope(&assm, FMA3); Label exit; @@ -972,7 +982,8 @@ TEST(AssemblerX64FMA_ss) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[1024]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { CpuFeatureScope fscope(&assm, FMA3); Label exit; @@ -1597,7 +1608,8 @@ TEST(AssemblerX64BMI1) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[1024]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { CpuFeatureScope fscope(&assm, BMI1); Label exit; @@ -1786,7 +1798,8 @@ TEST(AssemblerX64LZCNT) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[256]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { CpuFeatureScope fscope(&assm, LZCNT); Label exit; @@ -1845,7 +1858,8 @@ TEST(AssemblerX64POPCNT) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[256]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { CpuFeatureScope fscope(&assm, POPCNT); Label exit; @@ -1904,7 +1918,8 @@ TEST(AssemblerX64BMI2) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[2048]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); { CpuFeatureScope fscope(&assm, BMI2); Label exit; @@ -2164,7 +2179,8 @@ TEST(AssemblerX64JumpTables1) { CcTest::InitializeVM(); Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); - MacroAssembler assm(isolate, nullptr, 0); + MacroAssembler assm(isolate, nullptr, 0, + v8::internal::CodeObjectRequired::kYes); const int kNumCases = 512; int values[kNumCases]; @@ -2211,7 +2227,8 @@ TEST(AssemblerX64JumpTables2) { CcTest::InitializeVM(); Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); - MacroAssembler assm(isolate, nullptr, 0); + MacroAssembler assm(isolate, nullptr, 0, + v8::internal::CodeObjectRequired::kYes); const int kNumCases = 512; int values[kNumCases]; diff --git a/deps/v8/test/cctest/test-assembler-x87.cc b/deps/v8/test/cctest/test-assembler-x87.cc index d6a0d2d461..a831a0b2f1 100644 --- a/deps/v8/test/cctest/test-assembler-x87.cc +++ b/deps/v8/test/cctest/test-assembler-x87.cc @@ -185,7 +185,8 @@ TEST(AssemblerIa329) { Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate()); HandleScope scope(isolate); v8::internal::byte buffer[256]; - MacroAssembler assm(isolate, buffer, sizeof buffer); + MacroAssembler assm(isolate, buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); enum { kEqual = 0, kGreater = 1, kLess = 2, kNaN = 3, kUndefined = 4 }; Label equal_l, less_l, greater_l, nan_l; __ fld_d(Operand(esp, 3 * kPointerSize)); diff --git a/deps/v8/test/cctest/test-ast-expression-visitor.cc b/deps/v8/test/cctest/test-ast-expression-visitor.cc index b95905e32e..b6cca6ac38 100644 --- a/deps/v8/test/cctest/test-ast-expression-visitor.cc +++ b/deps/v8/test/cctest/test-ast-expression-visitor.cc @@ -6,11 +6,11 @@ #include "src/v8.h" -#include "src/ast.h" -#include "src/ast-expression-visitor.h" -#include "src/parser.h" -#include "src/rewriter.h" -#include "src/scopes.h" +#include "src/ast/ast.h" +#include "src/ast/ast-expression-visitor.h" +#include "src/ast/scopes.h" +#include "src/parsing/parser.h" +#include "src/parsing/rewriter.h" #include "test/cctest/cctest.h" #include "test/cctest/expression-type-collector.h" #include "test/cctest/expression-type-collector-macros.h" @@ -270,6 +270,33 @@ TEST(VisitExpressions) { } +TEST(VisitConditional) { + v8::V8::Initialize(); + HandleAndZoneScope handles; + ZoneVector<ExpressionTypeEntry> types(handles.main_zone()); + // Check that traversing the ternary operator works. + const char test_function[] = + "function foo() {\n" + " var a, b, c;\n" + " var x = a ? b : c;\n" + "}\n"; + CollectTypes(&handles, test_function, &types); + CHECK_TYPES_BEGIN { + CHECK_EXPR(FunctionLiteral, Bounds::Unbounded()) { + CHECK_EXPR(Assignment, Bounds::Unbounded()) { + CHECK_VAR(x, Bounds::Unbounded()); + CHECK_EXPR(Conditional, Bounds::Unbounded()) { + CHECK_VAR(a, Bounds::Unbounded()); + CHECK_VAR(b, Bounds::Unbounded()); + CHECK_VAR(c, Bounds::Unbounded()); + } + } + } + } + CHECK_TYPES_END +} + + TEST(VisitEmptyForStatment) { v8::V8::Initialize(); HandleAndZoneScope handles; diff --git a/deps/v8/test/cctest/test-ast.cc b/deps/v8/test/cctest/test-ast.cc index 7d8b4059f5..49e44eb7b9 100644 --- a/deps/v8/test/cctest/test-ast.cc +++ b/deps/v8/test/cctest/test-ast.cc @@ -29,7 +29,7 @@ #include "src/v8.h" -#include "src/ast.h" +#include "src/ast/ast.h" #include "test/cctest/cctest.h" using namespace v8::internal; diff --git a/deps/v8/test/cctest/test-code-stubs-arm.cc b/deps/v8/test/cctest/test-code-stubs-arm.cc index 385718f486..f59d85483d 100644 --- a/deps/v8/test/cctest/test-code-stubs-arm.cc +++ b/deps/v8/test/cctest/test-code-stubs-arm.cc @@ -51,7 +51,8 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, Assembler::kMinimalBufferSize, &actual_size, true)); CHECK(buffer); HandleScope handles(isolate); - MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); DoubleToIStub stub(isolate, source_reg, destination_reg, 0, true, inline_fastpath); @@ -146,7 +147,7 @@ static Isolate* GetIsolateFrom(LocalContext* context) { int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func, double from) { #ifdef USE_SIMULATOR - return CALL_GENERATED_FP_INT(func, from, 0); + return CALL_GENERATED_FP_INT(CcTest::i_isolate(), func, from, 0); #else return (*func)(from); #endif diff --git a/deps/v8/test/cctest/test-code-stubs-arm64.cc b/deps/v8/test/cctest/test-code-stubs-arm64.cc index c7a6cdb4be..f5a40789be 100644 --- a/deps/v8/test/cctest/test-code-stubs-arm64.cc +++ b/deps/v8/test/cctest/test-code-stubs-arm64.cc @@ -51,7 +51,8 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, v8::base::OS::Allocate(actual_size, &actual_size, true)); CHECK(buffer); HandleScope handles(isolate); - MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); DoubleToIStub stub(isolate, source_reg, destination_reg, 0, true, inline_fastpath); @@ -146,7 +147,7 @@ int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func, Simulator::CallArgument(from), Simulator::CallArgument::End() }; - return static_cast<int32_t>(Simulator::current(Isolate::Current()) + return static_cast<int32_t>(Simulator::current(CcTest::i_isolate()) ->CallInt64(FUNCTION_ADDR(func), args)); #else return (*func)(from); diff --git a/deps/v8/test/cctest/test-code-stubs-ia32.cc b/deps/v8/test/cctest/test-code-stubs-ia32.cc index e0f9a453ed..efc39e9a2e 100644 --- a/deps/v8/test/cctest/test-code-stubs-ia32.cc +++ b/deps/v8/test/cctest/test-code-stubs-ia32.cc @@ -51,7 +51,8 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, Assembler::kMinimalBufferSize, &actual_size, true)); CHECK(buffer); HandleScope handles(isolate); - MacroAssembler assm(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assm(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); int offset = source_reg.is(esp) ? 0 : (HeapNumber::kValueOffset - kSmiTagSize); DoubleToIStub stub(isolate, source_reg, destination_reg, offset, true); diff --git a/deps/v8/test/cctest/test-code-stubs-mips.cc b/deps/v8/test/cctest/test-code-stubs-mips.cc index de6203c0ff..ce577da46b 100644 --- a/deps/v8/test/cctest/test-code-stubs-mips.cc +++ b/deps/v8/test/cctest/test-code-stubs-mips.cc @@ -53,7 +53,8 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, Assembler::kMinimalBufferSize, &actual_size, true)); CHECK(buffer); HandleScope handles(isolate); - MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); DoubleToIStub stub(isolate, source_reg, destination_reg, 0, true, inline_fastpath); @@ -140,7 +141,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, CodeDesc desc; masm.GetCode(&desc); - CpuFeatures::FlushICache(buffer, actual_size); + Assembler::FlushICache(isolate, buffer, actual_size); return (reinterpret_cast<ConvertDToIFunc>( reinterpret_cast<intptr_t>(buffer))); } @@ -156,8 +157,9 @@ static Isolate* GetIsolateFrom(LocalContext* context) { int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func, double from) { #ifdef USE_SIMULATOR - Simulator::current(Isolate::Current())->CallFP(FUNCTION_ADDR(func), from, 0.); - return Simulator::current(Isolate::Current())->get_register(v0.code()); + Simulator::current(CcTest::i_isolate()) + ->CallFP(FUNCTION_ADDR(func), from, 0.); + return Simulator::current(CcTest::i_isolate())->get_register(v0.code()); #else return (*func)(from); #endif diff --git a/deps/v8/test/cctest/test-code-stubs-mips64.cc b/deps/v8/test/cctest/test-code-stubs-mips64.cc index 929c4c326c..97f57b9168 100644 --- a/deps/v8/test/cctest/test-code-stubs-mips64.cc +++ b/deps/v8/test/cctest/test-code-stubs-mips64.cc @@ -53,7 +53,8 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, Assembler::kMinimalBufferSize, &actual_size, true)); CHECK(buffer); HandleScope handles(isolate); - MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); DoubleToIStub stub(isolate, source_reg, destination_reg, 0, true, inline_fastpath); @@ -138,7 +139,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, CodeDesc desc; masm.GetCode(&desc); - CpuFeatures::FlushICache(buffer, actual_size); + Assembler::FlushICache(isolate, buffer, actual_size); return (reinterpret_cast<ConvertDToIFunc>( reinterpret_cast<intptr_t>(buffer))); } @@ -154,9 +155,10 @@ static Isolate* GetIsolateFrom(LocalContext* context) { int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func, double from) { #ifdef USE_SIMULATOR - Simulator::current(Isolate::Current())->CallFP(FUNCTION_ADDR(func), from, 0.); + Simulator::current(CcTest::i_isolate()) + ->CallFP(FUNCTION_ADDR(func), from, 0.); return static_cast<int32_t>( - Simulator::current(Isolate::Current())->get_register(v0.code())); + Simulator::current(CcTest::i_isolate())->get_register(v0.code())); #else return (*func)(from); #endif diff --git a/deps/v8/test/cctest/test-code-stubs-x64.cc b/deps/v8/test/cctest/test-code-stubs-x64.cc index 31c8a134ea..786da547e4 100644 --- a/deps/v8/test/cctest/test-code-stubs-x64.cc +++ b/deps/v8/test/cctest/test-code-stubs-x64.cc @@ -51,7 +51,8 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, Assembler::kMinimalBufferSize, &actual_size, true)); CHECK(buffer); HandleScope handles(isolate); - MacroAssembler assm(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assm(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); int offset = source_reg.is(rsp) ? 0 : (HeapNumber::kValueOffset - kSmiTagSize); DoubleToIStub stub(isolate, source_reg, destination_reg, offset, true); diff --git a/deps/v8/test/cctest/test-code-stubs-x87.cc b/deps/v8/test/cctest/test-code-stubs-x87.cc index e0f9a453ed..efc39e9a2e 100644 --- a/deps/v8/test/cctest/test-code-stubs-x87.cc +++ b/deps/v8/test/cctest/test-code-stubs-x87.cc @@ -51,7 +51,8 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, Assembler::kMinimalBufferSize, &actual_size, true)); CHECK(buffer); HandleScope handles(isolate); - MacroAssembler assm(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assm(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); int offset = source_reg.is(esp) ? 0 : (HeapNumber::kValueOffset - kSmiTagSize); DoubleToIStub stub(isolate, source_reg, destination_reg, offset, true); diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc index e15aef74a0..db2ccb29af 100644 --- a/deps/v8/test/cctest/test-compiler.cc +++ b/deps/v8/test/cctest/test-compiler.cc @@ -32,7 +32,7 @@ #include "src/compiler.h" #include "src/disasm.h" -#include "src/parser.h" +#include "src/parsing/parser.h" #include "test/cctest/cctest.h" using namespace v8::internal; @@ -262,8 +262,7 @@ TEST(Regression236) { TEST(GetScriptLineNumber) { LocalContext context; v8::HandleScope scope(CcTest::isolate()); - v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::NewFromUtf8(CcTest::isolate(), "test")); + v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("test")); const char function_f[] = "function f() {}"; const int max_rows = 1000; const int buffer_size = max_rows + sizeof(function_f); @@ -275,12 +274,13 @@ TEST(GetScriptLineNumber) { if (i > 0) buffer[i - 1] = '\n'; MemCopy(&buffer[i], function_f, sizeof(function_f) - 1); - v8::Handle<v8::String> script_body = - v8::String::NewFromUtf8(CcTest::isolate(), buffer.start()); - v8::Script::Compile(script_body, &origin)->Run(); - v8::Local<v8::Function> f = - v8::Local<v8::Function>::Cast(context->Global()->Get( - v8::String::NewFromUtf8(CcTest::isolate(), "f"))); + v8::Local<v8::String> script_body = v8_str(buffer.start()); + v8::Script::Compile(context.local(), script_body, &origin) + .ToLocalChecked() + ->Run(context.local()) + .ToLocalChecked(); + v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( + context->Global()->Get(context.local(), v8_str("f")).ToLocalChecked()); CHECK_EQ(i, f->GetScriptLineNumber()); } } @@ -292,14 +292,16 @@ TEST(FeedbackVectorPreservedAcrossRecompiles) { CcTest::InitializeVM(); if (!CcTest::i_isolate()->use_crankshaft()) return; v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); // Make sure function f has a call that uses a type feedback slot. CompileRun("function fun() {};" "fun1 = fun;" "function f(a) { a(); } f(fun1);"); - Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( - *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); + Handle<JSFunction> f = Handle<JSFunction>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( + CcTest::global()->Get(context, v8_str("f")).ToLocalChecked()))); // We shouldn't have deoptimization support. We want to recompile and // verify that our feedback vector preserves information. @@ -329,6 +331,7 @@ TEST(FeedbackVectorUnaffectedByScopeChanges) { if (i::FLAG_always_opt || !i::FLAG_lazy) return; CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); CompileRun("function builder() {" " call_target = function() { return 3; };" @@ -342,9 +345,10 @@ TEST(FeedbackVectorUnaffectedByScopeChanges) { "}" "morphing_call = builder();"); - Handle<JSFunction> f = Handle<JSFunction>::cast( - v8::Utils::OpenHandle(*v8::Handle<v8::Function>::Cast( - CcTest::global()->Get(v8_str("morphing_call"))))); + Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( + *v8::Local<v8::Function>::Cast(CcTest::global() + ->Get(context, v8_str("morphing_call")) + .ToLocalChecked()))); // Not compiled, and so no feedback vector allocated yet. CHECK(!f->shared()->is_compiled()); @@ -367,8 +371,9 @@ TEST(OptimizedCodeSharing1) { v8::HandleScope scope(CcTest::isolate()); for (int i = 0; i < 3; i++) { LocalContext env; - env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), - v8::Integer::New(CcTest::isolate(), i)); + env->Global() + ->Set(env.local(), v8_str("x"), v8::Integer::New(CcTest::isolate(), i)) + .FromJust(); CompileRun( "function MakeClosure() {" " return function() { return x; };" @@ -381,10 +386,14 @@ TEST(OptimizedCodeSharing1) { "var closure2 = MakeClosure();"); Handle<JSFunction> fun1 = Handle<JSFunction>::cast( v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( - env->Global()->Get(v8_str("closure1"))))); + env->Global() + ->Get(env.local(), v8_str("closure1")) + .ToLocalChecked()))); Handle<JSFunction> fun2 = Handle<JSFunction>::cast( v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( - env->Global()->Get(v8_str("closure2"))))); + env->Global() + ->Get(env.local(), v8_str("closure2")) + .ToLocalChecked()))); CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); CHECK_EQ(fun1->code(), fun2->code()); @@ -410,9 +419,13 @@ TEST(OptimizedCodeSharing2) { 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(); + env->Global() + ->Set(env.local(), v8_str("x"), v8::Integer::New(CcTest::isolate(), 23)) + .FromJust(); + script->GetUnboundScript() + ->BindToCurrentContext() + ->Run(env.local()) + .ToLocalChecked(); CompileRun( "var closure0 = MakeClosure();" "%DebugPrint(closure0());" @@ -420,15 +433,21 @@ TEST(OptimizedCodeSharing2) { "%DebugPrint(closure0());"); Handle<JSFunction> fun0 = Handle<JSFunction>::cast( v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( - env->Global()->Get(v8_str("closure0"))))); + env->Global() + ->Get(env.local(), v8_str("closure0")) + .ToLocalChecked()))); CHECK(fun0->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); reference_code = handle(fun0->code()); } 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(); + env->Global() + ->Set(env.local(), v8_str("x"), v8::Integer::New(CcTest::isolate(), i)) + .FromJust(); + script->GetUnboundScript() + ->BindToCurrentContext() + ->Run(env.local()) + .ToLocalChecked(); CompileRun( "var closure0 = MakeClosure();" "%DebugPrint(closure0());" @@ -438,10 +457,14 @@ TEST(OptimizedCodeSharing2) { "var closure2 = MakeClosure();"); Handle<JSFunction> fun1 = Handle<JSFunction>::cast( v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( - env->Global()->Get(v8_str("closure1"))))); + env->Global() + ->Get(env.local(), v8_str("closure1")) + .ToLocalChecked()))); Handle<JSFunction> fun2 = Handle<JSFunction>::cast( v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( - env->Global()->Get(v8_str("closure2"))))); + env->Global() + ->Get(env.local(), v8_str("closure2")) + .ToLocalChecked()))); CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); CHECK_EQ(*reference_code, fun1->code()); @@ -468,9 +491,13 @@ TEST(OptimizedCodeSharing3) { 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(); + env->Global() + ->Set(env.local(), v8_str("x"), v8::Integer::New(CcTest::isolate(), 23)) + .FromJust(); + script->GetUnboundScript() + ->BindToCurrentContext() + ->Run(env.local()) + .ToLocalChecked(); CompileRun( "var closure0 = MakeClosure();" "%DebugPrint(closure0());" @@ -478,7 +505,9 @@ TEST(OptimizedCodeSharing3) { "%DebugPrint(closure0());"); Handle<JSFunction> fun0 = Handle<JSFunction>::cast( v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( - env->Global()->Get(v8_str("closure0"))))); + env->Global() + ->Get(env.local(), v8_str("closure0")) + .ToLocalChecked()))); 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 @@ -487,9 +516,13 @@ TEST(OptimizedCodeSharing3) { } 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(); + env->Global() + ->Set(env.local(), v8_str("x"), v8::Integer::New(CcTest::isolate(), i)) + .FromJust(); + script->GetUnboundScript() + ->BindToCurrentContext() + ->Run(env.local()) + .ToLocalChecked(); CompileRun( "var closure0 = MakeClosure();" "%DebugPrint(closure0());" @@ -499,10 +532,14 @@ TEST(OptimizedCodeSharing3) { "var closure2 = MakeClosure();"); Handle<JSFunction> fun1 = Handle<JSFunction>::cast( v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( - env->Global()->Get(v8_str("closure1"))))); + env->Global() + ->Get(env.local(), v8_str("closure1")) + .ToLocalChecked()))); Handle<JSFunction> fun2 = Handle<JSFunction>::cast( v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( - env->Global()->Get(v8_str("closure2"))))); + env->Global() + ->Get(env.local(), v8_str("closure2")) + .ToLocalChecked()))); CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); CHECK_EQ(*reference_code, fun1->code()); @@ -516,28 +553,33 @@ TEST(CompileFunctionInContext) { v8::HandleScope scope(CcTest::isolate()); LocalContext env; CompileRun("var r = 10;"); - v8::Local<v8::Object> math = - v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("Math"))); + v8::Local<v8::Object> math = v8::Local<v8::Object>::Cast( + env->Global()->Get(env.local(), v8_str("Math")).ToLocalChecked()); v8::ScriptCompiler::Source script_source(v8_str( "a = PI * r * r;" "x = r * cos(PI);" "y = r * sin(PI / 2);")); - v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext( - CcTest::isolate(), &script_source, env.local(), 0, NULL, 1, &math); + v8::Local<v8::Function> fun = + v8::ScriptCompiler::CompileFunctionInContext(env.local(), &script_source, + 0, NULL, 1, &math) + .ToLocalChecked(); CHECK(!fun.IsEmpty()); - fun->Call(env->Global(), 0, NULL); - CHECK(env->Global()->Has(v8_str("a"))); - v8::Local<v8::Value> a = env->Global()->Get(v8_str("a")); + fun->Call(env.local(), env->Global(), 0, NULL).ToLocalChecked(); + CHECK(env->Global()->Has(env.local(), v8_str("a")).FromJust()); + v8::Local<v8::Value> a = + env->Global()->Get(env.local(), v8_str("a")).ToLocalChecked(); CHECK(a->IsNumber()); - CHECK(env->Global()->Has(v8_str("x"))); - v8::Local<v8::Value> x = env->Global()->Get(v8_str("x")); + CHECK(env->Global()->Has(env.local(), v8_str("x")).FromJust()); + v8::Local<v8::Value> x = + env->Global()->Get(env.local(), v8_str("x")).ToLocalChecked(); CHECK(x->IsNumber()); - CHECK(env->Global()->Has(v8_str("y"))); - v8::Local<v8::Value> y = env->Global()->Get(v8_str("y")); + CHECK(env->Global()->Has(env.local(), v8_str("y")).FromJust()); + v8::Local<v8::Value> y = + env->Global()->Get(env.local(), v8_str("y")).ToLocalChecked(); CHECK(y->IsNumber()); - CHECK_EQ(314.1592653589793, a->NumberValue()); - CHECK_EQ(-10.0, x->NumberValue()); - CHECK_EQ(10.0, y->NumberValue()); + CHECK_EQ(314.1592653589793, a->NumberValue(env.local()).FromJust()); + CHECK_EQ(-10.0, x->NumberValue(env.local()).FromJust()); + CHECK_EQ(10.0, y->NumberValue(env.local()).FromJust()); } @@ -552,17 +594,22 @@ TEST(CompileFunctionInContextComplex) { "var a = {x: 8, y: 16};" "var b = {x: 32};"); v8::Local<v8::Object> ext[2]; - ext[0] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a"))); - ext[1] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("b"))); + ext[0] = v8::Local<v8::Object>::Cast( + env->Global()->Get(env.local(), v8_str("a")).ToLocalChecked()); + ext[1] = v8::Local<v8::Object>::Cast( + env->Global()->Get(env.local(), v8_str("b")).ToLocalChecked()); v8::ScriptCompiler::Source script_source(v8_str("result = x + y + z")); - v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext( - CcTest::isolate(), &script_source, env.local(), 0, NULL, 2, ext); + v8::Local<v8::Function> fun = + v8::ScriptCompiler::CompileFunctionInContext(env.local(), &script_source, + 0, NULL, 2, ext) + .ToLocalChecked(); CHECK(!fun.IsEmpty()); - fun->Call(env->Global(), 0, NULL); - CHECK(env->Global()->Has(v8_str("result"))); - v8::Local<v8::Value> result = env->Global()->Get(v8_str("result")); + fun->Call(env.local(), env->Global(), 0, NULL).ToLocalChecked(); + CHECK(env->Global()->Has(env.local(), v8_str("result")).FromJust()); + v8::Local<v8::Value> result = + env->Global()->Get(env.local(), v8_str("result")).ToLocalChecked(); CHECK(result->IsNumber()); - CHECK_EQ(52.0, result->NumberValue()); + CHECK_EQ(52.0, result->NumberValue(env.local()).FromJust()); } @@ -572,18 +619,22 @@ TEST(CompileFunctionInContextArgs) { LocalContext env; CompileRun("var a = {x: 23};"); v8::Local<v8::Object> ext[1]; - ext[0] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a"))); + ext[0] = v8::Local<v8::Object>::Cast( + env->Global()->Get(env.local(), v8_str("a")).ToLocalChecked()); v8::ScriptCompiler::Source script_source(v8_str("result = x + b")); v8::Local<v8::String> arg = v8_str("b"); - v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext( - CcTest::isolate(), &script_source, env.local(), 1, &arg, 1, ext); + v8::Local<v8::Function> fun = + v8::ScriptCompiler::CompileFunctionInContext(env.local(), &script_source, + 1, &arg, 1, ext) + .ToLocalChecked(); CHECK(!fun.IsEmpty()); v8::Local<v8::Value> b_value = v8::Number::New(CcTest::isolate(), 42.0); - fun->Call(env->Global(), 1, &b_value); - CHECK(env->Global()->Has(v8_str("result"))); - v8::Local<v8::Value> result = env->Global()->Get(v8_str("result")); + fun->Call(env.local(), env->Global(), 1, &b_value).ToLocalChecked(); + CHECK(env->Global()->Has(env.local(), v8_str("result")).FromJust()); + v8::Local<v8::Value> result = + env->Global()->Get(env.local(), v8_str("result")).ToLocalChecked(); CHECK(result->IsNumber()); - CHECK_EQ(65.0, result->NumberValue()); + CHECK_EQ(65.0, result->NumberValue(env.local()).FromJust()); } @@ -593,19 +644,23 @@ TEST(CompileFunctionInContextComments) { LocalContext env; CompileRun("var a = {x: 23, y: 1, z: 2};"); v8::Local<v8::Object> ext[1]; - ext[0] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a"))); + ext[0] = v8::Local<v8::Object>::Cast( + env->Global()->Get(env.local(), v8_str("a")).ToLocalChecked()); v8::ScriptCompiler::Source script_source( v8_str("result = /* y + */ x + b // + z")); v8::Local<v8::String> arg = v8_str("b"); - v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext( - CcTest::isolate(), &script_source, env.local(), 1, &arg, 1, ext); + v8::Local<v8::Function> fun = + v8::ScriptCompiler::CompileFunctionInContext(env.local(), &script_source, + 1, &arg, 1, ext) + .ToLocalChecked(); CHECK(!fun.IsEmpty()); v8::Local<v8::Value> b_value = v8::Number::New(CcTest::isolate(), 42.0); - fun->Call(env->Global(), 1, &b_value); - CHECK(env->Global()->Has(v8_str("result"))); - v8::Local<v8::Value> result = env->Global()->Get(v8_str("result")); + fun->Call(env.local(), env->Global(), 1, &b_value).ToLocalChecked(); + CHECK(env->Global()->Has(env.local(), v8_str("result")).FromJust()); + v8::Local<v8::Value> result = + env->Global()->Get(env.local(), v8_str("result")).ToLocalChecked(); CHECK(result->IsNumber()); - CHECK_EQ(65.0, result->NumberValue()); + CHECK_EQ(65.0, result->NumberValue(env.local()).FromJust()); } @@ -615,9 +670,9 @@ TEST(CompileFunctionInContextNonIdentifierArgs) { LocalContext env; v8::ScriptCompiler::Source script_source(v8_str("result = 1")); v8::Local<v8::String> arg = v8_str("b }"); - v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext( - CcTest::isolate(), &script_source, env.local(), 1, &arg, 0, NULL); - CHECK(fun.IsEmpty()); + CHECK(v8::ScriptCompiler::CompileFunctionInContext( + env.local(), &script_source, 1, &arg, 0, NULL) + .IsEmpty()); } @@ -629,12 +684,14 @@ TEST(CompileFunctionInContextScriptOrigin) { 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); + v8::Local<v8::Function> fun = + v8::ScriptCompiler::CompileFunctionInContext(env.local(), &script_source, + 0, NULL, 0, NULL) + .ToLocalChecked(); CHECK(!fun.IsEmpty()); - v8::TryCatch try_catch; + v8::TryCatch try_catch(CcTest::isolate()); CcTest::isolate()->SetCaptureStackTraceForUncaughtExceptions(true); - fun->Call(env->Global(), 0, NULL); + CHECK(fun->Call(env.local(), env->Global(), 0, NULL).IsEmpty()); CHECK(try_catch.HasCaught()); CHECK(!try_catch.Exception().IsEmpty()); v8::Local<v8::StackTrace> stack = @@ -648,10 +705,11 @@ TEST(CompileFunctionInContextScriptOrigin) { #ifdef ENABLE_DISASSEMBLER -static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj, +static Handle<JSFunction> GetJSFunction(v8::Local<v8::Object> obj, const char* property_name) { - v8::Local<v8::Function> fun = - v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name))); + v8::Local<v8::Function> fun = v8::Local<v8::Function>::Cast( + obj->Get(CcTest::isolate()->GetCurrentContext(), v8_str(property_name)) + .ToLocalChecked()); return Handle<JSFunction>::cast(v8::Utils::OpenHandle(*fun)); } diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc index ef3571a7d2..29a24e62df 100644 --- a/deps/v8/test/cctest/test-cpu-profiler.cc +++ b/deps/v8/test/cctest/test-cpu-profiler.cc @@ -51,8 +51,10 @@ using v8::base::SmartPointer; // Helper methods -static v8::Local<v8::Function> GetFunction(v8::Context* env, const char* name) { - return v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str(name))); +static v8::Local<v8::Function> GetFunction(v8::Local<v8::Context> env, + const char* name) { + return v8::Local<v8::Function>::Cast( + env->Global()->Get(env, v8_str(name)).ToLocalChecked()); } @@ -135,7 +137,7 @@ i::Code* CreateCode(LocalContext* env) { CompileRun(script.start()); i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast( - v8::Utils::OpenHandle(*GetFunction(**env, name_start))); + v8::Utils::OpenHandle(*GetFunction(env->local(), name_start))); return fun->code(); } @@ -416,10 +418,11 @@ TEST(ProfileStartEndTime) { } -static v8::CpuProfile* RunProfiler( - v8::Handle<v8::Context> env, v8::Handle<v8::Function> function, - v8::Handle<v8::Value> argv[], int argc, - unsigned min_js_samples, bool collect_samples = false) { +static v8::CpuProfile* RunProfiler(v8::Local<v8::Context> env, + v8::Local<v8::Function> function, + v8::Local<v8::Value> argv[], int argc, + unsigned min_js_samples, + bool collect_samples = false) { v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); v8::Local<v8::String> profile_name = v8_str("my_profile"); @@ -429,7 +432,7 @@ static v8::CpuProfile* RunProfiler( reinterpret_cast<i::Isolate*>(env->GetIsolate())->logger()->sampler(); sampler->StartCountingSamples(); do { - function->Call(env->Global(), argc, argv); + function->Call(env, env->Global(), argc, argv).ToLocalChecked(); } while (sampler->js_and_external_sample_count() < min_js_samples); v8::CpuProfile* profile = cpu_profiler->StopProfiling(profile_name); @@ -442,21 +445,23 @@ static v8::CpuProfile* RunProfiler( } -static bool ContainsString(v8::Handle<v8::String> string, - const Vector<v8::Handle<v8::String> >& vector) { +static bool ContainsString(v8::Local<v8::Context> context, + v8::Local<v8::String> string, + const Vector<v8::Local<v8::String> >& vector) { for (int i = 0; i < vector.length(); i++) { - if (string->Equals(vector[i])) return true; + if (string->Equals(context, vector[i]).FromJust()) return true; } return false; } -static void CheckChildrenNames(const v8::CpuProfileNode* node, - const Vector<v8::Handle<v8::String> >& names) { +static void CheckChildrenNames(v8::Local<v8::Context> context, + const v8::CpuProfileNode* node, + const Vector<v8::Local<v8::String> >& names) { int count = node->GetChildrenCount(); for (int i = 0; i < count; i++) { - v8::Handle<v8::String> name = node->GetChild(i)->GetFunctionName(); - if (!ContainsString(name, names)) { + v8::Local<v8::String> name = node->GetChild(i)->GetFunctionName(); + if (!ContainsString(context, name, names)) { char buffer[100]; i::SNPrintF(Vector<char>(buffer, arraysize(buffer)), "Unexpected child '%s' found in '%s'", @@ -467,7 +472,8 @@ static void CheckChildrenNames(const v8::CpuProfileNode* node, // Check that there are no duplicates. for (int j = 0; j < count; j++) { if (j == i) continue; - if (name->Equals(node->GetChild(j)->GetFunctionName())) { + if (name->Equals(context, node->GetChild(j)->GetFunctionName()) + .FromJust()) { char buffer[100]; i::SNPrintF(Vector<char>(buffer, arraysize(buffer)), "Second child with the same name '%s' found in '%s'", @@ -480,21 +486,25 @@ static void CheckChildrenNames(const v8::CpuProfileNode* node, } -static const v8::CpuProfileNode* FindChild(const v8::CpuProfileNode* node, +static const v8::CpuProfileNode* FindChild(v8::Local<v8::Context> context, + const v8::CpuProfileNode* node, const char* name) { int count = node->GetChildrenCount(); - v8::Handle<v8::String> nameHandle = v8_str(name); + v8::Local<v8::String> nameHandle = v8_str(name); for (int i = 0; i < count; i++) { const v8::CpuProfileNode* child = node->GetChild(i); - if (nameHandle->Equals(child->GetFunctionName())) return child; + if (nameHandle->Equals(context, child->GetFunctionName()).FromJust()) { + return child; + } } return NULL; } -static const v8::CpuProfileNode* GetChild(const v8::CpuProfileNode* node, +static const v8::CpuProfileNode* GetChild(v8::Local<v8::Context> context, + const v8::CpuProfileNode* node, const char* name) { - const v8::CpuProfileNode* result = FindChild(node, name); + const v8::CpuProfileNode* result = FindChild(context, node, name); if (!result) { char buffer[100]; i::SNPrintF(Vector<char>(buffer, arraysize(buffer)), @@ -505,22 +515,24 @@ static const v8::CpuProfileNode* GetChild(const v8::CpuProfileNode* node, } -static void CheckSimpleBranch(const v8::CpuProfileNode* node, +static void CheckSimpleBranch(v8::Local<v8::Context> context, + const v8::CpuProfileNode* node, const char* names[], int length) { for (int i = 0; i < length; i++) { const char* name = names[i]; - node = GetChild(node, name); + node = GetChild(context, node, name); int expectedChildrenCount = (i == length - 1) ? 0 : 1; CHECK_EQ(expectedChildrenCount, node->GetChildrenCount()); } } -static const ProfileNode* GetSimpleBranch(v8::CpuProfile* profile, +static const ProfileNode* GetSimpleBranch(v8::Local<v8::Context> context, + v8::CpuProfile* profile, const char* names[], int length) { const v8::CpuProfileNode* node = profile->GetTopDownRoot(); for (int i = 0; i < length; i++) { - node = GetChild(node, names[i]); + node = GetChild(context, node, names[i]); } return reinterpret_cast<const ProfileNode*>(node); } @@ -580,36 +592,36 @@ TEST(CollectCpuProfile) { v8::HandleScope scope(env->GetIsolate()); CompileRun(cpu_profiler_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env.local(), "start"); int32_t profiling_interval_ms = 200; - v8::Handle<v8::Value> args[] = { - v8::Integer::New(env->GetIsolate(), profiling_interval_ms) - }; + v8::Local<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), profiling_interval_ms)}; v8::CpuProfile* profile = RunProfiler(env.local(), function, args, arraysize(args), 200); - function->Call(env->Global(), arraysize(args), args); + function->Call(env.local(), env->Global(), arraysize(args), args) + .ToLocalChecked(); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - ScopedVector<v8::Handle<v8::String> > names(3); + ScopedVector<v8::Local<v8::String> > names(3); names[0] = v8_str(ProfileGenerator::kGarbageCollectorEntryName); names[1] = v8_str(ProfileGenerator::kProgramEntryName); names[2] = v8_str("start"); - CheckChildrenNames(root, names); + CheckChildrenNames(env.local(), root, names); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); + const v8::CpuProfileNode* startNode = GetChild(env.local(), root, "start"); CHECK_EQ(1, startNode->GetChildrenCount()); - const v8::CpuProfileNode* fooNode = GetChild(startNode, "foo"); + const v8::CpuProfileNode* fooNode = GetChild(env.local(), startNode, "foo"); CHECK_EQ(3, fooNode->GetChildrenCount()); const char* barBranch[] = { "bar", "delay", "loop" }; - CheckSimpleBranch(fooNode, barBranch, arraysize(barBranch)); + CheckSimpleBranch(env.local(), fooNode, barBranch, arraysize(barBranch)); const char* bazBranch[] = { "baz", "delay", "loop" }; - CheckSimpleBranch(fooNode, bazBranch, arraysize(bazBranch)); + CheckSimpleBranch(env.local(), fooNode, bazBranch, arraysize(bazBranch)); const char* delayBranch[] = { "delay", "loop" }; - CheckSimpleBranch(fooNode, delayBranch, arraysize(delayBranch)); + CheckSimpleBranch(env.local(), fooNode, delayBranch, arraysize(delayBranch)); profile->Delete(); } @@ -648,28 +660,28 @@ TEST(HotDeoptNoFrameEntry) { v8::HandleScope scope(env->GetIsolate()); CompileRun(hot_deopt_no_frame_entry_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env.local(), "start"); int32_t profiling_interval_ms = 200; - v8::Handle<v8::Value> args[] = { - v8::Integer::New(env->GetIsolate(), profiling_interval_ms) - }; + v8::Local<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), profiling_interval_ms)}; v8::CpuProfile* profile = RunProfiler(env.local(), function, args, arraysize(args), 200); - function->Call(env->Global(), arraysize(args), args); + function->Call(env.local(), env->Global(), arraysize(args), args) + .ToLocalChecked(); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - ScopedVector<v8::Handle<v8::String> > names(3); + ScopedVector<v8::Local<v8::String> > names(3); names[0] = v8_str(ProfileGenerator::kGarbageCollectorEntryName); names[1] = v8_str(ProfileGenerator::kProgramEntryName); names[2] = v8_str("start"); - CheckChildrenNames(root, names); + CheckChildrenNames(env.local(), root, names); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); + const v8::CpuProfileNode* startNode = GetChild(env.local(), root, "start"); CHECK_EQ(1, startNode->GetChildrenCount()); - GetChild(startNode, "foo"); + GetChild(env.local(), startNode, "foo"); profile->Delete(); } @@ -680,12 +692,11 @@ TEST(CollectCpuProfileSamples) { v8::HandleScope scope(env->GetIsolate()); CompileRun(cpu_profiler_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env.local(), "start"); int32_t profiling_interval_ms = 200; - v8::Handle<v8::Value> args[] = { - v8::Integer::New(env->GetIsolate(), profiling_interval_ms) - }; + v8::Local<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), profiling_interval_ms)}; v8::CpuProfile* profile = RunProfiler(env.local(), function, args, arraysize(args), 200, true); @@ -730,36 +741,36 @@ TEST(SampleWhenFrameIsNotSetup) { v8::HandleScope scope(env->GetIsolate()); CompileRun(cpu_profiler_test_source2); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env.local(), "start"); int32_t repeat_count = 100; #if defined(USE_SIMULATOR) // Simulators are much slower. repeat_count = 1; #endif - v8::Handle<v8::Value> args[] = { - v8::Integer::New(env->GetIsolate(), repeat_count) - }; + v8::Local<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), repeat_count)}; v8::CpuProfile* profile = RunProfiler(env.local(), function, args, arraysize(args), 100); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - ScopedVector<v8::Handle<v8::String> > names(3); + ScopedVector<v8::Local<v8::String> > names(3); names[0] = v8_str(ProfileGenerator::kGarbageCollectorEntryName); names[1] = v8_str(ProfileGenerator::kProgramEntryName); names[2] = v8_str("start"); - CheckChildrenNames(root, names); + CheckChildrenNames(env.local(), root, names); - const v8::CpuProfileNode* startNode = FindChild(root, "start"); + const v8::CpuProfileNode* startNode = FindChild(env.local(), root, "start"); // On slow machines there may be no meaningfull samples at all, skip the // check there. if (startNode && startNode->GetChildrenCount() > 0) { CHECK_EQ(1, startNode->GetChildrenCount()); - const v8::CpuProfileNode* delayNode = GetChild(startNode, "delay"); + const v8::CpuProfileNode* delayNode = + GetChild(env.local(), startNode, "delay"); if (delayNode->GetChildrenCount() > 0) { CHECK_EQ(1, delayNode->GetChildrenCount()); - GetChild(delayNode, "loop"); + GetChild(env.local(), delayNode, "loop"); } } @@ -842,22 +853,24 @@ TEST(NativeAccessorUninitializedIC) { v8::External::New(isolate, &accessors); instance_template->SetAccessor(v8_str("foo"), &TestApiCallbacks::Getter, &TestApiCallbacks::Setter, data); - v8::Local<v8::Function> func = func_template->GetFunction(); - v8::Local<v8::Object> instance = func->NewInstance(); - env->Global()->Set(v8_str("instance"), instance); + v8::Local<v8::Function> func = + func_template->GetFunction(env.local()).ToLocalChecked(); + v8::Local<v8::Object> instance = + func->NewInstance(env.local()).ToLocalChecked(); + env->Global()->Set(env.local(), v8_str("instance"), instance).FromJust(); CompileRun(native_accessor_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env.local(), "start"); int32_t repeat_count = 1; - v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) }; + v8::Local<v8::Value> args[] = {v8::Integer::New(isolate, repeat_count)}; v8::CpuProfile* profile = RunProfiler(env.local(), function, args, arraysize(args), 180); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); - GetChild(startNode, "get foo"); - GetChild(startNode, "set foo"); + const v8::CpuProfileNode* startNode = GetChild(env.local(), root, "start"); + GetChild(env.local(), startNode, "get foo"); + GetChild(env.local(), startNode, "set foo"); profile->Delete(); } @@ -881,34 +894,36 @@ TEST(NativeAccessorMonomorphicIC) { v8::External::New(isolate, &accessors); instance_template->SetAccessor(v8_str("foo"), &TestApiCallbacks::Getter, &TestApiCallbacks::Setter, data); - v8::Local<v8::Function> func = func_template->GetFunction(); - v8::Local<v8::Object> instance = func->NewInstance(); - env->Global()->Set(v8_str("instance"), instance); + v8::Local<v8::Function> func = + func_template->GetFunction(env.local()).ToLocalChecked(); + v8::Local<v8::Object> instance = + func->NewInstance(env.local()).ToLocalChecked(); + env->Global()->Set(env.local(), v8_str("instance"), instance).FromJust(); CompileRun(native_accessor_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env.local(), "start"); { // Make sure accessors ICs are in monomorphic state before starting // profiling. accessors.set_warming_up(true); int32_t warm_up_iterations = 3; - v8::Handle<v8::Value> args[] = { - v8::Integer::New(isolate, warm_up_iterations) - }; - function->Call(env->Global(), arraysize(args), args); + v8::Local<v8::Value> args[] = { + v8::Integer::New(isolate, warm_up_iterations)}; + function->Call(env.local(), env->Global(), arraysize(args), args) + .ToLocalChecked(); accessors.set_warming_up(false); } int32_t repeat_count = 100; - v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) }; + v8::Local<v8::Value> args[] = {v8::Integer::New(isolate, repeat_count)}; v8::CpuProfile* profile = RunProfiler(env.local(), function, args, arraysize(args), 200); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); - GetChild(startNode, "get foo"); - GetChild(startNode, "set foo"); + const v8::CpuProfileNode* startNode = GetChild(env.local(), root, "start"); + GetChild(env.local(), startNode, "get foo"); + GetChild(env.local(), startNode, "set foo"); profile->Delete(); } @@ -942,21 +957,23 @@ TEST(NativeMethodUninitializedIC) { v8::FunctionTemplate::New(isolate, &TestApiCallbacks::Callback, data, signature, 0)); - v8::Local<v8::Function> func = func_template->GetFunction(); - v8::Local<v8::Object> instance = func->NewInstance(); - env->Global()->Set(v8_str("instance"), instance); + v8::Local<v8::Function> func = + func_template->GetFunction(env.local()).ToLocalChecked(); + v8::Local<v8::Object> instance = + func->NewInstance(env.local()).ToLocalChecked(); + env->Global()->Set(env.local(), v8_str("instance"), instance).FromJust(); CompileRun(native_method_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env.local(), "start"); int32_t repeat_count = 1; - v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) }; + v8::Local<v8::Value> args[] = {v8::Integer::New(isolate, repeat_count)}; v8::CpuProfile* profile = RunProfiler(env.local(), function, args, arraysize(args), 100); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); - GetChild(startNode, "fooMethod"); + const v8::CpuProfileNode* startNode = GetChild(env.local(), root, "start"); + GetChild(env.local(), startNode, "fooMethod"); profile->Delete(); } @@ -983,33 +1000,35 @@ TEST(NativeMethodMonomorphicIC) { v8::FunctionTemplate::New(isolate, &TestApiCallbacks::Callback, data, signature, 0)); - v8::Local<v8::Function> func = func_template->GetFunction(); - v8::Local<v8::Object> instance = func->NewInstance(); - env->Global()->Set(v8_str("instance"), instance); + v8::Local<v8::Function> func = + func_template->GetFunction(env.local()).ToLocalChecked(); + v8::Local<v8::Object> instance = + func->NewInstance(env.local()).ToLocalChecked(); + env->Global()->Set(env.local(), v8_str("instance"), instance).FromJust(); CompileRun(native_method_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env.local(), "start"); { // Make sure method ICs are in monomorphic state before starting // profiling. callbacks.set_warming_up(true); int32_t warm_up_iterations = 3; - v8::Handle<v8::Value> args[] = { - v8::Integer::New(isolate, warm_up_iterations) - }; - function->Call(env->Global(), arraysize(args), args); + v8::Local<v8::Value> args[] = { + v8::Integer::New(isolate, warm_up_iterations)}; + function->Call(env.local(), env->Global(), arraysize(args), args) + .ToLocalChecked(); callbacks.set_warming_up(false); } int32_t repeat_count = 100; - v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) }; + v8::Local<v8::Value> args[] = {v8::Integer::New(isolate, repeat_count)}; v8::CpuProfile* profile = RunProfiler(env.local(), function, args, arraysize(args), 100); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - GetChild(root, "start"); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); - GetChild(startNode, "fooMethod"); + GetChild(env.local(), root, "start"); + const v8::CpuProfileNode* startNode = GetChild(env.local(), root, "start"); + GetChild(env.local(), startNode, "fooMethod"); profile->Delete(); } @@ -1031,20 +1050,20 @@ TEST(BoundFunctionCall) { v8::Context::Scope context_scope(env); CompileRun(bound_function_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env, "start"); v8::CpuProfile* profile = RunProfiler(env, function, NULL, 0, 0); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - ScopedVector<v8::Handle<v8::String> > names(3); + ScopedVector<v8::Local<v8::String> > names(3); names[0] = v8_str(ProfileGenerator::kGarbageCollectorEntryName); names[1] = v8_str(ProfileGenerator::kProgramEntryName); names[2] = v8_str("start"); // Don't allow |foo| node to be at the top level. - CheckChildrenNames(root, names); + CheckChildrenNames(env, root, names); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); - GetChild(startNode, "foo"); + const v8::CpuProfileNode* startNode = GetChild(env, root, "start"); + GetChild(env, startNode, "foo"); profile->Delete(); } @@ -1077,7 +1096,7 @@ TEST(TickLines) { CompileRun(script.start()); i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast( - v8::Utils::OpenHandle(*GetFunction(*env, func_name))); + v8::Utils::OpenHandle(*GetFunction(env.local(), func_name))); CHECK(func->shared()); CHECK(func->shared()->code()); i::Code* code = NULL; @@ -1181,45 +1200,44 @@ TEST(FunctionCallSample) { CcTest::heap()->CollectAllGarbage(); CompileRun(call_function_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env.local(), "start"); int32_t duration_ms = 100; - v8::Handle<v8::Value> args[] = { - v8::Integer::New(env->GetIsolate(), duration_ms) - }; + v8::Local<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), duration_ms)}; v8::CpuProfile* profile = RunProfiler(env.local(), function, args, arraysize(args), 100); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); { - ScopedVector<v8::Handle<v8::String> > names(4); + ScopedVector<v8::Local<v8::String> > names(4); names[0] = v8_str(ProfileGenerator::kGarbageCollectorEntryName); names[1] = v8_str(ProfileGenerator::kProgramEntryName); names[2] = v8_str("start"); names[3] = v8_str(i::ProfileGenerator::kUnresolvedFunctionName); // Don't allow |bar| and |call| nodes to be at the top level. - CheckChildrenNames(root, names); + CheckChildrenNames(env.local(), root, names); } // In case of GC stress tests all samples may be in GC phase and there // won't be |start| node in the profiles. bool is_gc_stress_testing = (i::FLAG_gc_interval != -1) || i::FLAG_stress_compaction; - const v8::CpuProfileNode* startNode = FindChild(root, "start"); + const v8::CpuProfileNode* startNode = FindChild(env.local(), root, "start"); CHECK(is_gc_stress_testing || startNode); if (startNode) { - ScopedVector<v8::Handle<v8::String> > names(2); + ScopedVector<v8::Local<v8::String> > names(2); names[0] = v8_str("bar"); names[1] = v8_str("call"); - CheckChildrenNames(startNode, names); + CheckChildrenNames(env.local(), startNode, names); } - const v8::CpuProfileNode* unresolvedNode = - FindChild(root, i::ProfileGenerator::kUnresolvedFunctionName); + const v8::CpuProfileNode* unresolvedNode = FindChild( + env.local(), root, i::ProfileGenerator::kUnresolvedFunctionName); if (unresolvedNode) { - ScopedVector<v8::Handle<v8::String> > names(1); + ScopedVector<v8::Local<v8::String> > names(1); names[0] = v8_str("call"); - CheckChildrenNames(unresolvedNode, names); + CheckChildrenNames(env.local(), unresolvedNode, names); } profile->Delete(); @@ -1257,52 +1275,53 @@ TEST(FunctionApplySample) { v8::HandleScope scope(env->GetIsolate()); CompileRun(function_apply_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env.local(), "start"); int32_t duration_ms = 100; - v8::Handle<v8::Value> args[] = { - v8::Integer::New(env->GetIsolate(), duration_ms) - }; + v8::Local<v8::Value> args[] = { + v8::Integer::New(env->GetIsolate(), duration_ms)}; v8::CpuProfile* profile = RunProfiler(env.local(), function, args, arraysize(args), 100); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); { - ScopedVector<v8::Handle<v8::String> > names(3); + ScopedVector<v8::Local<v8::String> > names(3); names[0] = v8_str(ProfileGenerator::kGarbageCollectorEntryName); names[1] = v8_str(ProfileGenerator::kProgramEntryName); names[2] = v8_str("start"); // Don't allow |test|, |bar| and |apply| nodes to be at the top level. - CheckChildrenNames(root, names); + CheckChildrenNames(env.local(), root, names); } - const v8::CpuProfileNode* startNode = FindChild(root, "start"); + const v8::CpuProfileNode* startNode = FindChild(env.local(), root, "start"); if (startNode) { { - ScopedVector<v8::Handle<v8::String> > names(2); + ScopedVector<v8::Local<v8::String> > names(2); names[0] = v8_str("test"); names[1] = v8_str(ProfileGenerator::kUnresolvedFunctionName); - CheckChildrenNames(startNode, names); + CheckChildrenNames(env.local(), startNode, names); } - const v8::CpuProfileNode* testNode = FindChild(startNode, "test"); + const v8::CpuProfileNode* testNode = + FindChild(env.local(), startNode, "test"); if (testNode) { - ScopedVector<v8::Handle<v8::String> > names(3); + ScopedVector<v8::Local<v8::String> > names(3); names[0] = v8_str("bar"); names[1] = v8_str("apply"); // apply calls "get length" before invoking the function itself // and we may get hit into it. names[2] = v8_str("get length"); - CheckChildrenNames(testNode, names); + CheckChildrenNames(env.local(), testNode, names); } if (const v8::CpuProfileNode* unresolvedNode = - FindChild(startNode, ProfileGenerator::kUnresolvedFunctionName)) { - ScopedVector<v8::Handle<v8::String> > names(1); + FindChild(env.local(), startNode, + ProfileGenerator::kUnresolvedFunctionName)) { + ScopedVector<v8::Local<v8::String> > names(1); names[0] = v8_str("apply"); - CheckChildrenNames(unresolvedNode, names); - GetChild(unresolvedNode, "apply"); + CheckChildrenNames(env.local(), unresolvedNode, names); + GetChild(env.local(), unresolvedNode, "apply"); } } @@ -1339,11 +1358,11 @@ TEST(CpuProfileDeepStack) { v8::Context::Scope context_scope(env); CompileRun(cpu_profiler_deep_stack_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env, "start"); v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler(); v8::Local<v8::String> profile_name = v8_str("my_profile"); - function->Call(env->Global(), 0, NULL); + function->Call(env, env->Global(), 0, NULL).ToLocalChecked(); v8::CpuProfile* profile = cpu_profiler->StopProfiling(profile_name); CHECK(profile); // Dump collected profile to have a better diagnostic in case of failure. @@ -1351,16 +1370,16 @@ TEST(CpuProfileDeepStack) { const v8::CpuProfileNode* root = profile->GetTopDownRoot(); { - ScopedVector<v8::Handle<v8::String> > names(3); + ScopedVector<v8::Local<v8::String> > names(3); names[0] = v8_str(ProfileGenerator::kGarbageCollectorEntryName); names[1] = v8_str(ProfileGenerator::kProgramEntryName); names[2] = v8_str("start"); - CheckChildrenNames(root, names); + CheckChildrenNames(env, root, names); } - const v8::CpuProfileNode* node = GetChild(root, "start"); + const v8::CpuProfileNode* node = GetChild(env, root, "start"); for (int i = 0; i < 250; ++i) { - node = GetChild(node, "foo"); + node = GetChild(env, node, "foo"); } // TODO(alph): // In theory there must be one more 'foo' and a 'startProfiling' nodes, @@ -1384,9 +1403,11 @@ static const char* js_native_js_test_source = "}"; static void CallJsFunction(const v8::FunctionCallbackInfo<v8::Value>& info) { - v8::Handle<v8::Function> function = info[0].As<v8::Function>(); - v8::Handle<v8::Value> argv[] = { info[1] }; - function->Call(info.This(), arraysize(argv), argv); + v8::Local<v8::Function> function = info[0].As<v8::Function>(); + v8::Local<v8::Value> argv[] = {info[1]}; + function->Call(info.GetIsolate()->GetCurrentContext(), info.This(), + arraysize(argv), argv) + .ToLocalChecked(); } @@ -1404,34 +1425,35 @@ TEST(JsNativeJsSample) { v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New( env->GetIsolate(), CallJsFunction); - v8::Local<v8::Function> func = func_template->GetFunction(); + v8::Local<v8::Function> func = + func_template->GetFunction(env).ToLocalChecked(); func->SetName(v8_str("CallJsFunction")); - env->Global()->Set(v8_str("CallJsFunction"), func); + env->Global()->Set(env, v8_str("CallJsFunction"), func).FromJust(); CompileRun(js_native_js_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env, "start"); v8::CpuProfile* profile = RunProfiler(env, function, NULL, 0, 0); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); { - ScopedVector<v8::Handle<v8::String> > names(3); + ScopedVector<v8::Local<v8::String> > names(3); names[0] = v8_str(ProfileGenerator::kGarbageCollectorEntryName); names[1] = v8_str(ProfileGenerator::kProgramEntryName); names[2] = v8_str("start"); - CheckChildrenNames(root, names); + CheckChildrenNames(env, root, names); } - const v8::CpuProfileNode* startNode = GetChild(root, "start"); + const v8::CpuProfileNode* startNode = GetChild(env, root, "start"); CHECK_EQ(1, startNode->GetChildrenCount()); const v8::CpuProfileNode* nativeFunctionNode = - GetChild(startNode, "CallJsFunction"); + GetChild(env, startNode, "CallJsFunction"); CHECK_EQ(1, nativeFunctionNode->GetChildrenCount()); - const v8::CpuProfileNode* barNode = GetChild(nativeFunctionNode, "bar"); + const v8::CpuProfileNode* barNode = GetChild(env, nativeFunctionNode, "bar"); CHECK_EQ(1, barNode->GetChildrenCount()); - GetChild(barNode, "foo"); + GetChild(env, barNode, "foo"); profile->Delete(); } @@ -1466,36 +1488,37 @@ TEST(JsNativeJsRuntimeJsSample) { v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New( env->GetIsolate(), CallJsFunction); - v8::Local<v8::Function> func = func_template->GetFunction(); + v8::Local<v8::Function> func = + func_template->GetFunction(env).ToLocalChecked(); func->SetName(v8_str("CallJsFunction")); - env->Global()->Set(v8_str("CallJsFunction"), func); + env->Global()->Set(env, v8_str("CallJsFunction"), func).FromJust(); CompileRun(js_native_js_runtime_js_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env, "start"); v8::CpuProfile* profile = RunProfiler(env, function, NULL, 0, 0); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - ScopedVector<v8::Handle<v8::String> > names(3); + ScopedVector<v8::Local<v8::String> > names(3); names[0] = v8_str(ProfileGenerator::kGarbageCollectorEntryName); names[1] = v8_str(ProfileGenerator::kProgramEntryName); names[2] = v8_str("start"); - CheckChildrenNames(root, names); + CheckChildrenNames(env, root, names); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); + const v8::CpuProfileNode* startNode = GetChild(env, root, "start"); CHECK_EQ(1, startNode->GetChildrenCount()); const v8::CpuProfileNode* nativeFunctionNode = - GetChild(startNode, "CallJsFunction"); + GetChild(env, startNode, "CallJsFunction"); CHECK_EQ(1, nativeFunctionNode->GetChildrenCount()); - const v8::CpuProfileNode* barNode = GetChild(nativeFunctionNode, "bar"); + const v8::CpuProfileNode* barNode = GetChild(env, nativeFunctionNode, "bar"); // The child is in fact a bound foo. // A bound function has a wrapper that may make calls to // other functions e.g. "get length". CHECK_LE(1, barNode->GetChildrenCount()); CHECK_GE(2, barNode->GetChildrenCount()); - GetChild(barNode, "foo"); + GetChild(env, barNode, "foo"); profile->Delete(); } @@ -1538,40 +1561,44 @@ TEST(JsNative1JsNative2JsSample) { v8::Local<v8::FunctionTemplate> func_template = v8::FunctionTemplate::New( env->GetIsolate(), CallJsFunction); - v8::Local<v8::Function> func1 = func_template->GetFunction(); + v8::Local<v8::Function> func1 = + func_template->GetFunction(env).ToLocalChecked(); func1->SetName(v8_str("CallJsFunction1")); - env->Global()->Set(v8_str("CallJsFunction1"), func1); + env->Global()->Set(env, v8_str("CallJsFunction1"), func1).FromJust(); - v8::Local<v8::Function> func2 = v8::FunctionTemplate::New( - env->GetIsolate(), CallJsFunction2)->GetFunction(); + v8::Local<v8::Function> func2 = + v8::FunctionTemplate::New(env->GetIsolate(), CallJsFunction2) + ->GetFunction(env) + .ToLocalChecked(); func2->SetName(v8_str("CallJsFunction2")); - env->Global()->Set(v8_str("CallJsFunction2"), func2); + env->Global()->Set(env, v8_str("CallJsFunction2"), func2).FromJust(); CompileRun(js_native1_js_native2_js_test_source); - v8::Local<v8::Function> function = GetFunction(*env, "start"); + v8::Local<v8::Function> function = GetFunction(env, "start"); v8::CpuProfile* profile = RunProfiler(env, function, NULL, 0, 0); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - ScopedVector<v8::Handle<v8::String> > names(3); + ScopedVector<v8::Local<v8::String> > names(3); names[0] = v8_str(ProfileGenerator::kGarbageCollectorEntryName); names[1] = v8_str(ProfileGenerator::kProgramEntryName); names[2] = v8_str("start"); - CheckChildrenNames(root, names); + CheckChildrenNames(env, root, names); - const v8::CpuProfileNode* startNode = GetChild(root, "start"); + const v8::CpuProfileNode* startNode = GetChild(env, root, "start"); CHECK_EQ(1, startNode->GetChildrenCount()); const v8::CpuProfileNode* nativeNode1 = - GetChild(startNode, "CallJsFunction1"); + GetChild(env, startNode, "CallJsFunction1"); CHECK_EQ(1, nativeNode1->GetChildrenCount()); - const v8::CpuProfileNode* barNode = GetChild(nativeNode1, "bar"); + const v8::CpuProfileNode* barNode = GetChild(env, nativeNode1, "bar"); CHECK_EQ(1, barNode->GetChildrenCount()); - const v8::CpuProfileNode* nativeNode2 = GetChild(barNode, "CallJsFunction2"); + const v8::CpuProfileNode* nativeNode2 = + GetChild(env, barNode, "CallJsFunction2"); CHECK_EQ(1, nativeNode2->GetChildrenCount()); - GetChild(nativeNode2, "foo"); + GetChild(env, nativeNode2, "foo"); profile->Delete(); } @@ -1609,19 +1636,19 @@ TEST(IdleTime) { reinterpret_cast<i::CpuProfile*>(profile)->Print(); const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - ScopedVector<v8::Handle<v8::String> > names(3); + ScopedVector<v8::Local<v8::String> > names(3); names[0] = v8_str(ProfileGenerator::kGarbageCollectorEntryName); names[1] = v8_str(ProfileGenerator::kProgramEntryName); names[2] = v8_str(ProfileGenerator::kIdleEntryName); - CheckChildrenNames(root, names); + CheckChildrenNames(env.local(), root, names); const v8::CpuProfileNode* programNode = - GetChild(root, ProfileGenerator::kProgramEntryName); + GetChild(env.local(), root, ProfileGenerator::kProgramEntryName); CHECK_EQ(0, programNode->GetChildrenCount()); CHECK_GE(programNode->GetHitCount(), 3u); const v8::CpuProfileNode* idleNode = - GetChild(root, ProfileGenerator::kIdleEntryName); + GetChild(env.local(), root, ProfileGenerator::kIdleEntryName); CHECK_EQ(0, idleNode->GetChildrenCount()); CHECK_GE(idleNode->GetHitCount(), 3u); @@ -1633,8 +1660,11 @@ static void CheckFunctionDetails(v8::Isolate* isolate, const v8::CpuProfileNode* node, const char* name, const char* script_name, int script_id, int line, int column) { - CHECK(v8_str(name)->Equals(node->GetFunctionName())); - CHECK(v8_str(script_name)->Equals(node->GetScriptResourceName())); + v8::Local<v8::Context> context = isolate->GetCurrentContext(); + CHECK(v8_str(name)->Equals(context, node->GetFunctionName()).FromJust()); + CHECK(v8_str(script_name) + ->Equals(context, node->GetScriptResourceName()) + .FromJust()); CHECK_EQ(script_id, node->GetScriptId()); CHECK_EQ(line, node->GetLineNumber()); CHECK_EQ(column, node->GetColumnNumber()); @@ -1646,17 +1676,17 @@ TEST(FunctionDetails) { v8::Local<v8::Context> env = CcTest::NewContext(PROFILER_EXTENSION); v8::Context::Scope context_scope(env); - v8::Handle<v8::Script> script_a = CompileWithOrigin( - " function foo\n() { try { bar(); } catch(e) {} }\n" - " function bar() { startProfiling(); }\n", - "script_a"); - script_a->Run(); - v8::Handle<v8::Script> script_b = CompileWithOrigin( - "\n\n function baz() { try { foo(); } catch(e) {} }\n" - "\n\nbaz();\n" - "stopProfiling();\n", - "script_b"); - script_b->Run(); + v8::Local<v8::Script> script_a = CompileWithOrigin( + " function foo\n() { try { bar(); } catch(e) {} }\n" + " function bar() { startProfiling(); }\n", + "script_a"); + script_a->Run(env).ToLocalChecked(); + v8::Local<v8::Script> script_b = CompileWithOrigin( + "\n\n function baz() { try { foo(); } catch(e) {} }\n" + "\n\nbaz();\n" + "stopProfiling();\n", + "script_b"); + script_b->Run(env).ToLocalChecked(); const v8::CpuProfile* profile = i::ProfilerExtension::last_profile; const v8::CpuProfileNode* current = profile->GetTopDownRoot(); reinterpret_cast<ProfileNode*>( @@ -1668,16 +1698,16 @@ TEST(FunctionDetails) { // 0 foo 18 #4 TryCatchStatement script_a:2 // 1 bar 18 #5 no reason script_a:3 const v8::CpuProfileNode* root = profile->GetTopDownRoot(); - const v8::CpuProfileNode* script = GetChild(root, ""); + const v8::CpuProfileNode* script = GetChild(env, root, ""); CheckFunctionDetails(env->GetIsolate(), script, "", "script_b", script_b->GetUnboundScript()->GetId(), 1, 1); - const v8::CpuProfileNode* baz = GetChild(script, "baz"); + const v8::CpuProfileNode* baz = GetChild(env, script, "baz"); CheckFunctionDetails(env->GetIsolate(), baz, "baz", "script_b", script_b->GetUnboundScript()->GetId(), 3, 16); - const v8::CpuProfileNode* foo = GetChild(baz, "foo"); + const v8::CpuProfileNode* foo = GetChild(env, baz, "foo"); CheckFunctionDetails(env->GetIsolate(), foo, "foo", "script_a", script_a->GetUnboundScript()->GetId(), 2, 1); - const v8::CpuProfileNode* bar = GetChild(foo, "bar"); + const v8::CpuProfileNode* bar = GetChild(env, foo, "bar"); CheckFunctionDetails(env->GetIsolate(), bar, "bar", "script_a", script_a->GetUnboundScript()->GetId(), 3, 14); } @@ -1692,11 +1722,11 @@ TEST(DontStopOnFinishedProfileDelete) { i::CpuProfiler* iprofiler = reinterpret_cast<i::CpuProfiler*>(profiler); CHECK_EQ(0, iprofiler->GetProfilesCount()); - v8::Handle<v8::String> outer = v8_str("outer"); + v8::Local<v8::String> outer = v8_str("outer"); profiler->StartProfiling(outer); CHECK_EQ(0, iprofiler->GetProfilesCount()); - v8::Handle<v8::String> inner = v8_str("inner"); + v8::Local<v8::String> inner = v8_str("inner"); profiler->StartProfiling(inner); CHECK_EQ(0, iprofiler->GetProfilesCount()); @@ -1716,11 +1746,12 @@ TEST(DontStopOnFinishedProfileDelete) { } -const char* GetBranchDeoptReason(i::CpuProfile* iprofile, const char* branch[], +const char* GetBranchDeoptReason(v8::Local<v8::Context> context, + i::CpuProfile* iprofile, const char* branch[], int length) { v8::CpuProfile* profile = reinterpret_cast<v8::CpuProfile*>(iprofile); const ProfileNode* iopt_function = NULL; - iopt_function = GetSimpleBranch(profile, branch, length); + iopt_function = GetSimpleBranch(context, profile, branch, length); CHECK_EQ(1U, iopt_function->deopt_infos().size()); return iopt_function->deopt_infos()[0].deopt_reason; } @@ -1748,7 +1779,10 @@ TEST(CollectDeoptEvents) { for (int i = 0; i < 3; ++i) { i::EmbeddedVector<char, sizeof(opt_source) + 100> buffer; i::SNPrintF(buffer, opt_source, i, i); - v8::Script::Compile(v8_str(buffer.start()))->Run(); + v8::Script::Compile(env, v8_str(buffer.start())) + .ToLocalChecked() + ->Run(env) + .ToLocalChecked(); } const char* source = @@ -1781,7 +1815,10 @@ TEST(CollectDeoptEvents) { "stopProfiling();\n" "\n"; - v8::Script::Compile(v8_str(source))->Run(); + v8::Script::Compile(env, v8_str(source)) + .ToLocalChecked() + ->Run(env) + .ToLocalChecked(); i::CpuProfile* iprofile = iprofiler->GetProfile(0); iprofile->Print(); /* The expected profile @@ -1805,12 +1842,12 @@ TEST(CollectDeoptEvents) { { const char* branch[] = {"", "opt_function0", "opt_function0"}; CHECK_EQ(reason(i::Deoptimizer::kNotAHeapNumber), - GetBranchDeoptReason(iprofile, branch, arraysize(branch))); + GetBranchDeoptReason(env, iprofile, branch, arraysize(branch))); } { const char* branch[] = {"", "opt_function1", "opt_function1"}; const char* deopt_reason = - GetBranchDeoptReason(iprofile, branch, arraysize(branch)); + GetBranchDeoptReason(env, iprofile, branch, arraysize(branch)); if (deopt_reason != reason(i::Deoptimizer::kNaN) && deopt_reason != reason(i::Deoptimizer::kLostPrecisionOrNaN)) { FATAL(deopt_reason); @@ -1819,7 +1856,7 @@ TEST(CollectDeoptEvents) { { const char* branch[] = {"", "opt_function2", "opt_function2"}; CHECK_EQ(reason(i::Deoptimizer::kDivisionByZero), - GetBranchDeoptReason(iprofile, branch, arraysize(branch))); + GetBranchDeoptReason(env, iprofile, branch, arraysize(branch))); } iprofiler->DeleteProfile(iprofile); } @@ -1837,7 +1874,10 @@ TEST(SourceLocation) { "}\n" "CompareStatementWithThis();\n"; - v8::Script::Compile(v8_str(source))->Run(); + v8::Script::Compile(env.local(), v8_str(source)) + .ToLocalChecked() + ->Run(env.local()) + .ToLocalChecked(); } @@ -1875,12 +1915,12 @@ TEST(DeoptAtFirstLevelInlinedSource) { "stopProfiling();\n" "\n"; - v8::Handle<v8::Script> inlined_script = v8_compile(inlined_source); - inlined_script->Run(); + v8::Local<v8::Script> inlined_script = v8_compile(inlined_source); + inlined_script->Run(env).ToLocalChecked(); int inlined_script_id = inlined_script->GetUnboundScript()->GetId(); - v8::Handle<v8::Script> script = v8_compile(source); - script->Run(); + v8::Local<v8::Script> script = v8_compile(source); + script->Run(env).ToLocalChecked(); int script_id = script->GetUnboundScript()->GetId(); i::CpuProfile* iprofile = iprofiler->GetProfile(0); @@ -1899,7 +1939,7 @@ TEST(DeoptAtFirstLevelInlinedSource) { const char* branch[] = {"", "test"}; const ProfileNode* itest_node = - GetSimpleBranch(profile, branch, arraysize(branch)); + GetSimpleBranch(env, profile, branch, arraysize(branch)); const std::vector<v8::CpuProfileDeoptInfo>& deopt_infos = itest_node->deopt_infos(); CHECK_EQ(1U, deopt_infos.size()); @@ -1945,12 +1985,12 @@ TEST(DeoptAtSecondLevelInlinedSource) { "stopProfiling();\n" "\n"; - v8::Handle<v8::Script> inlined_script = v8_compile(inlined_source); - inlined_script->Run(); + v8::Local<v8::Script> inlined_script = v8_compile(inlined_source); + inlined_script->Run(env).ToLocalChecked(); int inlined_script_id = inlined_script->GetUnboundScript()->GetId(); - v8::Handle<v8::Script> script = v8_compile(source); - script->Run(); + v8::Local<v8::Script> script = v8_compile(source); + script->Run(env).ToLocalChecked(); int script_id = script->GetUnboundScript()->GetId(); i::CpuProfile* iprofile = iprofiler->GetProfile(0); @@ -1972,7 +2012,7 @@ TEST(DeoptAtSecondLevelInlinedSource) { const char* branch[] = {"", "test1"}; const ProfileNode* itest_node = - GetSimpleBranch(profile, branch, arraysize(branch)); + GetSimpleBranch(env, profile, branch, arraysize(branch)); const std::vector<v8::CpuProfileDeoptInfo>& deopt_infos = itest_node->deopt_infos(); CHECK_EQ(1U, deopt_infos.size()); @@ -2018,11 +2058,11 @@ TEST(DeoptUntrackedFunction) { "stopProfiling();\n" "\n"; - v8::Handle<v8::Script> inlined_script = v8_compile(inlined_source); - inlined_script->Run(); + v8::Local<v8::Script> inlined_script = v8_compile(inlined_source); + inlined_script->Run(env).ToLocalChecked(); - v8::Handle<v8::Script> script = v8_compile(source); - script->Run(); + v8::Local<v8::Script> script = v8_compile(source); + script->Run(env).ToLocalChecked(); i::CpuProfile* iprofile = iprofiler->GetProfile(0); iprofile->Print(); @@ -2030,7 +2070,7 @@ TEST(DeoptUntrackedFunction) { const char* branch[] = {"", "test"}; const ProfileNode* itest_node = - GetSimpleBranch(profile, branch, arraysize(branch)); + GetSimpleBranch(env, profile, branch, arraysize(branch)); CHECK_EQ(0U, itest_node->deopt_infos().size()); iprofiler->DeleteProfile(iprofile); diff --git a/deps/v8/test/cctest/test-date.cc b/deps/v8/test/cctest/test-date.cc index 89372c07ee..67b9501592 100644 --- a/deps/v8/test/cctest/test-date.cc +++ b/deps/v8/test/cctest/test-date.cc @@ -25,9 +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. -// TODO(jochen): Remove this after the setting is turned on globally. -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "src/global-handles.h" @@ -169,31 +166,3 @@ TEST(DaylightSavingsTime) { CheckDST(august_20 + 2 * 3600 - 1000); CheckDST(august_20); } - - -TEST(DateCacheVersion) { - FLAG_allow_natives_syntax = true; - v8::Isolate* isolate = CcTest::isolate(); - v8::Isolate::Scope isolate_scope(isolate); - v8::HandleScope scope(isolate); - v8::Local<v8::Context> context = v8::Context::New(isolate); - v8::Context::Scope context_scope(context); - v8::Local<v8::Array> date_cache_version = - v8::Local<v8::Array>::Cast(CompileRun("%DateCacheVersion()")); - - CHECK_EQ(1, static_cast<int32_t>(date_cache_version->Length())); - CHECK(date_cache_version->Get(context, 0).ToLocalChecked()->IsNumber()); - CHECK_EQ(0.0, date_cache_version->Get(context, 0) - .ToLocalChecked() - ->NumberValue(context) - .FromJust()); - - v8::Date::DateTimeConfigurationChangeNotification(isolate); - - CHECK_EQ(1, static_cast<int32_t>(date_cache_version->Length())); - CHECK(date_cache_version->Get(context, 0).ToLocalChecked()->IsNumber()); - CHECK_EQ(1.0, date_cache_version->Get(context, 0) - .ToLocalChecked() - ->NumberValue(context) - .FromJust()); -} diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc index e1e928f43a..e35227ab23 100644 --- a/deps/v8/test/cctest/test-debug.cc +++ b/deps/v8/test/cctest/test-debug.cc @@ -73,9 +73,9 @@ class DebugLocalContext { public: inline DebugLocalContext( v8::Isolate* isolate, v8::ExtensionConfiguration* extensions = 0, - v8::Handle<v8::ObjectTemplate> global_template = - v8::Handle<v8::ObjectTemplate>(), - v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) + v8::Local<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate>(), + v8::Local<v8::Value> global_object = v8::Local<v8::Value>()) : scope_(isolate), context_(v8::Context::New(isolate, extensions, global_template, global_object)) { @@ -83,9 +83,9 @@ class DebugLocalContext { } inline DebugLocalContext( v8::ExtensionConfiguration* extensions = 0, - v8::Handle<v8::ObjectTemplate> global_template = - v8::Handle<v8::ObjectTemplate>(), - v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>()) + v8::Local<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate>(), + v8::Local<v8::Value> global_object = v8::Local<v8::Value>()) : scope_(CcTest::isolate()), context_(v8::Context::New(CcTest::isolate(), extensions, global_template, global_object)) { @@ -115,7 +115,8 @@ class DebugLocalContext { Handle<v8::internal::String> debug_string = factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("debug")); v8::internal::JSObject::SetOwnPropertyIgnoreAttributes( - global, debug_string, handle(debug_context->global_proxy()), DONT_ENUM) + global, debug_string, handle(debug_context->global_proxy()), + v8::internal::DONT_ENUM) .Check(); } @@ -127,31 +128,29 @@ class DebugLocalContext { // --- H e l p e r F u n c t i o n s - -// Compile and run the supplied source and return the fequested function. -static v8::Local<v8::Function> CompileFunction(DebugLocalContext* env, +// Compile and run the supplied source and return the requested function. +static v8::Local<v8::Function> CompileFunction(v8::Isolate* isolate, const char* source, const char* function_name) { - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source)) - ->Run(); - return v8::Local<v8::Function>::Cast((*env)->Global()->Get( - v8::String::NewFromUtf8(env->GetIsolate(), function_name))); + CompileRunChecked(isolate, source); + v8::Local<v8::String> name = v8_str(isolate, function_name); + v8::Local<v8::Context> context = isolate->GetCurrentContext(); + v8::MaybeLocal<v8::Value> maybe_function = + context->Global()->Get(context, name); + return v8::Local<v8::Function>::Cast(maybe_function.ToLocalChecked()); } // Compile and run the supplied source and return the requested function. -static v8::Local<v8::Function> CompileFunction(v8::Isolate* isolate, +static v8::Local<v8::Function> CompileFunction(DebugLocalContext* env, const char* source, const char* function_name) { - v8::Script::Compile(v8::String::NewFromUtf8(isolate, source))->Run(); - v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(); - return v8::Local<v8::Function>::Cast( - global->Get(v8::String::NewFromUtf8(isolate, function_name))); + return CompileFunction(env->GetIsolate(), source, function_name); } // Is there any debug info for the function? -static bool HasDebugInfo(v8::Handle<v8::Function> fun) { +static bool HasDebugInfo(v8::Local<v8::Function> fun) { Handle<v8::internal::JSFunction> f = Handle<v8::internal::JSFunction>::cast(v8::Utils::OpenHandle(*fun)); Handle<v8::internal::SharedFunctionInfo> shared(f->shared()); @@ -175,7 +174,7 @@ static int SetBreakPoint(Handle<v8::internal::JSFunction> fun, int position) { // Set a break point in a function and return the associated break point // number. -static int SetBreakPoint(v8::Handle<v8::Function> fun, int position) { +static int SetBreakPoint(v8::Local<v8::Function> fun, int position) { return SetBreakPoint( i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*fun)), position); } @@ -191,8 +190,8 @@ static int SetBreakPointFromJS(v8::Isolate* isolate, "debug.Debug.setBreakPoint(%s,%d,%d)", function_name, line, position); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; - v8::Handle<v8::String> str = v8::String::NewFromUtf8(isolate, buffer.start()); - return v8::Script::Compile(str)->Run()->Int32Value(); + v8::Local<v8::Value> value = CompileRunChecked(isolate, buffer.start()); + return value->Int32Value(isolate->GetCurrentContext()).FromJust(); } @@ -214,11 +213,9 @@ static int SetScriptBreakPointByIdFromJS(v8::Isolate* isolate, int script_id, buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; { v8::TryCatch try_catch(isolate); - v8::Handle<v8::String> str = - v8::String::NewFromUtf8(isolate, buffer.start()); - v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run(); + v8::Local<v8::Value> value = CompileRunChecked(isolate, buffer.start()); CHECK(!try_catch.HasCaught()); - return value->Int32Value(); + return value->Int32Value(isolate->GetCurrentContext()).FromJust(); } } @@ -243,11 +240,9 @@ static int SetScriptBreakPointByNameFromJS(v8::Isolate* isolate, buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; { v8::TryCatch try_catch(isolate); - v8::Handle<v8::String> str = - v8::String::NewFromUtf8(isolate, buffer.start()); - v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run(); + v8::Local<v8::Value> value = CompileRunChecked(isolate, buffer.start()); CHECK(!try_catch.HasCaught()); - return value->Int32Value(); + return value->Int32Value(isolate->GetCurrentContext()).FromJust(); } } @@ -269,7 +264,7 @@ static void ClearBreakPointFromJS(v8::Isolate* isolate, "debug.Debug.clearBreakPoint(%d)", break_point_number); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; - v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); + CompileRunChecked(isolate, buffer.start()); } @@ -280,7 +275,7 @@ static void EnableScriptBreakPointFromJS(v8::Isolate* isolate, "debug.Debug.enableScriptBreakPoint(%d)", break_point_number); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; - v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); + CompileRunChecked(isolate, buffer.start()); } @@ -291,7 +286,7 @@ static void DisableScriptBreakPointFromJS(v8::Isolate* isolate, "debug.Debug.disableScriptBreakPoint(%d)", break_point_number); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; - v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); + CompileRunChecked(isolate, buffer.start()); } @@ -303,7 +298,7 @@ static void ChangeScriptBreakPointConditionFromJS(v8::Isolate* isolate, "debug.Debug.changeScriptBreakPointCondition(%d, \"%s\")", break_point_number, condition); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; - v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); + CompileRunChecked(isolate, buffer.start()); } @@ -315,7 +310,7 @@ static void ChangeScriptBreakPointIgnoreCountFromJS(v8::Isolate* isolate, "debug.Debug.changeScriptBreakPointIgnoreCount(%d, %d)", break_point_number, ignoreCount); buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0'; - v8::Script::Compile(v8::String::NewFromUtf8(isolate, buffer.start()))->Run(); + CompileRunChecked(isolate, buffer.start()); } @@ -331,22 +326,14 @@ static void ChangeBreakOnException(bool caught, bool uncaught) { static void ChangeBreakOnExceptionFromJS(v8::Isolate* isolate, bool caught, bool uncaught) { if (caught) { - v8::Script::Compile( - v8::String::NewFromUtf8(isolate, "debug.Debug.setBreakOnException()")) - ->Run(); + CompileRunChecked(isolate, "debug.Debug.setBreakOnException()"); } else { - v8::Script::Compile( - v8::String::NewFromUtf8(isolate, "debug.Debug.clearBreakOnException()")) - ->Run(); + CompileRunChecked(isolate, "debug.Debug.clearBreakOnException()"); } if (uncaught) { - v8::Script::Compile( - v8::String::NewFromUtf8( - isolate, "debug.Debug.setBreakOnUncaughtException()"))->Run(); + CompileRunChecked(isolate, "debug.Debug.setBreakOnUncaughtException()"); } else { - v8::Script::Compile( - v8::String::NewFromUtf8( - isolate, "debug.Debug.clearBreakOnUncaughtException()"))->Run(); + CompileRunChecked(isolate, "debug.Debug.clearBreakOnUncaughtException()"); } } @@ -354,10 +341,13 @@ static void ChangeBreakOnExceptionFromJS(v8::Isolate* isolate, bool caught, // Prepare to step to next break location. static void PrepareStep(StepAction step_action) { v8::internal::Debug* debug = CcTest::i_isolate()->debug(); - debug->PrepareStep(step_action, 1, StackFrame::NO_ID); + debug->PrepareStep(step_action); } +static void ClearStepping() { CcTest::i_isolate()->debug()->ClearStepping(); } + + // This function is in namespace v8::internal to be friend with class // v8::internal::Debug. namespace v8 { @@ -429,9 +419,10 @@ void CheckDebuggerUnloaded(bool check_functions) { // Check that the debugger has been fully unloaded. -static void CheckDebuggerUnloaded(bool check_functions = false) { +static void CheckDebuggerUnloaded(v8::Isolate* isolate, + bool check_functions = false) { // Let debugger to unload itself synchronously - v8::Debug::ProcessDebugMessages(); + v8::Debug::ProcessDebugMessages(isolate); v8::internal::CheckDebuggerUnloaded(check_functions); } @@ -520,7 +511,7 @@ static const char* frame_count_source = "function frame_count(exec_state) {" " return exec_state.frameCount();" "}"; -v8::Handle<v8::Function> frame_count; +v8::Local<v8::Function> frame_count; // Global variable to store the last function hit - used by some tests. @@ -539,7 +530,8 @@ int break_point_hit_count_deoptimize = 0; static void DebugEventBreakPointHitCount( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); - v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); + v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); v8::internal::Isolate* isolate = CcTest::i_isolate(); Debug* debug = isolate->debug(); // When hitting a debug event listener there must be a break set. @@ -551,16 +543,16 @@ static void DebugEventBreakPointHitCount( if (!frame_function_name.IsEmpty()) { // Get the name of the function. const int argc = 2; - v8::Handle<v8::Value> argv[argc] = { - exec_state, v8::Integer::New(CcTest::isolate(), 0) - }; - v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, - argc, argv); + v8::Local<v8::Value> argv[argc] = { + exec_state, v8::Integer::New(CcTest::isolate(), 0)}; + v8::Local<v8::Value> result = + frame_function_name->Call(context, exec_state, argc, argv) + .ToLocalChecked(); if (result->IsUndefined()) { last_function_hit[0] = '\0'; } else { CHECK(result->IsString()); - v8::Handle<v8::String> function_name(result.As<v8::String>()); + v8::Local<v8::String> function_name(result.As<v8::String>()); function_name->WriteUtf8(last_function_hit); } } @@ -568,34 +560,37 @@ static void DebugEventBreakPointHitCount( if (!frame_source_line.IsEmpty()) { // Get the source line. const int argc = 1; - v8::Handle<v8::Value> argv[argc] = { exec_state }; - v8::Handle<v8::Value> result = frame_source_line->Call(exec_state, - argc, argv); + v8::Local<v8::Value> argv[argc] = {exec_state}; + v8::Local<v8::Value> result = + frame_source_line->Call(context, exec_state, argc, argv) + .ToLocalChecked(); CHECK(result->IsNumber()); - last_source_line = result->Int32Value(); + last_source_line = result->Int32Value(context).FromJust(); } if (!frame_source_column.IsEmpty()) { // Get the source column. const int argc = 1; - v8::Handle<v8::Value> argv[argc] = { exec_state }; - v8::Handle<v8::Value> result = frame_source_column->Call(exec_state, - argc, argv); + v8::Local<v8::Value> argv[argc] = {exec_state}; + v8::Local<v8::Value> result = + frame_source_column->Call(context, exec_state, argc, argv) + .ToLocalChecked(); CHECK(result->IsNumber()); - last_source_column = result->Int32Value(); + last_source_column = result->Int32Value(context).FromJust(); } if (!frame_script_name.IsEmpty()) { // Get the script name of the function script. const int argc = 1; - v8::Handle<v8::Value> argv[argc] = { exec_state }; - v8::Handle<v8::Value> result = frame_script_name->Call(exec_state, - argc, argv); + v8::Local<v8::Value> argv[argc] = {exec_state}; + v8::Local<v8::Value> result = + frame_script_name->Call(context, exec_state, argc, argv) + .ToLocalChecked(); if (result->IsUndefined()) { last_script_name_hit[0] = '\0'; } else { CHECK(result->IsString()); - v8::Handle<v8::String> script_name(result.As<v8::String>()); + v8::Local<v8::String> script_name(result.As<v8::String>()); script_name->WriteUtf8(last_script_name_hit); } } @@ -614,7 +609,7 @@ static void DebugEventBreakPointHitCount( int exception_hit_count = 0; int uncaught_exception_hit_count = 0; int last_js_stack_height = -1; -v8::Handle<v8::Function> debug_event_listener_callback; +v8::Local<v8::Function> debug_event_listener_callback; int debug_event_listener_callback_result; static void DebugEventCounterClear() { @@ -626,8 +621,9 @@ static void DebugEventCounterClear() { static void DebugEventCounter( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); - v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); - v8::Handle<v8::Object> event_data = event_details.GetEventData(); + v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); + v8::Local<v8::Object> event_data = event_details.GetEventData(); + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // When hitting a debug event listener there must be a break set. @@ -640,11 +636,11 @@ static void DebugEventCounter( exception_hit_count++; // Check whether the exception was uncaught. - v8::Local<v8::String> fun_name = - v8::String::NewFromUtf8(CcTest::isolate(), "uncaught"); - v8::Local<v8::Function> fun = - v8::Local<v8::Function>::Cast(event_data->Get(fun_name)); - v8::Local<v8::Value> result = fun->Call(event_data, 0, NULL); + v8::Local<v8::String> fun_name = v8_str(CcTest::isolate(), "uncaught"); + v8::Local<v8::Function> fun = v8::Local<v8::Function>::Cast( + event_data->Get(context, fun_name).ToLocalChecked()); + v8::Local<v8::Value> result = + fun->Call(context, event_data, 0, NULL).ToLocalChecked(); if (result->IsTrue()) { uncaught_exception_hit_count++; } @@ -654,18 +650,21 @@ static void DebugEventCounter( // compiled. if (!frame_count.IsEmpty()) { static const int kArgc = 1; - v8::Handle<v8::Value> argv[kArgc] = { exec_state }; + v8::Local<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(); + v8::Local<v8::Value> result = + frame_count->Call(context, exec_state, kArgc, argv).ToLocalChecked(); + last_js_stack_height = result->Int32Value(context).FromJust(); } // Run callback from DebugEventListener and check the result. if (!debug_event_listener_callback.IsEmpty()) { - v8::Handle<v8::Value> result = - debug_event_listener_callback->Call(event_data, 0, NULL); + v8::Local<v8::Value> result = + debug_event_listener_callback->Call(context, event_data, 0, NULL) + .ToLocalChecked(); CHECK(!result.IsEmpty()); - CHECK_EQ(debug_event_listener_callback_result, result->Int32Value()); + CHECK_EQ(debug_event_listener_callback_result, + result->Int32Value(context).FromJust()); } } @@ -680,7 +679,7 @@ static void DebugEventCounter( // Structure for holding checks to do. struct EvaluateCheck { const char* expr; // An expression to evaluate when a break point is hit. - v8::Handle<v8::Value> expected; // The expected result. + v8::Local<v8::Value> expected; // The expected result. }; @@ -698,7 +697,9 @@ v8::Local<v8::Function> evaluate_check_function; static void DebugEventEvaluate( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); - v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); + v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); + v8::Isolate* isolate = CcTest::isolate(); + v8::Local<v8::Context> context = isolate->GetCurrentContext(); v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // When hitting a debug event listener there must be a break set. CHECK_NE(debug->break_id(), 0); @@ -707,12 +708,12 @@ static void DebugEventEvaluate( break_point_hit_count++; for (int i = 0; checks[i].expr != NULL; i++) { const int argc = 3; - v8::Handle<v8::Value> argv[argc] = { - exec_state, - v8::String::NewFromUtf8(CcTest::isolate(), checks[i].expr), - checks[i].expected}; - v8::Handle<v8::Value> result = - evaluate_check_function->Call(exec_state, argc, argv); + v8::Local<v8::String> string = v8_str(isolate, checks[i].expr); + v8::Local<v8::Value> argv[argc] = {exec_state, string, + checks[i].expected}; + v8::Local<v8::Value> result = + evaluate_check_function->Call(context, exec_state, argc, argv) + .ToLocalChecked(); if (!result->IsTrue()) { v8::String::Utf8Value utf8(checks[i].expected); V8_Fatal(__FILE__, __LINE__, "%s != %s", checks[i].expr, *utf8); @@ -727,7 +728,7 @@ int debug_event_remove_break_point = 0; static void DebugEventRemoveBreakPoint( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); - v8::Handle<v8::Value> data = event_details.GetCallbackData(); + v8::Local<v8::Value> data = event_details.GetCallbackData(); v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // When hitting a debug event listener there must be a break set. CHECK_NE(debug->break_id(), 0); @@ -772,7 +773,7 @@ const char* expected_step_sequence = NULL; static void DebugEventStepSequence( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); - v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); + v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); v8::internal::Debug* debug = CcTest::i_isolate()->debug(); // When hitting a debug event listener there must be a break set. CHECK_NE(debug->break_id(), 0); @@ -782,13 +783,15 @@ static void DebugEventStepSequence( CHECK(break_point_hit_count < StrLength(expected_step_sequence)); const int argc = 2; - v8::Handle<v8::Value> argv[argc] = { - exec_state, v8::Integer::New(CcTest::isolate(), 0) - }; - v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, - argc, argv); + v8::Local<v8::Value> argv[argc] = {exec_state, + v8::Integer::New(CcTest::isolate(), 0)}; + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); + v8::Local<v8::Value> result = + frame_function_name->Call(context, exec_state, argc, argv) + .ToLocalChecked(); CHECK(result->IsString()); - v8::String::Utf8Value function_name(result->ToString(CcTest::isolate())); + v8::String::Utf8Value function_name( + result->ToString(context).ToLocalChecked()); CHECK_EQ(1, StrLength(*function_name)); CHECK_EQ((*function_name)[0], expected_step_sequence[break_point_hit_count]); @@ -870,7 +873,7 @@ static void DebugEventBreakMax( } else if (terminate_after_max_break_point_hit) { // Terminate execution after the last break if requested. - v8::V8::TerminateExecution(v8_isolate); + v8_isolate->TerminateExecution(); } // Perform a full deoptimization when the specified number of @@ -892,8 +895,8 @@ static void MessageCallbackCountClear() { message_callback_count = 0; } -static void MessageCallbackCount(v8::Handle<v8::Message> message, - v8::Handle<v8::Value> data) { +static void MessageCallbackCount(v8::Local<v8::Message> message, + v8::Local<v8::Value> data) { message_callback_count++; } @@ -914,7 +917,7 @@ TEST(DebugInfo) { CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length()); CHECK(!HasDebugInfo(foo)); CHECK(!HasDebugInfo(bar)); - EnableDebugger(); + EnableDebugger(env->GetIsolate()); // One function (foo) is debugged. int bp1 = SetBreakPoint(foo, 0); CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length()); @@ -932,7 +935,7 @@ TEST(DebugInfo) { CHECK(HasDebugInfo(bar)); // No functions are debugged. ClearBreakPoint(bp2); - DisableDebugger(); + DisableDebugger(env->GetIsolate()); CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length()); CHECK(!HasDebugInfo(foo)); CHECK(!HasDebugInfo(bar)); @@ -945,30 +948,29 @@ TEST(BreakPointICStore) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), - "function foo(){bar=0;}"))->Run(); - v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); + v8::Local<v8::Function> foo = + CompileFunction(&env, "function foo(){bar=0;}", "foo"); // Run without breakpoints. - foo->Call(env->Global(), 0, NULL); + foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Run with breakpoint int bp = SetBreakPoint(foo, 0); - foo->Call(env->Global(), 0, NULL); + foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); - foo->Call(env->Global(), 0, NULL); + foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); // Run without breakpoints. ClearBreakPoint(bp); - foo->Call(env->Global(), 0, NULL); + foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -977,33 +979,31 @@ TEST(BreakPointICLoad) { break_point_hit_count = 0; DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "bar=1")) - ->Run(); - v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){var x=bar;}")) - ->Run(); - v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); + + CompileRunChecked(env->GetIsolate(), "bar=1"); + v8::Local<v8::Function> foo = + CompileFunction(&env, "function foo(){var x=bar;}", "foo"); // Run without breakpoints. - foo->Call(env->Global(), 0, NULL); + foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Run with breakpoint. int bp = SetBreakPoint(foo, 0); - foo->Call(env->Global(), 0, NULL); + foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); - foo->Call(env->Global(), 0, NULL); + foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); // Run without breakpoints. ClearBreakPoint(bp); - foo->Call(env->Global(), 0, NULL); + foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -1012,32 +1012,30 @@ TEST(BreakPointICCall) { break_point_hit_count = 0; DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); - v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){}"))->Run(); - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), - "function foo(){bar();}"))->Run(); - v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); + CompileRunChecked(env->GetIsolate(), "function bar(){}"); + v8::Local<v8::Function> foo = + CompileFunction(&env, "function foo(){bar();}", "foo"); // Run without breakpoints. - foo->Call(env->Global(), 0, NULL); + foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Run with breakpoint int bp = SetBreakPoint(foo, 0); - foo->Call(env->Global(), 0, NULL); + foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); - foo->Call(env->Global(), 0, NULL); + foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); // Run without breakpoints. ClearBreakPoint(bp); - foo->Call(env->Global(), 0, NULL); + foo->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -1046,34 +1044,40 @@ TEST(BreakPointICCallWithGC) { break_point_hit_count = 0; DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage); - v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){return 1;}")) - ->Run(); - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), - "function foo(){return bar();}")) - ->Run(); - v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointCollectGarbage); + CompileRunChecked(env->GetIsolate(), "function bar(){return 1;}"); + v8::Local<v8::Function> foo = + CompileFunction(&env, "function foo(){return bar();}", "foo"); + v8::Local<v8::Context> context = env.context(); // Run without breakpoints. - CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); + CHECK_EQ(1, foo->Call(context, env->Global(), 0, NULL) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); CHECK_EQ(0, break_point_hit_count); // Run with breakpoint. int bp = SetBreakPoint(foo, 0); - CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); + CHECK_EQ(1, foo->Call(context, env->Global(), 0, NULL) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); CHECK_EQ(1, break_point_hit_count); - CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); + CHECK_EQ(1, foo->Call(context, env->Global(), 0, NULL) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); CHECK_EQ(2, break_point_hit_count); // Run without breakpoints. ClearBreakPoint(bp); - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -1082,34 +1086,40 @@ TEST(BreakPointConstructCallWithGC) { break_point_hit_count = 0; DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage); - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), - "function bar(){ this.x = 1;}")) - ->Run(); - v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), - "function foo(){return new bar(1).x;}"))->Run(); - v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointCollectGarbage); + CompileRunChecked(env->GetIsolate(), "function bar(){ this.x = 1;}"); + v8::Local<v8::Function> foo = + CompileFunction(&env, "function foo(){return new bar(1).x;}", "foo"); + v8::Local<v8::Context> context = env.context(); // Run without breakpoints. - CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); + CHECK_EQ(1, foo->Call(context, env->Global(), 0, NULL) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); CHECK_EQ(0, break_point_hit_count); // Run with breakpoint. int bp = SetBreakPoint(foo, 0); - CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); + CHECK_EQ(1, foo->Call(context, env->Global(), 0, NULL) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); CHECK_EQ(1, break_point_hit_count); - CHECK_EQ(1, foo->Call(env->Global(), 0, NULL)->Int32Value()); + CHECK_EQ(1, foo->Call(context, env->Global(), 0, NULL) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); CHECK_EQ(2, break_point_hit_count); // Run without breakpoints. ClearBreakPoint(bp); - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -1129,44 +1139,44 @@ TEST(BreakPointReturn) { "frame_source_column"); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); - v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){}"))->Run(); - v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); + v8::Local<v8::Function> foo = + CompileFunction(&env, "function foo(){}", "foo"); + v8::Local<v8::Context> context = env.context(); // Run without breakpoints. - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Run with breakpoint int bp = SetBreakPoint(foo, 0); - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); CHECK_EQ(0, last_source_line); CHECK_EQ(15, last_source_column); - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); CHECK_EQ(0, last_source_line); CHECK_EQ(15, last_source_column); // Run without breakpoints. ClearBreakPoint(bp); - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } -static void CallWithBreakPoints(v8::Local<v8::Object> recv, +static void CallWithBreakPoints(v8::Local<v8::Context> context, + v8::Local<v8::Object> recv, v8::Local<v8::Function> f, - int break_point_count, - int call_count) { + int break_point_count, int call_count) { break_point_hit_count = 0; for (int i = 0; i < call_count; i++) { - f->Call(recv, 0, NULL); + f->Call(context, recv, 0, NULL).ToLocalChecked(); CHECK_EQ((i + 1) * break_point_count, break_point_hit_count); } } @@ -1177,59 +1187,61 @@ TEST(GCDuringBreakPointProcessing) { break_point_hit_count = 0; DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::Context> context = env.context(); - v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointCollectGarbage); v8::Local<v8::Function> foo; // Test IC store break point with garbage collection. foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); SetBreakPoint(foo, 0); - CallWithBreakPoints(env->Global(), foo, 1, 10); + CallWithBreakPoints(context, env->Global(), foo, 1, 10); // Test IC load break point with garbage collection. foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); SetBreakPoint(foo, 0); - CallWithBreakPoints(env->Global(), foo, 1, 10); + CallWithBreakPoints(context, env->Global(), foo, 1, 10); // Test IC call break point with garbage collection. foo = CompileFunction(&env, "function bar(){};function foo(){bar();}", "foo"); SetBreakPoint(foo, 0); - CallWithBreakPoints(env->Global(), foo, 1, 10); + CallWithBreakPoints(context, env->Global(), foo, 1, 10); // Test return break point with garbage collection. foo = CompileFunction(&env, "function foo(){}", "foo"); SetBreakPoint(foo, 0); - CallWithBreakPoints(env->Global(), foo, 1, 25); + CallWithBreakPoints(context, env->Global(), foo, 1, 25); // Test debug break slot break point with garbage collection. foo = CompileFunction(&env, "function foo(){var a;}", "foo"); SetBreakPoint(foo, 0); - CallWithBreakPoints(env->Global(), foo, 1, 25); + CallWithBreakPoints(context, env->Global(), foo, 1, 25); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } // Call the function three times with different garbage collections in between // and make sure that the break point survives. -static void CallAndGC(v8::Local<v8::Object> recv, - v8::Local<v8::Function> f) { +static void CallAndGC(v8::Local<v8::Context> context, + v8::Local<v8::Object> recv, v8::Local<v8::Function> f) { break_point_hit_count = 0; for (int i = 0; i < 3; i++) { // Call function. - f->Call(recv, 0, NULL); + f->Call(context, recv, 0, NULL).ToLocalChecked(); CHECK_EQ(1 + i * 3, break_point_hit_count); // Scavenge and call function. CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE); - f->Call(recv, 0, NULL); + f->Call(context, recv, 0, NULL).ToLocalChecked(); CHECK_EQ(2 + i * 3, break_point_hit_count); // Mark sweep (and perhaps compact) and call function. CcTest::heap()->CollectAllGarbage(); - f->Call(recv, 0, NULL); + f->Call(context, recv, 0, NULL).ToLocalChecked(); CHECK_EQ(3 + i * 3, break_point_hit_count); } } @@ -1240,8 +1252,10 @@ TEST(BreakPointSurviveGC) { break_point_hit_count = 0; DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::Context> context = env.context(); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); v8::Local<v8::Function> foo; // Test IC store break point with garbage collection. @@ -1250,7 +1264,7 @@ TEST(BreakPointSurviveGC) { foo = CompileFunction(&env, "function foo(){bar=0;}", "foo"); SetBreakPoint(foo, 0); } - CallAndGC(env->Global(), foo); + CallAndGC(context, env->Global(), foo); // Test IC load break point with garbage collection. { @@ -1258,7 +1272,7 @@ TEST(BreakPointSurviveGC) { foo = CompileFunction(&env, "bar=1;function foo(){var x=bar;}", "foo"); SetBreakPoint(foo, 0); } - CallAndGC(env->Global(), foo); + CallAndGC(context, env->Global(), foo); // Test IC call break point with garbage collection. { @@ -1268,7 +1282,7 @@ TEST(BreakPointSurviveGC) { "foo"); SetBreakPoint(foo, 0); } - CallAndGC(env->Global(), foo); + CallAndGC(context, env->Global(), foo); // Test return break point with garbage collection. { @@ -1276,7 +1290,7 @@ TEST(BreakPointSurviveGC) { foo = CompileFunction(&env, "function foo(){}", "foo"); SetBreakPoint(foo, 0); } - CallAndGC(env->Global(), foo); + CallAndGC(context, env->Global(), foo); // Test non IC break point with garbage collection. { @@ -1284,11 +1298,11 @@ TEST(BreakPointSurviveGC) { foo = CompileFunction(&env, "function foo(){var bar=0;}", "foo"); SetBreakPoint(foo, 0); } - CallAndGC(env->Global(), foo); + CallAndGC(context, env->Global(), foo); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -1296,53 +1310,51 @@ TEST(BreakPointSurviveGC) { TEST(BreakPointThroughJavaScript) { break_point_hit_count = 0; DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Local<v8::Context> context = env.context(); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); - v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){}"))->Run(); - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), - "function foo(){bar();bar();}")) - ->Run(); - // 012345678901234567890 - // 1 2 + v8::Debug::SetDebugEventListener(isolate, DebugEventBreakPointHitCount); + CompileRunChecked(isolate, "function bar(){}"); + CompileFunction(isolate, "function foo(){bar();bar();}", "foo"); + // 012345678901234567890 + // 1 2 // Break points are set at position 3 and 9 + v8::Local<v8::String> source = v8_str(env->GetIsolate(), "foo()"); v8::Local<v8::Script> foo = - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "foo()")); + v8::Script::Compile(context, source).ToLocalChecked(); - // Run without breakpoints. - foo->Run(); CHECK_EQ(0, break_point_hit_count); // Run with one breakpoint int bp1 = SetBreakPointFromJS(env->GetIsolate(), "foo", 0, 3); - foo->Run(); + foo->Run(context).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); - foo->Run(); + foo->Run(context).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); // Run with two breakpoints int bp2 = SetBreakPointFromJS(env->GetIsolate(), "foo", 0, 9); - foo->Run(); + foo->Run(context).ToLocalChecked(); CHECK_EQ(4, break_point_hit_count); - foo->Run(); + foo->Run(context).ToLocalChecked(); CHECK_EQ(6, break_point_hit_count); // Run with one breakpoint ClearBreakPointFromJS(env->GetIsolate(), bp2); - foo->Run(); + foo->Run(context).ToLocalChecked(); CHECK_EQ(7, break_point_hit_count); - foo->Run(); + foo->Run(context).ToLocalChecked(); CHECK_EQ(8, break_point_hit_count); // Run without breakpoints. ClearBreakPointFromJS(env->GetIsolate(), bp1); - foo->Run(); + foo->Run(context).ToLocalChecked(); CHECK_EQ(8, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); // Make sure that the break point numbers are consecutive. CHECK_EQ(1, bp1); @@ -1355,96 +1367,99 @@ TEST(BreakPointThroughJavaScript) { TEST(ScriptBreakPointByNameThroughJavaScript) { break_point_hit_count = 0; DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Local<v8::Context> context = env.context(); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); - - v8::Local<v8::String> script = v8::String::NewFromUtf8( - env->GetIsolate(), - "function f() {\n" - " function h() {\n" - " a = 0; // line 2\n" - " }\n" - " b = 1; // line 4\n" - " return h();\n" - "}\n" - "\n" - "function g() {\n" - " function h() {\n" - " a = 0;\n" - " }\n" - " b = 2; // line 12\n" - " h();\n" - " b = 3; // line 14\n" - " f(); // line 15\n" - "}"); + v8::Debug::SetDebugEventListener(isolate, DebugEventBreakPointHitCount); + + v8::Local<v8::String> script = v8_str(isolate, + "function f() {\n" + " function h() {\n" + " a = 0; // line 2\n" + " }\n" + " b = 1; // line 4\n" + " return h();\n" + "}\n" + "\n" + "function g() {\n" + " function h() {\n" + " a = 0;\n" + " }\n" + " b = 2; // line 12\n" + " h();\n" + " b = 3; // line 14\n" + " f(); // line 15\n" + "}"); // Compile the script and get the two functions. - v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); - v8::Script::Compile(script, &origin)->Run(); + v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str(isolate, "test")); + v8::Script::Compile(context, script, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global()->Get(context, v8_str(isolate, "f")).ToLocalChecked()); v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); + env->Global()->Get(context, v8_str(isolate, "g")).ToLocalChecked()); // Call f and g without break points. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Call f and g with break point on line 12. - int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 12, 0); + int sbp1 = SetScriptBreakPointByNameFromJS(isolate, "test", 12, 0); break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); // Remove the break point again. break_point_hit_count = 0; ClearBreakPointFromJS(env->GetIsolate(), sbp1); - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Call f and g with break point on line 2. int sbp2 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 2, 0); break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); // Call f and g with break point on line 2, 4, 12, 14 and 15. - int sbp3 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 4, 0); - int sbp4 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 12, 0); - int sbp5 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 14, 0); - int sbp6 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 15, 0); + int sbp3 = SetScriptBreakPointByNameFromJS(isolate, "test", 4, 0); + int sbp4 = SetScriptBreakPointByNameFromJS(isolate, "test", 12, 0); + int sbp5 = SetScriptBreakPointByNameFromJS(isolate, "test", 14, 0); + int sbp6 = SetScriptBreakPointByNameFromJS(isolate, "test", 15, 0); break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(7, break_point_hit_count); // Remove all the break points again. break_point_hit_count = 0; - ClearBreakPointFromJS(env->GetIsolate(), sbp2); - ClearBreakPointFromJS(env->GetIsolate(), sbp3); - ClearBreakPointFromJS(env->GetIsolate(), sbp4); - ClearBreakPointFromJS(env->GetIsolate(), sbp5); - ClearBreakPointFromJS(env->GetIsolate(), sbp6); - f->Call(env->Global(), 0, NULL); + ClearBreakPointFromJS(isolate, sbp2); + ClearBreakPointFromJS(isolate, sbp3); + ClearBreakPointFromJS(isolate, sbp4); + ClearBreakPointFromJS(isolate, sbp5); + ClearBreakPointFromJS(isolate, sbp6); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); // Make sure that the break point numbers are consecutive. CHECK_EQ(1, sbp1); @@ -1459,73 +1474,74 @@ TEST(ScriptBreakPointByNameThroughJavaScript) { TEST(ScriptBreakPointByIdThroughJavaScript) { break_point_hit_count = 0; DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Local<v8::Context> context = env.context(); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); - - v8::Local<v8::String> source = v8::String::NewFromUtf8( - env->GetIsolate(), - "function f() {\n" - " function h() {\n" - " a = 0; // line 2\n" - " }\n" - " b = 1; // line 4\n" - " return h();\n" - "}\n" - "\n" - "function g() {\n" - " function h() {\n" - " a = 0;\n" - " }\n" - " b = 2; // line 12\n" - " h();\n" - " b = 3; // line 14\n" - " f(); // line 15\n" - "}"); + v8::Debug::SetDebugEventListener(isolate, DebugEventBreakPointHitCount); + + v8::Local<v8::String> source = v8_str(isolate, + "function f() {\n" + " function h() {\n" + " a = 0; // line 2\n" + " }\n" + " b = 1; // line 4\n" + " return h();\n" + "}\n" + "\n" + "function g() {\n" + " function h() {\n" + " a = 0;\n" + " }\n" + " b = 2; // line 12\n" + " h();\n" + " b = 3; // line 14\n" + " f(); // line 15\n" + "}"); // Compile the script and get the two functions. - v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); - v8::Local<v8::Script> script = v8::Script::Compile(source, &origin); - script->Run(); + v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str(isolate, "test")); + v8::Local<v8::Script> script = + v8::Script::Compile(context, source, &origin).ToLocalChecked(); + script->Run(context).ToLocalChecked(); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global()->Get(context, v8_str(isolate, "f")).ToLocalChecked()); v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); + env->Global()->Get(context, v8_str(isolate, "g")).ToLocalChecked()); // Get the script id knowing that internally it is a 32 integer. int script_id = script->GetUnboundScript()->GetId(); // Call f and g without break points. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Call f and g with break point on line 12. int sbp1 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 12, 0); break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); // Remove the break point again. break_point_hit_count = 0; ClearBreakPointFromJS(env->GetIsolate(), sbp1); - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Call f and g with break point on line 2. int sbp2 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 2, 0); break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); // Call f and g with break point on line 2, 4, 12, 14 and 15. @@ -1534,9 +1550,9 @@ TEST(ScriptBreakPointByIdThroughJavaScript) { int sbp5 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 14, 0); int sbp6 = SetScriptBreakPointByIdFromJS(env->GetIsolate(), script_id, 15, 0); break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(7, break_point_hit_count); // Remove all the break points again. @@ -1546,13 +1562,13 @@ TEST(ScriptBreakPointByIdThroughJavaScript) { ClearBreakPointFromJS(env->GetIsolate(), sbp4); ClearBreakPointFromJS(env->GetIsolate(), sbp5); ClearBreakPointFromJS(env->GetIsolate(), sbp6); - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); // Make sure that the break point numbers are consecutive. CHECK_EQ(1, sbp1); @@ -1568,57 +1584,63 @@ TEST(ScriptBreakPointByIdThroughJavaScript) { TEST(EnableDisableScriptBreakPoint) { break_point_hit_count = 0; DebugLocalContext env; - v8::HandleScope scope(env->GetIsolate()); + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Local<v8::Context> context = env.context(); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(isolate, DebugEventBreakPointHitCount); - v8::Local<v8::String> script = v8::String::NewFromUtf8( - env->GetIsolate(), - "function f() {\n" - " a = 0; // line 1\n" - "};"); + v8::Local<v8::String> script = v8_str(isolate, + "function f() {\n" + " a = 0; // line 1\n" + "};"); // Compile the script and get function f. - v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); - v8::Script::Compile(script, &origin)->Run(); + v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str(isolate, "test")); + v8::Script::Compile(context, script, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global()->Get(context, v8_str(isolate, "f")).ToLocalChecked()); // Set script break point on line 1 (in function f). - int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); + int sbp = SetScriptBreakPointByNameFromJS(isolate, "test", 1, 0); // Call f while enabeling and disabling the script break point. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); - DisableScriptBreakPointFromJS(env->GetIsolate(), sbp); - f->Call(env->Global(), 0, NULL); + DisableScriptBreakPointFromJS(isolate, sbp); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); - EnableScriptBreakPointFromJS(env->GetIsolate(), sbp); - f->Call(env->Global(), 0, NULL); + EnableScriptBreakPointFromJS(isolate, sbp); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); - DisableScriptBreakPointFromJS(env->GetIsolate(), sbp); - f->Call(env->Global(), 0, NULL); + DisableScriptBreakPointFromJS(isolate, sbp); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); - // Reload the script and get f again checking that the disabeling survives. - v8::Script::Compile(script, &origin)->Run(); + // Reload the script and get f again checking that the disabling survives. + v8::Script::Compile(context, script, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); - f->Call(env->Global(), 0, NULL); + env->Global()->Get(context, v8_str(isolate, "f")).ToLocalChecked()); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); - EnableScriptBreakPointFromJS(env->GetIsolate(), sbp); - f->Call(env->Global(), 0, NULL); + EnableScriptBreakPointFromJS(isolate, sbp); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(3, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -1629,24 +1651,29 @@ TEST(ConditionalScriptBreakPoint) { v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); - v8::Local<v8::String> script = v8::String::NewFromUtf8( - env->GetIsolate(), - "count = 0;\n" - "function f() {\n" - " g(count++); // line 2\n" - "};\n" - "function g(x) {\n" - " var a=x; // line 5\n" - "};"); + v8::Local<v8::String> script = v8_str(env->GetIsolate(), + "count = 0;\n" + "function f() {\n" + " g(count++); // line 2\n" + "};\n" + "function g(x) {\n" + " var a=x; // line 5\n" + "};"); // Compile the script and get function f. - v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); - v8::Script::Compile(script, &origin)->Run(); + v8::Local<v8::Context> context = env.context(); + v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str(env->GetIsolate(), "test")); + v8::Script::Compile(context, script, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); // Set script break point on line 5 (in function g). int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 5, 0); @@ -1654,34 +1681,39 @@ TEST(ConditionalScriptBreakPoint) { // Call f with different conditions on the script break point. break_point_hit_count = 0; ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "false"); - f->Call(env->Global(), 0, NULL); + f->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "true"); break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); ChangeScriptBreakPointConditionFromJS(env->GetIsolate(), sbp1, "x % 2 == 0"); break_point_hit_count = 0; for (int i = 0; i < 10; i++) { - f->Call(env->Global(), 0, NULL); + f->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); } CHECK_EQ(5, break_point_hit_count); // Reload the script and get f again checking that the condition survives. - v8::Script::Compile(script, &origin)->Run(); + v8::Script::Compile(context, script, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); break_point_hit_count = 0; for (int i = 0; i < 10; i++) { - f->Call(env->Global(), 0, NULL); + f->Call(env.context(), env->Global(), 0, NULL).ToLocalChecked(); } CHECK_EQ(5, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -1692,20 +1724,25 @@ TEST(ScriptBreakPointIgnoreCount) { v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); - v8::Local<v8::String> script = v8::String::NewFromUtf8( - env->GetIsolate(), - "function f() {\n" - " a = 0; // line 1\n" - "};"); + v8::Local<v8::String> script = v8_str(env->GetIsolate(), + "function f() {\n" + " a = 0; // line 1\n" + "};"); // Compile the script and get function f. - v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); - v8::Script::Compile(script, &origin)->Run(); + v8::Local<v8::Context> context = env.context(); + v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str(env->GetIsolate(), "test")); + v8::Script::Compile(context, script, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); // Set script break point on line 1 (in function f). int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); @@ -1713,31 +1750,36 @@ TEST(ScriptBreakPointIgnoreCount) { // Call f with different ignores on the script break point. break_point_hit_count = 0; ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 1); - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); ChangeScriptBreakPointIgnoreCountFromJS(env->GetIsolate(), sbp, 5); break_point_hit_count = 0; for (int i = 0; i < 10; i++) { - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); } CHECK_EQ(5, break_point_hit_count); // Reload the script and get f again checking that the ignore survives. - v8::Script::Compile(script, &origin)->Run(); + v8::Script::Compile(context, script, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); break_point_hit_count = 0; for (int i = 0; i < 10; i++) { - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); } CHECK_EQ(5, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -1748,60 +1790,74 @@ TEST(ScriptBreakPointReload) { v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); + v8::Local<v8::Context> context = env.context(); v8::Local<v8::Function> f; - v8::Local<v8::String> script = v8::String::NewFromUtf8( - env->GetIsolate(), - "function f() {\n" - " function h() {\n" - " a = 0; // line 2\n" - " }\n" - " b = 1; // line 4\n" - " return h();\n" - "}"); - - v8::ScriptOrigin origin_1 = - v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "1")); - v8::ScriptOrigin origin_2 = - v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "2")); + v8::Local<v8::String> script = v8_str(env->GetIsolate(), + "function f() {\n" + " function h() {\n" + " a = 0; // line 2\n" + " }\n" + " b = 1; // line 4\n" + " return h();\n" + "}"); + + v8::ScriptOrigin origin_1 = v8::ScriptOrigin(v8_str(env->GetIsolate(), "1")); + v8::ScriptOrigin origin_2 = v8::ScriptOrigin(v8_str(env->GetIsolate(), "2")); // Set a script break point before the script is loaded. SetScriptBreakPointByNameFromJS(env->GetIsolate(), "1", 2, 0); // Compile the script and get the function. - v8::Script::Compile(script, &origin_1)->Run(); + v8::Script::Compile(context, script, &origin_1) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); // Call f and check that the script break point is active. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); // Compile the script again with a different script data and get the // function. - v8::Script::Compile(script, &origin_2)->Run(); + v8::Script::Compile(context, script, &origin_2) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); // Call f and check that no break points are set. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Compile the script again and get the function. - v8::Script::Compile(script, &origin_1)->Run(); + v8::Script::Compile(context, script, &origin_1) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); // Call f and check that the script break point is active. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -1812,41 +1868,50 @@ TEST(ScriptBreakPointMultiple) { v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); + v8::Local<v8::Context> context = env.context(); v8::Local<v8::Function> f; - v8::Local<v8::String> script_f = - v8::String::NewFromUtf8(env->GetIsolate(), - "function f() {\n" - " a = 0; // line 1\n" - "}"); + v8::Local<v8::String> script_f = v8_str(env->GetIsolate(), + "function f() {\n" + " a = 0; // line 1\n" + "}"); v8::Local<v8::Function> g; - v8::Local<v8::String> script_g = - v8::String::NewFromUtf8(env->GetIsolate(), - "function g() {\n" - " b = 0; // line 1\n" - "}"); + v8::Local<v8::String> script_g = v8_str(env->GetIsolate(), + "function g() {\n" + " b = 0; // line 1\n" + "}"); - v8::ScriptOrigin origin = - v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test")); + v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str(env->GetIsolate(), "test")); // Set a script break point before the scripts are loaded. int sbp = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test", 1, 0); // Compile the scripts with same script data and get the functions. - v8::Script::Compile(script_f, &origin)->Run(); + v8::Script::Compile(context, script_f, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); - v8::Script::Compile(script_g, &origin)->Run(); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); + v8::Script::Compile(context, script_g, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); g = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "g")) + .ToLocalChecked()); // Call f and g and check that the script break point is active. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); // Clear the script break point. @@ -1854,9 +1919,9 @@ TEST(ScriptBreakPointMultiple) { // Call f and g and check that the script break point is no longer active. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Set script break point with the scripts loaded. @@ -1864,13 +1929,13 @@ TEST(ScriptBreakPointMultiple) { // Call f and g and check that the script break point is active. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -1881,20 +1946,21 @@ TEST(ScriptBreakPointLineOffset) { v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); + v8::Local<v8::Context> context = env.context(); v8::Local<v8::Function> f; - v8::Local<v8::String> script = v8::String::NewFromUtf8( - env->GetIsolate(), - "function f() {\n" - " a = 0; // line 8 as this script has line offset 7\n" - " b = 0; // line 9 as this script has line offset 7\n" - "}"); + v8::Local<v8::String> script = + v8_str(env->GetIsolate(), + "function f() {\n" + " a = 0; // line 8 as this script has line offset 7\n" + " b = 0; // line 9 as this script has line offset 7\n" + "}"); // Create script origin both name and line offset. - v8::ScriptOrigin origin( - v8::String::NewFromUtf8(env->GetIsolate(), "test.html"), - v8::Integer::New(env->GetIsolate(), 7)); + v8::ScriptOrigin origin(v8_str(env->GetIsolate(), "test.html"), + v8::Integer::New(env->GetIsolate(), 7)); // Set two script break points before the script is loaded. int sbp1 = @@ -1903,13 +1969,18 @@ TEST(ScriptBreakPointLineOffset) { SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 9, 0); // Compile the script and get the function. - v8::Script::Compile(script, &origin)->Run(); + v8::Script::Compile(context, script, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); // Call f and check that the script break point is active. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); // Clear the script break points. @@ -1918,7 +1989,7 @@ TEST(ScriptBreakPointLineOffset) { // Call f and check that no script break points are active. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Set a script break point with the script loaded. @@ -1926,11 +1997,11 @@ TEST(ScriptBreakPointLineOffset) { // Call f and check that the script break point is active. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -1945,25 +2016,27 @@ TEST(ScriptBreakPointLine) { frame_function_name_source, "frame_function_name"); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); + v8::Local<v8::Context> context = env.context(); v8::Local<v8::Function> f; v8::Local<v8::Function> g; v8::Local<v8::String> script = - v8::String::NewFromUtf8(env->GetIsolate(), - "a = 0 // line 0\n" - "function f() {\n" - " a = 1; // line 2\n" - "}\n" - " a = 2; // line 4\n" - " /* xx */ function g() { // line 5\n" - " function h() { // line 6\n" - " a = 3; // line 7\n" - " }\n" - " h(); // line 9\n" - " a = 4; // line 10\n" - " }\n" - " a=5; // line 12"); + v8_str(env->GetIsolate(), + "a = 0 // line 0\n" + "function f() {\n" + " a = 1; // line 2\n" + "}\n" + " a = 2; // line 4\n" + " /* xx */ function g() { // line 5\n" + " function h() { // line 6\n" + " a = 3; // line 7\n" + " }\n" + " h(); // line 9\n" + " a = 4; // line 10\n" + " }\n" + " a=5; // line 12"); // Set a couple script break point before the script is loaded. int sbp1 = @@ -1975,26 +2048,32 @@ TEST(ScriptBreakPointLine) { // Compile the script and get the function. break_point_hit_count = 0; - v8::ScriptOrigin origin( - v8::String::NewFromUtf8(env->GetIsolate(), "test.html"), - v8::Integer::New(env->GetIsolate(), 0)); - v8::Script::Compile(script, &origin)->Run(); + v8::ScriptOrigin origin(v8_str(env->GetIsolate(), "test.html"), + v8::Integer::New(env->GetIsolate(), 0)); + v8::Script::Compile(context, script, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); g = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "g")) + .ToLocalChecked()); // Check that a break point was hit when the script was run. CHECK_EQ(1, break_point_hit_count); CHECK_EQ(0, StrLength(last_function_hit)); // Call f and check that the script break point. - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); CHECK_EQ(0, strcmp("f", last_function_hit)); // Call g and check that the script break point. - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(3, break_point_hit_count); CHECK_EQ(0, strcmp("g", last_function_hit)); @@ -2004,7 +2083,7 @@ TEST(ScriptBreakPointLine) { SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 6, -1); // Call g and check that the script break point in h is hit. - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(4, break_point_hit_count); CHECK_EQ(0, strcmp("h", last_function_hit)); @@ -2016,13 +2095,16 @@ TEST(ScriptBreakPointLine) { int sbp5 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 4, -1); break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); - g->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Reload the script which should hit two break points. break_point_hit_count = 0; - v8::Script::Compile(script, &origin)->Run(); + v8::Script::Compile(context, script, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); CHECK_EQ(0, StrLength(last_function_hit)); @@ -2032,7 +2114,10 @@ TEST(ScriptBreakPointLine) { // Reload the script which should hit three break points. break_point_hit_count = 0; - v8::Script::Compile(script, &origin)->Run(); + v8::Script::Compile(context, script, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); CHECK_EQ(3, break_point_hit_count); CHECK_EQ(0, StrLength(last_function_hit)); @@ -2042,11 +2127,14 @@ TEST(ScriptBreakPointLine) { ClearBreakPointFromJS(env->GetIsolate(), sbp5); ClearBreakPointFromJS(env->GetIsolate(), sbp6); break_point_hit_count = 0; - v8::Script::Compile(script, &origin)->Run(); + v8::Script::Compile(context, script, &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2056,21 +2144,25 @@ TEST(ScriptBreakPointLineTopLevel) { v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); + v8::Local<v8::Context> context = env.context(); v8::Local<v8::String> script = - v8::String::NewFromUtf8(env->GetIsolate(), - "function f() {\n" - " a = 1; // line 1\n" - "}\n" - "a = 2; // line 3\n"); + v8_str(env->GetIsolate(), + "function f() {\n" + " a = 1; // line 1\n" + "}\n" + "a = 2; // line 3\n"); v8::Local<v8::Function> f; { v8::HandleScope scope(env->GetIsolate()); CompileRunWithOrigin(script, "test.html"); } f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); CcTest::heap()->CollectAllGarbage(); @@ -2078,7 +2170,7 @@ TEST(ScriptBreakPointLineTopLevel) { // Call f and check that there was no break points. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Recompile and run script and check that break point was hit. @@ -2089,11 +2181,13 @@ TEST(ScriptBreakPointLineTopLevel) { // Call f and check that there are still no break points. break_point_hit_count = 0; f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); CHECK_EQ(0, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2104,14 +2198,14 @@ TEST(ScriptBreakPointTopLevelCrash) { v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); - v8::Local<v8::String> script_source = - v8::String::NewFromUtf8(env->GetIsolate(), - "function f() {\n" - " return 0;\n" - "}\n" - "f()"); + v8::Local<v8::String> script_source = v8_str(env->GetIsolate(), + "function f() {\n" + " return 0;\n" + "}\n" + "f()"); int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), "test.html", 3, -1); @@ -2127,8 +2221,8 @@ TEST(ScriptBreakPointTopLevelCrash) { ClearBreakPointFromJS(env->GetIsolate(), sbp1); ClearBreakPointFromJS(env->GetIsolate(), sbp2); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2138,24 +2232,26 @@ TEST(RemoveBreakPointInBreak) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::Context> context = env.context(); v8::Local<v8::Function> foo = CompileFunction(&env, "function foo(){a=1;}", "foo"); // Register the debug event listener pasing the function - v8::Debug::SetDebugEventListener(DebugEventRemoveBreakPoint, foo); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventRemoveBreakPoint, foo); debug_event_remove_break_point = SetBreakPoint(foo, 0); break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2164,28 +2260,38 @@ TEST(DebuggerStatement) { break_point_hit_count = 0; DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); - v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), "function bar(){debugger}")) - ->Run(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); + v8::Local<v8::Context> context = env.context(); + v8::Script::Compile(context, + v8_str(env->GetIsolate(), "function bar(){debugger}")) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), - "function foo(){debugger;debugger;}"))->Run(); + context, v8_str(env->GetIsolate(), "function foo(){debugger;debugger;}")) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "foo")) + .ToLocalChecked()); v8::Local<v8::Function> bar = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "bar"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "bar")) + .ToLocalChecked()); // Run function with debugger statement - bar->Call(env->Global(), 0, NULL); + bar->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); // Run function with two debugger statement - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(3, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2194,26 +2300,32 @@ TEST(DebuggerStatementBreakpoint) { break_point_hit_count = 0; DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); - v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), "function foo(){debugger;}")) - ->Run(); + v8::Local<v8::Context> context = env.context(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); + v8::Script::Compile(context, + v8_str(env->GetIsolate(), "function foo(){debugger;}")) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "foo")) + .ToLocalChecked()); // The debugger statement triggers breakpoint hit - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); int bp = SetBreakPoint(foo, 0); // Set breakpoint does not duplicate hits - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); ClearBreakPoint(bp); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2230,25 +2342,21 @@ TEST(DebugEvaluate) { evaluate_check_source, "evaluate_check"); // Register the debug event listener - v8::Debug::SetDebugEventListener(DebugEventEvaluate); + v8::Debug::SetDebugEventListener(isolate, DebugEventEvaluate); // Different expected vaules of x and a when in a break point (u = undefined, // d = Hello, world!). - struct EvaluateCheck checks_uu[] = { - {"x", v8::Undefined(isolate)}, - {"a", v8::Undefined(isolate)}, - {NULL, v8::Handle<v8::Value>()} - }; + struct EvaluateCheck checks_uu[] = {{"x", v8::Undefined(isolate)}, + {"a", v8::Undefined(isolate)}, + {NULL, v8::Local<v8::Value>()}}; struct EvaluateCheck checks_hu[] = { - {"x", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}, - {"a", v8::Undefined(isolate)}, - {NULL, v8::Handle<v8::Value>()} - }; + {"x", v8_str(env->GetIsolate(), "Hello, world!")}, + {"a", v8::Undefined(isolate)}, + {NULL, v8::Local<v8::Value>()}}; struct EvaluateCheck checks_hh[] = { - {"x", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}, - {"a", v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}, - {NULL, v8::Handle<v8::Value>()} - }; + {"x", v8_str(env->GetIsolate(), "Hello, world!")}, + {"a", v8_str(env->GetIsolate(), "Hello, world!")}, + {NULL, v8::Local<v8::Value>()}}; // Simple test function. The "y=0" is in the function foo to provide a break // location. For "y=0" the "y" is at position 15 in the foo function @@ -2265,24 +2373,25 @@ TEST(DebugEvaluate) { const int foo_break_position_1 = 15; const int foo_break_position_2 = 29; + v8::Local<v8::Context> context = env.context(); // Arguments with one parameter "Hello, world!" - v8::Handle<v8::Value> argv_foo[1] = { - v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}; + v8::Local<v8::Value> argv_foo[1] = { + v8_str(env->GetIsolate(), "Hello, world!")}; // Call foo with breakpoint set before a=x and undefined as parameter. int bp = SetBreakPoint(foo, foo_break_position_1); checks = checks_uu; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // Call foo with breakpoint set before a=x and parameter "Hello, world!". checks = checks_hu; - foo->Call(env->Global(), 1, argv_foo); + foo->Call(context, env->Global(), 1, argv_foo).ToLocalChecked(); // Call foo with breakpoint set after a=x and parameter "Hello, world!". ClearBreakPoint(bp); SetBreakPoint(foo, foo_break_position_2); checks = checks_hh; - foo->Call(env->Global(), 1, argv_foo); + foo->Call(context, env->Global(), 1, argv_foo).ToLocalChecked(); // Test that overriding Object.prototype will not interfere into evaluation // on call frame. @@ -2301,14 +2410,14 @@ TEST(DebugEvaluate) { const int zoo_break_position = 50; // Arguments with one parameter "Hello, world!" - v8::Handle<v8::Value> argv_zoo[1] = { - v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!")}; + v8::Local<v8::Value> argv_zoo[1] = { + v8_str(env->GetIsolate(), "Hello, world!")}; // Call zoo with breakpoint set at y=0. DebugEventCounterClear(); bp = SetBreakPoint(zoo, zoo_break_position); checks = checks_hu; - zoo->Call(env->Global(), 1, argv_zoo); + zoo->Call(context, env->Global(), 1, argv_zoo).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); ClearBreakPoint(bp); @@ -2335,32 +2444,28 @@ TEST(DebugEvaluate) { // Call bar setting breakpoint before a=x in barbar and undefined as // parameter. checks = checks_uu; - v8::Handle<v8::Value> argv_bar_1[2] = { - v8::Undefined(isolate), - v8::Number::New(isolate, barbar_break_position) - }; - bar->Call(env->Global(), 2, argv_bar_1); + v8::Local<v8::Value> argv_bar_1[2] = { + v8::Undefined(isolate), v8::Number::New(isolate, barbar_break_position)}; + bar->Call(context, env->Global(), 2, argv_bar_1).ToLocalChecked(); // Call bar setting breakpoint before a=x in barbar and parameter // "Hello, world!". checks = checks_hu; - v8::Handle<v8::Value> argv_bar_2[2] = { - v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!"), - v8::Number::New(env->GetIsolate(), barbar_break_position) - }; - bar->Call(env->Global(), 2, argv_bar_2); + v8::Local<v8::Value> argv_bar_2[2] = { + v8_str(env->GetIsolate(), "Hello, world!"), + v8::Number::New(env->GetIsolate(), barbar_break_position)}; + bar->Call(context, env->Global(), 2, argv_bar_2).ToLocalChecked(); // Call bar setting breakpoint after a=x in barbar and parameter // "Hello, world!". checks = checks_hh; - v8::Handle<v8::Value> argv_bar_3[2] = { - v8::String::NewFromUtf8(env->GetIsolate(), "Hello, world!"), - v8::Number::New(env->GetIsolate(), barbar_break_position + 1) - }; - bar->Call(env->Global(), 2, argv_bar_3); + v8::Local<v8::Value> argv_bar_3[2] = { + v8_str(env->GetIsolate(), "Hello, world!"), + v8::Number::New(env->GetIsolate(), barbar_break_position + 1)}; + bar->Call(context, env->Global(), 2, argv_bar_3).ToLocalChecked(); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -2377,8 +2482,9 @@ TEST(ConditionalBreakpointWithCodeGenerationDisallowed) { v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(CheckDebugEvent); + v8::Debug::SetDebugEventListener(env->GetIsolate(), CheckDebugEvent); + v8::Local<v8::Context> context = env.context(); v8::Local<v8::Function> foo = CompileFunction(&env, "function foo(x) {\n" " var s = 'String value2';\n" @@ -2391,27 +2497,34 @@ TEST(ConditionalBreakpointWithCodeGenerationDisallowed) { debugEventCount = 0; env->AllowCodeGenerationFromStrings(false); - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, debugEventCount); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } bool checkedDebugEvals = true; -v8::Handle<v8::Function> checkGlobalEvalFunction; -v8::Handle<v8::Function> checkFrameEvalFunction; +v8::Local<v8::Function> checkGlobalEvalFunction; +v8::Local<v8::Function> checkFrameEvalFunction; static void CheckDebugEval(const v8::Debug::EventDetails& eventDetails) { if (eventDetails.GetEvent() == v8::Break) { ++debugEventCount; v8::HandleScope handleScope(CcTest::isolate()); - v8::Handle<v8::Value> args[] = { eventDetails.GetExecutionState() }; - CHECK(checkGlobalEvalFunction->Call( - eventDetails.GetEventContext()->Global(), 1, args)->IsTrue()); - CHECK(checkFrameEvalFunction->Call( - eventDetails.GetEventContext()->Global(), 1, args)->IsTrue()); + v8::Local<v8::Value> args[] = {eventDetails.GetExecutionState()}; + CHECK( + checkGlobalEvalFunction->Call(eventDetails.GetEventContext(), + eventDetails.GetEventContext()->Global(), + 1, args) + .ToLocalChecked() + ->IsTrue()); + CHECK(checkFrameEvalFunction->Call(eventDetails.GetEventContext(), + eventDetails.GetEventContext()->Global(), + 1, args) + .ToLocalChecked() + ->IsTrue()); } } @@ -2424,8 +2537,9 @@ TEST(DebugEvaluateWithCodeGenerationDisallowed) { v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(CheckDebugEval); + v8::Debug::SetDebugEventListener(env->GetIsolate(), CheckDebugEval); + v8::Local<v8::Context> context = env.context(); v8::Local<v8::Function> foo = CompileFunction(&env, "var global = 'Global';\n" "function foo(x) {\n" @@ -2447,13 +2561,13 @@ TEST(DebugEvaluateWithCodeGenerationDisallowed) { "checkFrameEval"); debugEventCount = 0; env->AllowCodeGenerationFromStrings(false); - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, debugEventCount); checkGlobalEvalFunction.Clear(); checkFrameEvalFunction.Clear(); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2541,7 +2655,7 @@ DebugProcessDebugMessagesData process_debug_messages_data; static void DebugProcessDebugMessagesHandler( const v8::Debug::Message& message) { - v8::Handle<v8::String> json = message.GetJSON(); + v8::Local<v8::String> json = message.GetJSON(); v8::String::Utf8Value utf8(json); EvaluateResult* array_item = process_debug_messages_data.current(); @@ -2557,18 +2671,21 @@ static void DebugProcessDebugMessagesHandler( // Test that the evaluation of expressions works even from ProcessDebugMessages // i.e. with empty stack. TEST(DebugEvaluateWithoutStack) { - v8::Debug::SetMessageHandler(DebugProcessDebugMessagesHandler); - DebugLocalContext env; + v8::Debug::SetMessageHandler(env->GetIsolate(), + DebugProcessDebugMessagesHandler); v8::HandleScope scope(env->GetIsolate()); const char* source = "var v1 = 'Pinguin';\n function getAnimal() { return 'Capy' + 'bara'; }"; - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source)) - ->Run(); + v8::Local<v8::Context> context = env.context(); + v8::Script::Compile(context, v8_str(env->GetIsolate(), source)) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); - v8::Debug::ProcessDebugMessages(); + v8::Debug::ProcessDebugMessages(env->GetIsolate()); const int kBufferSize = 1000; uint16_t buffer[kBufferSize]; @@ -2604,7 +2721,7 @@ TEST(DebugEvaluateWithoutStack) { v8::Debug::SendCommand(isolate, buffer, AsciiToUtf16(command_113, buffer)); - v8::Debug::ProcessDebugMessages(); + v8::Debug::ProcessDebugMessages(isolate); CHECK_EQ(3, process_debug_messages_data.counter); @@ -2613,9 +2730,9 @@ TEST(DebugEvaluateWithoutStack) { 0); CHECK_EQ(strcmp("805", process_debug_messages_data.results[2].buffer), 0); - v8::Debug::SetMessageHandler(NULL); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2633,32 +2750,34 @@ TEST(DebugStepLinear) { CompileRun("a=0; b=0; c=0; foo();"); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStep); SetBreakPoint(foo, 3); step_action = StepIn; break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + v8::Local<v8::Context> context = env.context(); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // With stepping all break locations are hit. CHECK_EQ(4, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); // Register a debug event listener which just counts. - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); SetBreakPoint(foo, 3); break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // Without stepping only active break points are hit. CHECK_EQ(1, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2668,7 +2787,7 @@ TEST(DebugStepKeyedLoadLoop) { v8::HandleScope scope(env->GetIsolate()); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStep); // Create a function for testing stepping of keyed load. The statement 'y=1' // is there to have more than one breakable statement in the loop, TODO(315). @@ -2685,29 +2804,31 @@ TEST(DebugStepKeyedLoadLoop) { "y=0\n", "foo"); + v8::Local<v8::Context> context = env.context(); // Create array [0,1,2,3,4,5,6,7,8,9] v8::Local<v8::Array> a = v8::Array::New(env->GetIsolate(), 10); for (int i = 0; i < 10; i++) { - a->Set(v8::Number::New(env->GetIsolate(), i), - v8::Number::New(env->GetIsolate(), i)); + CHECK(a->Set(context, v8::Number::New(env->GetIsolate(), i), + v8::Number::New(env->GetIsolate(), i)) + .FromJust()); } // Call function without any break points to ensure inlining is in place. const int kArgc = 1; - v8::Handle<v8::Value> args[kArgc] = { a }; - foo->Call(env->Global(), kArgc, args); + v8::Local<v8::Value> args[kArgc] = {a}; + foo->Call(context, env->Global(), kArgc, args).ToLocalChecked(); // Set up break point and step through the function. SetBreakPoint(foo, 3); step_action = StepNext; break_point_hit_count = 0; - foo->Call(env->Global(), kArgc, args); + foo->Call(context, env->Global(), kArgc, args).ToLocalChecked(); // With stepping all break locations are hit. CHECK_EQ(45, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2717,7 +2838,7 @@ TEST(DebugStepKeyedStoreLoop) { v8::HandleScope scope(env->GetIsolate()); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStep); // Create a function for testing stepping of keyed store. The statement 'y=1' // is there to have more than one breakable statement in the loop, TODO(315). @@ -2733,29 +2854,31 @@ TEST(DebugStepKeyedStoreLoop) { "y=0\n", "foo"); + v8::Local<v8::Context> context = env.context(); // Create array [0,1,2,3,4,5,6,7,8,9] v8::Local<v8::Array> a = v8::Array::New(env->GetIsolate(), 10); for (int i = 0; i < 10; i++) { - a->Set(v8::Number::New(env->GetIsolate(), i), - v8::Number::New(env->GetIsolate(), i)); + CHECK(a->Set(context, v8::Number::New(env->GetIsolate(), i), + v8::Number::New(env->GetIsolate(), i)) + .FromJust()); } // Call function without any break points to ensure inlining is in place. const int kArgc = 1; - v8::Handle<v8::Value> args[kArgc] = { a }; - foo->Call(env->Global(), kArgc, args); + v8::Local<v8::Value> args[kArgc] = {a}; + foo->Call(context, env->Global(), kArgc, args).ToLocalChecked(); // Set up break point and step through the function. SetBreakPoint(foo, 3); step_action = StepNext; break_point_hit_count = 0; - foo->Call(env->Global(), kArgc, args); + foo->Call(context, env->Global(), kArgc, args).ToLocalChecked(); // With stepping all break locations are hit. CHECK_EQ(44, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2765,8 +2888,9 @@ TEST(DebugStepNamedLoadLoop) { v8::HandleScope scope(env->GetIsolate()); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping of named load. v8::Local<v8::Function> foo = CompileFunction( &env, @@ -2787,19 +2911,19 @@ TEST(DebugStepNamedLoadLoop) { "foo"); // Call function without any break points to ensure inlining is in place. - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // Set up break point and step through the function. SetBreakPoint(foo, 4); step_action = StepNext; break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // With stepping all break locations are hit. CHECK_EQ(65, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2808,9 +2932,10 @@ static void DoDebugStepNamedStoreLoop(int expected) { v8::HandleScope scope(env->GetIsolate()); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStep); // Create a function for testing stepping of named store. + v8::Local<v8::Context> context = env.context(); v8::Local<v8::Function> foo = CompileFunction( &env, "function foo() {\n" @@ -2822,19 +2947,19 @@ static void DoDebugStepNamedStoreLoop(int expected) { "foo"); // Call function without any break points to ensure inlining is in place. - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // Set up break point and step through the function. SetBreakPoint(foo, 3); step_action = StepNext; break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // With stepping all expected break locations are hit. CHECK_EQ(expected, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2848,8 +2973,9 @@ TEST(DebugStepLinearMixedICs) { v8::HandleScope scope(env->GetIsolate()); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. v8::Local<v8::Function> foo = CompileFunction(&env, "function bar() {};" @@ -2866,26 +2992,27 @@ TEST(DebugStepLinearMixedICs) { step_action = StepIn; break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // With stepping all break locations are hit. CHECK_EQ(11, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); // Register a debug event listener which just counts. - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); SetBreakPoint(foo, 0); break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // Without stepping only active break points are hit. CHECK_EQ(1, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2894,8 +3021,9 @@ TEST(DebugStepDeclarations) { v8::HandleScope scope(env->GetIsolate()); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const char* src = "function foo() { " @@ -2913,12 +3041,12 @@ TEST(DebugStepDeclarations) { // Stepping through the declarations. step_action = StepIn; break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(6, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2927,8 +3055,9 @@ TEST(DebugStepLocals) { v8::HandleScope scope(env->GetIsolate()); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const char* src = "function foo() { " @@ -2946,12 +3075,12 @@ TEST(DebugStepLocals) { // Stepping through the declarations. step_action = StepIn; break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(6, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -2961,8 +3090,9 @@ TEST(DebugStepIf) { v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const int argc = 1; @@ -2982,20 +3112,20 @@ TEST(DebugStepIf) { // Stepping through the true part. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) }; - foo->Call(env->Global(), argc, argv_true); + v8::Local<v8::Value> argv_true[argc] = {v8::True(isolate)}; + foo->Call(context, env->Global(), argc, argv_true).ToLocalChecked(); CHECK_EQ(4, break_point_hit_count); // Stepping through the false part. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_false[argc] = { v8::False(isolate) }; - foo->Call(env->Global(), argc, argv_false); + v8::Local<v8::Value> argv_false[argc] = {v8::False(isolate)}; + foo->Call(context, env->Global(), argc, argv_false).ToLocalChecked(); CHECK_EQ(5, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(isolate); } @@ -3005,8 +3135,9 @@ TEST(DebugStepSwitch) { v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(isolate, DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const int argc = 1; @@ -3032,27 +3163,27 @@ TEST(DebugStepSwitch) { // One case with fall-through. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_1[argc] = { v8::Number::New(isolate, 1) }; - foo->Call(env->Global(), argc, argv_1); + v8::Local<v8::Value> argv_1[argc] = {v8::Number::New(isolate, 1)}; + foo->Call(context, env->Global(), argc, argv_1).ToLocalChecked(); CHECK_EQ(6, break_point_hit_count); // Another case. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_2[argc] = { v8::Number::New(isolate, 2) }; - foo->Call(env->Global(), argc, argv_2); + v8::Local<v8::Value> argv_2[argc] = {v8::Number::New(isolate, 2)}; + foo->Call(context, env->Global(), argc, argv_2).ToLocalChecked(); CHECK_EQ(5, break_point_hit_count); // Last case. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_3[argc] = { v8::Number::New(isolate, 3) }; - foo->Call(env->Global(), argc, argv_3); + v8::Local<v8::Value> argv_3[argc] = {v8::Number::New(isolate, 3)}; + foo->Call(context, env->Global(), argc, argv_3).ToLocalChecked(); CHECK_EQ(7, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -3062,8 +3193,9 @@ TEST(DebugStepWhile) { v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(isolate, DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const int argc = 1; @@ -3080,27 +3212,27 @@ TEST(DebugStepWhile) { // Looping 0 times. We still should break at the while-condition once. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_0[argc] = { v8::Number::New(isolate, 0) }; - foo->Call(env->Global(), argc, argv_0); + v8::Local<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)}; + foo->Call(context, env->Global(), argc, argv_0).ToLocalChecked(); CHECK_EQ(3, break_point_hit_count); // Looping 10 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; - foo->Call(env->Global(), argc, argv_10); + v8::Local<v8::Value> argv_10[argc] = {v8::Number::New(isolate, 10)}; + foo->Call(context, env->Global(), argc, argv_10).ToLocalChecked(); CHECK_EQ(23, break_point_hit_count); // Looping 100 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; - foo->Call(env->Global(), argc, argv_100); + v8::Local<v8::Value> argv_100[argc] = {v8::Number::New(isolate, 100)}; + foo->Call(context, env->Global(), argc, argv_100).ToLocalChecked(); CHECK_EQ(203, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -3110,8 +3242,9 @@ TEST(DebugStepDoWhile) { v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(isolate, DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const int argc = 1; @@ -3128,27 +3261,27 @@ TEST(DebugStepDoWhile) { // Looping 0 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)}; - foo->Call(env->Global(), argc, argv_0); + v8::Local<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)}; + foo->Call(context, env->Global(), argc, argv_0).ToLocalChecked(); CHECK_EQ(4, break_point_hit_count); // Looping 10 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; - foo->Call(env->Global(), argc, argv_10); + v8::Local<v8::Value> argv_10[argc] = {v8::Number::New(isolate, 10)}; + foo->Call(context, env->Global(), argc, argv_10).ToLocalChecked(); CHECK_EQ(22, break_point_hit_count); // Looping 100 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; - foo->Call(env->Global(), argc, argv_100); + v8::Local<v8::Value> argv_100[argc] = {v8::Number::New(isolate, 100)}; + foo->Call(context, env->Global(), argc, argv_100).ToLocalChecked(); CHECK_EQ(202, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -3158,8 +3291,9 @@ TEST(DebugStepFor) { v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(isolate, DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const int argc = 1; @@ -3177,27 +3311,27 @@ TEST(DebugStepFor) { // Looping 0 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)}; - foo->Call(env->Global(), argc, argv_0); + v8::Local<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)}; + foo->Call(context, env->Global(), argc, argv_0).ToLocalChecked(); CHECK_EQ(4, break_point_hit_count); // Looping 10 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; - foo->Call(env->Global(), argc, argv_10); + v8::Local<v8::Value> argv_10[argc] = {v8::Number::New(isolate, 10)}; + foo->Call(context, env->Global(), argc, argv_10).ToLocalChecked(); CHECK_EQ(34, break_point_hit_count); // Looping 100 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; - foo->Call(env->Global(), argc, argv_100); + v8::Local<v8::Value> argv_100[argc] = {v8::Number::New(isolate, 100)}; + foo->Call(context, env->Global(), argc, argv_100).ToLocalChecked(); CHECK_EQ(304, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -3207,8 +3341,9 @@ TEST(DebugStepForContinue) { v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(isolate, DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const int argc = 1; @@ -3226,7 +3361,7 @@ TEST(DebugStepForContinue) { "}" "foo()"; v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); - v8::Handle<v8::Value> result; + v8::Local<v8::Value> result; SetBreakPoint(foo, 8); // "var a = 0;" // Each loop generates 4 or 5 steps depending on whether a is equal. @@ -3234,22 +3369,22 @@ TEST(DebugStepForContinue) { // Looping 10 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; - result = foo->Call(env->Global(), argc, argv_10); - CHECK_EQ(5, result->Int32Value()); + v8::Local<v8::Value> argv_10[argc] = {v8::Number::New(isolate, 10)}; + result = foo->Call(context, env->Global(), argc, argv_10).ToLocalChecked(); + CHECK_EQ(5, result->Int32Value(context).FromJust()); CHECK_EQ(62, break_point_hit_count); // Looping 100 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; - result = foo->Call(env->Global(), argc, argv_100); - CHECK_EQ(50, result->Int32Value()); + v8::Local<v8::Value> argv_100[argc] = {v8::Number::New(isolate, 100)}; + result = foo->Call(context, env->Global(), argc, argv_100).ToLocalChecked(); + CHECK_EQ(50, result->Int32Value(context).FromJust()); CHECK_EQ(557, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -3259,8 +3394,9 @@ TEST(DebugStepForBreak) { v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(isolate, DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const int argc = 1; @@ -3278,7 +3414,7 @@ TEST(DebugStepForBreak) { "}" "foo()"; v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); - v8::Handle<v8::Value> result; + v8::Local<v8::Value> result; SetBreakPoint(foo, 8); // "var a = 0;" // Each loop generates 5 steps except for the last (when break is executed) @@ -3287,22 +3423,22 @@ TEST(DebugStepForBreak) { // Looping 10 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) }; - result = foo->Call(env->Global(), argc, argv_10); - CHECK_EQ(9, result->Int32Value()); + v8::Local<v8::Value> argv_10[argc] = {v8::Number::New(isolate, 10)}; + result = foo->Call(context, env->Global(), argc, argv_10).ToLocalChecked(); + CHECK_EQ(9, result->Int32Value(context).FromJust()); CHECK_EQ(64, break_point_hit_count); // Looping 100 times. step_action = StepIn; break_point_hit_count = 0; - v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) }; - result = foo->Call(env->Global(), argc, argv_100); - CHECK_EQ(99, result->Int32Value()); + v8::Local<v8::Value> argv_100[argc] = {v8::Number::New(isolate, 100)}; + result = foo->Call(context, env->Global(), argc, argv_100).ToLocalChecked(); + CHECK_EQ(99, result->Int32Value(context).FromJust()); CHECK_EQ(604, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -3311,8 +3447,9 @@ TEST(DebugStepForIn) { v8::HandleScope scope(env->GetIsolate()); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. v8::Local<v8::Function> foo; @@ -3328,7 +3465,7 @@ TEST(DebugStepForIn) { step_action = StepIn; break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(8, break_point_hit_count); // Create a function for testing stepping. Run it to allow it to get @@ -3345,12 +3482,12 @@ TEST(DebugStepForIn) { step_action = StepIn; break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(10, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -3359,8 +3496,9 @@ TEST(DebugStepWith) { v8::HandleScope scope(env->GetIsolate()); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const char* src = "function foo(x) { " @@ -3369,20 +3507,22 @@ TEST(DebugStepWith) { " with (b) {}" "}" "foo()"; - env->Global()->Set(v8::String::NewFromUtf8(env->GetIsolate(), "b"), - v8::Object::New(env->GetIsolate())); + CHECK(env->Global() + ->Set(context, v8_str(env->GetIsolate(), "b"), + v8::Object::New(env->GetIsolate())) + .FromJust()); v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo"); - v8::Handle<v8::Value> result; + v8::Local<v8::Value> result; SetBreakPoint(foo, 8); // "var a = {};" step_action = StepIn; break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(4, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -3392,8 +3532,9 @@ TEST(DebugConditional) { v8::HandleScope scope(isolate); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(isolate, DebugEventStep); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const char* src = "function foo(x) { " @@ -3407,19 +3548,19 @@ TEST(DebugConditional) { step_action = StepIn; break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(4, break_point_hit_count); step_action = StepIn; break_point_hit_count = 0; const int argc = 1; - v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) }; - foo->Call(env->Global(), argc, argv_true); + v8::Local<v8::Value> argv_true[argc] = {v8::True(isolate)}; + foo->Call(context, env->Global(), argc, argv_true).ToLocalChecked(); CHECK_EQ(4, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -3433,8 +3574,9 @@ TEST(StepInOutSimple) { "frame_function_name"); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStepSequence); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStepSequence); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const char* src = "function a() {b();c();}; " @@ -3448,7 +3590,7 @@ TEST(StepInOutSimple) { step_action = StepIn; break_point_hit_count = 0; expected_step_sequence = "abcbaca"; - a->Call(env->Global(), 0, NULL); + a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(StrLength(expected_step_sequence), break_point_hit_count); @@ -3456,7 +3598,7 @@ TEST(StepInOutSimple) { step_action = StepNext; break_point_hit_count = 0; expected_step_sequence = "aaa"; - a->Call(env->Global(), 0, NULL); + a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(StrLength(expected_step_sequence), break_point_hit_count); @@ -3464,13 +3606,13 @@ TEST(StepInOutSimple) { step_action = StepOut; break_point_hit_count = 0; expected_step_sequence = "a"; - a->Call(env->Global(), 0, NULL); + a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(StrLength(expected_step_sequence), break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -3484,8 +3626,9 @@ TEST(StepInOutTree) { "frame_function_name"); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStepSequence); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStepSequence); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const char* src = "function a() {b(c(d()),d());c(d());d()}; " @@ -3500,7 +3643,7 @@ TEST(StepInOutTree) { step_action = StepIn; break_point_hit_count = 0; expected_step_sequence = "adacadabcbadacada"; - a->Call(env->Global(), 0, NULL); + a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(StrLength(expected_step_sequence), break_point_hit_count); @@ -3508,7 +3651,7 @@ TEST(StepInOutTree) { step_action = StepNext; break_point_hit_count = 0; expected_step_sequence = "aaaa"; - a->Call(env->Global(), 0, NULL); + a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(StrLength(expected_step_sequence), break_point_hit_count); @@ -3516,13 +3659,13 @@ TEST(StepInOutTree) { step_action = StepOut; break_point_hit_count = 0; expected_step_sequence = "a"; - a->Call(env->Global(), 0, NULL); + a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(StrLength(expected_step_sequence), break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(true); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate(), true); } @@ -3536,8 +3679,9 @@ TEST(StepInOutBranch) { "frame_function_name"); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStepSequence); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStepSequence); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. Run it to allow it to get // optimized. const char* src = "function a() {b(false);c();}; " @@ -3551,13 +3695,13 @@ TEST(StepInOutBranch) { step_action = StepIn; break_point_hit_count = 0; expected_step_sequence = "abbaca"; - a->Call(env->Global(), 0, NULL); + a->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(StrLength(expected_step_sequence), break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -3573,29 +3717,31 @@ TEST(DebugStepNatives) { "foo"); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStep); + v8::Local<v8::Context> context = env.context(); step_action = StepIn; break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // With stepping all break locations are hit. CHECK_EQ(3, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); // Register a debug event listener which just counts. - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // Without stepping only active break points are hit. CHECK_EQ(1, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -3612,29 +3758,31 @@ TEST(DebugStepFunctionApply) { "foo"); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStep); + v8::Local<v8::Context> context = env.context(); step_action = StepIn; break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // With stepping all break locations are hit. CHECK_EQ(7, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); // Register a debug event listener which just counts. - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // Without stepping only the debugger statement is hit. CHECK_EQ(1, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -3644,6 +3792,7 @@ TEST(DebugStepFunctionCall) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. v8::Local<v8::Function> foo = CompileFunction( &env, @@ -3658,35 +3807,35 @@ TEST(DebugStepFunctionCall) { "foo"); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(isolate, DebugEventStep); step_action = StepIn; // Check stepping where the if condition in bar is false. break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(6, break_point_hit_count); // Check stepping where the if condition in bar is true. break_point_hit_count = 0; const int argc = 1; - v8::Handle<v8::Value> argv[argc] = { v8::True(isolate) }; - foo->Call(env->Global(), argc, argv); + v8::Local<v8::Value> argv[argc] = {v8::True(isolate)}; + foo->Call(context, env->Global(), argc, argv).ToLocalChecked(); CHECK_EQ(8, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); // Register a debug event listener which just counts. - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(isolate, DebugEventBreakPointHitCount); break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // Without stepping only the debugger statement is hit. CHECK_EQ(1, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -3696,6 +3845,7 @@ TEST(DebugStepFunctionCallApply) { v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. v8::Local<v8::Function> foo = CompileFunction(&env, @@ -3708,27 +3858,27 @@ TEST(DebugStepFunctionCallApply) { "foo"); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStep); + v8::Debug::SetDebugEventListener(isolate, DebugEventStep); step_action = StepIn; break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); - CHECK_EQ(5, break_point_hit_count); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); + CHECK_EQ(6, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); // Register a debug event listener which just counts. - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(isolate, DebugEventBreakPointHitCount); break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // Without stepping only the debugger statement is hit. CHECK_EQ(1, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -3739,8 +3889,9 @@ TEST(PauseInScript) { env.ExposeDebug(); // Register a debug event listener which counts. - v8::Debug::SetDebugEventListener(DebugEventCounter); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventCounter); + v8::Local<v8::Context> context = env.context(); // Create a script that returns a function. const char* src = "(function (evt) {})"; const char* script_name = "StepInHandlerTest"; @@ -3749,19 +3900,19 @@ TEST(PauseInScript) { SetScriptBreakPointByNameFromJS(env->GetIsolate(), script_name, 0, -1); break_point_hit_count = 0; - v8::ScriptOrigin origin( - v8::String::NewFromUtf8(env->GetIsolate(), script_name), - v8::Integer::New(env->GetIsolate(), 0)); - v8::Handle<v8::Script> script = v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), src), &origin); - v8::Local<v8::Value> r = script->Run(); + v8::ScriptOrigin origin(v8_str(env->GetIsolate(), script_name), + v8::Integer::New(env->GetIsolate(), 0)); + v8::Local<v8::Script> script = + v8::Script::Compile(context, v8_str(env->GetIsolate(), src), &origin) + .ToLocalChecked(); + v8::Local<v8::Value> r = script->Run(context).ToLocalChecked(); CHECK(r->IsFunction()); CHECK_EQ(1, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -3783,6 +3934,7 @@ TEST(BreakOnException) { v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); + v8::Local<v8::Context> context = env.context(); // Create functions for testing break on exception. CompileFunction(&env, "function throws(){throw 1;}", "throws"); v8::Local<v8::Function> caught = @@ -3801,135 +3953,136 @@ TEST(BreakOnException) { &env, "function caughtFinally(){L:try{throws();}finally{break L;}}", "caughtFinally"); - v8::V8::AddMessageListener(MessageCallbackCount); - v8::Debug::SetDebugEventListener(DebugEventCounter); + env->GetIsolate()->AddMessageListener(MessageCallbackCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventCounter); // Initial state should be no break on exceptions. DebugEventCounterClear(); MessageCallbackCountClear(); - caught->Call(env->Global(), 0, NULL); + caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(0, 0, 0); - notCaught->Call(env->Global(), 0, NULL); + CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(0, 0, 1); - notCaughtFinally->Call(env->Global(), 0, NULL); + CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(0, 0, 2); - edgeCaseFinally->Call(env->Global(), 0, NULL); + edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(0, 0, 2); // No break on exception DebugEventCounterClear(); MessageCallbackCountClear(); ChangeBreakOnException(false, false); - caught->Call(env->Global(), 0, NULL); + caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(0, 0, 0); - notCaught->Call(env->Global(), 0, NULL); + CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(0, 0, 1); - notCaughtFinally->Call(env->Global(), 0, NULL); + CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(0, 0, 2); - edgeCaseFinally->Call(env->Global(), 0, NULL); + edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(0, 0, 2); // Break on uncaught exception DebugEventCounterClear(); MessageCallbackCountClear(); ChangeBreakOnException(false, true); - caught->Call(env->Global(), 0, NULL); + caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(0, 0, 0); - notCaught->Call(env->Global(), 0, NULL); + CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(1, 1, 1); - notCaughtFinally->Call(env->Global(), 0, NULL); + CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(2, 2, 2); - edgeCaseFinally->Call(env->Global(), 0, NULL); + edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(3, 3, 2); // Break on exception and uncaught exception DebugEventCounterClear(); MessageCallbackCountClear(); ChangeBreakOnException(true, true); - caught->Call(env->Global(), 0, NULL); + caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(1, 0, 0); - notCaught->Call(env->Global(), 0, NULL); + CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(2, 1, 1); - notCaughtFinally->Call(env->Global(), 0, NULL); + CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(3, 2, 2); - edgeCaseFinally->Call(env->Global(), 0, NULL); + edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(4, 3, 2); // Break on exception DebugEventCounterClear(); MessageCallbackCountClear(); ChangeBreakOnException(true, false); - caught->Call(env->Global(), 0, NULL); + caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(1, 0, 0); - notCaught->Call(env->Global(), 0, NULL); + CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(2, 1, 1); - notCaughtFinally->Call(env->Global(), 0, NULL); + CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(3, 2, 2); - edgeCaseFinally->Call(env->Global(), 0, NULL); + edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(4, 3, 2); // No break on exception using JavaScript DebugEventCounterClear(); MessageCallbackCountClear(); ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, false); - caught->Call(env->Global(), 0, NULL); + caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(0, 0, 0); - notCaught->Call(env->Global(), 0, NULL); + CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(0, 0, 1); - notCaughtFinally->Call(env->Global(), 0, NULL); + CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(0, 0, 2); - edgeCaseFinally->Call(env->Global(), 0, NULL); + edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(0, 0, 2); // Break on uncaught exception using JavaScript DebugEventCounterClear(); MessageCallbackCountClear(); ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, true); - caught->Call(env->Global(), 0, NULL); + caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(0, 0, 0); - notCaught->Call(env->Global(), 0, NULL); + CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(1, 1, 1); - notCaughtFinally->Call(env->Global(), 0, NULL); + CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(2, 2, 2); - edgeCaseFinally->Call(env->Global(), 0, NULL); + edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(3, 3, 2); // Break on exception and uncaught exception using JavaScript DebugEventCounterClear(); MessageCallbackCountClear(); ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, true); - caught->Call(env->Global(), 0, NULL); + caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(1, 0, 0); - notCaught->Call(env->Global(), 0, NULL); + CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(2, 1, 1); - notCaughtFinally->Call(env->Global(), 0, NULL); + CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(3, 2, 2); - edgeCaseFinally->Call(env->Global(), 0, NULL); + edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(4, 3, 2); // Break on exception using JavaScript DebugEventCounterClear(); MessageCallbackCountClear(); ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, false); - caught->Call(env->Global(), 0, NULL); + caught->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(1, 0, 0); - notCaught->Call(env->Global(), 0, NULL); + CHECK(notCaught->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(2, 1, 1); - notCaughtFinally->Call(env->Global(), 0, NULL); + CHECK(notCaughtFinally->Call(context, env->Global(), 0, NULL).IsEmpty()); DebugEventCounterCheck(3, 2, 2); - edgeCaseFinally->Call(env->Global(), 0, NULL); + edgeCaseFinally->Call(context, env->Global(), 0, NULL).ToLocalChecked(); DebugEventCounterCheck(4, 3, 2); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); - v8::V8::RemoveMessageListeners(MessageCallbackCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); + env->GetIsolate()->RemoveMessageListeners(MessageCallbackCount); } -static void try_finally_original_message(v8::Handle<v8::Message> message, - v8::Handle<v8::Value> data) { - CHECK_EQ(2, message->GetLineNumber()); - CHECK_EQ(2, message->GetStartColumn()); +static void try_finally_original_message(v8::Local<v8::Message> message, + v8::Local<v8::Value> data) { + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); + CHECK_EQ(2, message->GetLineNumber(context).FromJust()); + CHECK_EQ(2, message->GetStartColumn(context).FromJust()); message_callback_count++; } @@ -3938,11 +4091,11 @@ TEST(TryFinallyOriginalMessage) { // Test that the debugger plays nicely with the pending message. message_callback_count = 0; DebugEventCounterClear(); - v8::V8::AddMessageListener(try_finally_original_message); - v8::Debug::SetDebugEventListener(DebugEventCounter); - ChangeBreakOnException(true, true); DebugLocalContext env; v8::Isolate* isolate = CcTest::isolate(); + isolate->AddMessageListener(try_finally_original_message); + v8::Debug::SetDebugEventListener(isolate, DebugEventCounter); + ChangeBreakOnException(true, true); v8::HandleScope scope(isolate); CompileRun( "try {\n" @@ -3950,8 +4103,8 @@ TEST(TryFinallyOriginalMessage) { "} finally {\n" "}\n"); DebugEventCounterCheck(1, 1, 1); - v8::Debug::SetDebugEventListener(NULL); - v8::V8::RemoveMessageListeners(try_finally_original_message); + v8::Debug::SetDebugEventListener(isolate, nullptr); + isolate->RemoveMessageListeners(try_finally_original_message); } @@ -3968,8 +4121,8 @@ TEST(EvalJSInDebugEventListenerOnNativeReThrownException) { debug_event_listener_callback = noThrowJS; debug_event_listener_callback_result = 2; - v8::V8::AddMessageListener(MessageCallbackCount); - v8::Debug::SetDebugEventListener(DebugEventCounter); + env->GetIsolate()->AddMessageListener(MessageCallbackCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventCounter); // Break on uncaught exception ChangeBreakOnException(false, true); DebugEventCounterClear(); @@ -3978,8 +4131,8 @@ TEST(EvalJSInDebugEventListenerOnNativeReThrownException) { // ReThrow native error { v8::TryCatch tryCatch(env->GetIsolate()); - env->GetIsolate()->ThrowException(v8::Exception::TypeError( - v8::String::NewFromUtf8(env->GetIsolate(), "Type error"))); + env->GetIsolate()->ThrowException( + v8::Exception::TypeError(v8_str(env->GetIsolate(), "Type error"))); CHECK(tryCatch.HasCaught()); tryCatch.ReThrow(); } @@ -3999,14 +4152,15 @@ TEST(BreakOnCompileException) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::Context> context = env.context(); // For this test, we want to break on uncaught exceptions: ChangeBreakOnException(false, true); // Create a function for checking the function when hitting a break point. frame_count = CompileFunction(&env, frame_count_source, "frame_count"); - v8::V8::AddMessageListener(MessageCallbackCount); - v8::Debug::SetDebugEventListener(DebugEventCounter); + env->GetIsolate()->AddMessageListener(MessageCallbackCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventCounter); DebugEventCounterClear(); MessageCallbackCountClear(); @@ -4018,30 +4172,36 @@ TEST(BreakOnCompileException) { CHECK_EQ(-1, last_js_stack_height); // Throws SyntaxError: Unexpected end of input - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "+++")); + CHECK( + v8::Script::Compile(context, v8_str(env->GetIsolate(), "+++")).IsEmpty()); CHECK_EQ(1, exception_hit_count); CHECK_EQ(1, uncaught_exception_hit_count); CHECK_EQ(1, message_callback_count); CHECK_EQ(0, last_js_stack_height); // No JavaScript stack. // Throws SyntaxError: Unexpected identifier - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "x x")); + CHECK( + v8::Script::Compile(context, v8_str(env->GetIsolate(), "x x")).IsEmpty()); CHECK_EQ(2, exception_hit_count); CHECK_EQ(2, uncaught_exception_hit_count); CHECK_EQ(2, message_callback_count); CHECK_EQ(0, last_js_stack_height); // No JavaScript stack. // Throws SyntaxError: Unexpected end of input - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "eval('+++')")) - ->Run(); + CHECK(v8::Script::Compile(context, v8_str(env->GetIsolate(), "eval('+++')")) + .ToLocalChecked() + ->Run(context) + .IsEmpty()); CHECK_EQ(3, exception_hit_count); CHECK_EQ(3, uncaught_exception_hit_count); CHECK_EQ(3, message_callback_count); CHECK_EQ(1, last_js_stack_height); // Throws SyntaxError: Unexpected identifier - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "eval('x x')")) - ->Run(); + CHECK(v8::Script::Compile(context, v8_str(env->GetIsolate(), "eval('x x')")) + .ToLocalChecked() + ->Run(context) + .IsEmpty()); CHECK_EQ(4, exception_hit_count); CHECK_EQ(4, uncaught_exception_hit_count); CHECK_EQ(4, message_callback_count); @@ -4062,8 +4222,9 @@ TEST(StepWithException) { "frame_function_name"); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventStepSequence); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStepSequence); + v8::Local<v8::Context> context = env.context(); // Create functions for testing stepping. const char* src = "function a() { n(); }; " "function b() { c(); }; " @@ -4075,32 +4236,36 @@ TEST(StepWithException) { "function h() { x = 1; throw 1; }; "; // Step through invocation of a. + ClearStepping(); v8::Local<v8::Function> a = CompileFunction(&env, src, "a"); SetBreakPoint(a, 0); step_action = StepIn; break_point_hit_count = 0; expected_step_sequence = "aa"; - a->Call(env->Global(), 0, NULL); + CHECK(a->Call(context, env->Global(), 0, NULL).IsEmpty()); CHECK_EQ(StrLength(expected_step_sequence), break_point_hit_count); // Step through invocation of b + c. + ClearStepping(); v8::Local<v8::Function> b = CompileFunction(&env, src, "b"); SetBreakPoint(b, 0); step_action = StepIn; break_point_hit_count = 0; expected_step_sequence = "bcc"; - b->Call(env->Global(), 0, NULL); + CHECK(b->Call(context, env->Global(), 0, NULL).IsEmpty()); CHECK_EQ(StrLength(expected_step_sequence), break_point_hit_count); + // Step through invocation of d + e. + ClearStepping(); v8::Local<v8::Function> d = CompileFunction(&env, src, "d"); SetBreakPoint(d, 0); ChangeBreakOnException(false, true); step_action = StepIn; break_point_hit_count = 0; expected_step_sequence = "ddedd"; - d->Call(env->Global(), 0, NULL); + d->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(StrLength(expected_step_sequence), break_point_hit_count); @@ -4109,18 +4274,19 @@ TEST(StepWithException) { step_action = StepIn; break_point_hit_count = 0; expected_step_sequence = "ddeedd"; - d->Call(env->Global(), 0, NULL); + d->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(StrLength(expected_step_sequence), break_point_hit_count); // Step through invocation of f + g + h. + ClearStepping(); v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); SetBreakPoint(f, 0); ChangeBreakOnException(false, true); step_action = StepIn; break_point_hit_count = 0; expected_step_sequence = "ffghhff"; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(StrLength(expected_step_sequence), break_point_hit_count); @@ -4129,13 +4295,13 @@ TEST(StepWithException) { step_action = StepIn; break_point_hit_count = 0; expected_step_sequence = "ffghhhff"; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(StrLength(expected_step_sequence), break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -4149,8 +4315,9 @@ TEST(DebugBreak) { v8::HandleScope scope(isolate); // Register a debug event listener which sets the break flag and counts. - v8::Debug::SetDebugEventListener(DebugEventBreak); + v8::Debug::SetDebugEventListener(isolate, DebugEventBreak); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. const char* src = "function f0() {}" "function f1(x1) {}" @@ -4162,16 +4329,15 @@ TEST(DebugBreak) { v8::Local<v8::Function> f3 = CompileFunction(&env, src, "f3"); // Call the function to make sure it is compiled. - v8::Handle<v8::Value> argv[] = { v8::Number::New(isolate, 1), - v8::Number::New(isolate, 1), - v8::Number::New(isolate, 1), - v8::Number::New(isolate, 1) }; + v8::Local<v8::Value> argv[] = { + v8::Number::New(isolate, 1), v8::Number::New(isolate, 1), + v8::Number::New(isolate, 1), v8::Number::New(isolate, 1)}; // Call all functions to make sure that they are compiled. - f0->Call(env->Global(), 0, NULL); - f1->Call(env->Global(), 0, NULL); - f2->Call(env->Global(), 0, NULL); - f3->Call(env->Global(), 0, NULL); + f0->Call(context, env->Global(), 0, NULL).ToLocalChecked(); + f1->Call(context, env->Global(), 0, NULL).ToLocalChecked(); + f2->Call(context, env->Global(), 0, NULL).ToLocalChecked(); + f3->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // Set the debug break flag. v8::Debug::DebugBreak(env->GetIsolate()); @@ -4180,18 +4346,18 @@ TEST(DebugBreak) { // Call all functions with different argument count. break_point_hit_count = 0; for (unsigned int i = 0; i < arraysize(argv); i++) { - f0->Call(env->Global(), i, argv); - f1->Call(env->Global(), i, argv); - f2->Call(env->Global(), i, argv); - f3->Call(env->Global(), i, argv); + f0->Call(context, env->Global(), i, argv).ToLocalChecked(); + f1->Call(context, env->Global(), i, argv).ToLocalChecked(); + f2->Call(context, env->Global(), i, argv).ToLocalChecked(); + f3->Call(context, env->Global(), i, argv).ToLocalChecked(); } // One break for each function called. CHECK(4 * arraysize(argv) == break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -4202,8 +4368,9 @@ TEST(DisableBreak) { v8::HandleScope scope(env->GetIsolate()); // Register a debug event listener which sets the break flag and counts. - v8::Debug::SetDebugEventListener(DebugEventCounter); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventCounter); + v8::Local<v8::Context> context = env.context(); // Create a function for testing stepping. const char* src = "function f() {g()};function g(){i=0; while(i<10){i++}}"; v8::Local<v8::Function> f = CompileFunction(&env, src, "f"); @@ -4219,23 +4386,23 @@ TEST(DisableBreak) { // Call all functions with different argument count. break_point_hit_count = 0; - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); { v8::Debug::DebugBreak(env->GetIsolate()); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(env->GetIsolate()); v8::internal::DisableBreak disable_break(isolate->debug(), true); - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); } - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } static const char* kSimpleExtensionSource = @@ -4250,7 +4417,7 @@ TEST(NoBreakWhenBootstrapping) { v8::HandleScope scope(isolate); // Register a debug event listener which sets the break flag and counts. - v8::Debug::SetDebugEventListener(DebugEventCounter); + v8::Debug::SetDebugEventListener(isolate, DebugEventCounter); // Set the debug break flag. v8::Debug::DebugBreak(isolate); @@ -4269,28 +4436,37 @@ TEST(NoBreakWhenBootstrapping) { CHECK_EQ(0, break_point_hit_count); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } static void NamedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { - v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 3); - result->Set(v8::Integer::New(info.GetIsolate(), 0), - v8::String::NewFromUtf8(info.GetIsolate(), "a")); - result->Set(v8::Integer::New(info.GetIsolate(), 1), - v8::String::NewFromUtf8(info.GetIsolate(), "b")); - result->Set(v8::Integer::New(info.GetIsolate(), 2), - v8::String::NewFromUtf8(info.GetIsolate(), "c")); + v8::Local<v8::Array> result = v8::Array::New(info.GetIsolate(), 3); + v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); + CHECK(result->Set(context, v8::Integer::New(info.GetIsolate(), 0), + v8_str(info.GetIsolate(), "a")) + .FromJust()); + CHECK(result->Set(context, v8::Integer::New(info.GetIsolate(), 1), + v8_str(info.GetIsolate(), "b")) + .FromJust()); + CHECK(result->Set(context, v8::Integer::New(info.GetIsolate(), 2), + v8_str(info.GetIsolate(), "c")) + .FromJust()); info.GetReturnValue().Set(result); } static void IndexedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { v8::Isolate* isolate = info.GetIsolate(); - v8::Handle<v8::Array> result = v8::Array::New(isolate, 2); - result->Set(v8::Integer::New(isolate, 0), v8::Number::New(isolate, 1)); - result->Set(v8::Integer::New(isolate, 1), v8::Number::New(isolate, 10)); + v8::Local<v8::Array> result = v8::Array::New(isolate, 2); + v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); + CHECK(result->Set(context, v8::Integer::New(isolate, 0), + v8::Number::New(isolate, 1)) + .FromJust()); + CHECK(result->Set(context, v8::Integer::New(isolate, 1), + v8::Number::New(isolate, 10)) + .FromJust()); info.GetReturnValue().Set(result); } @@ -4300,13 +4476,13 @@ static void NamedGetter(v8::Local<v8::Name> name, if (name->IsSymbol()) return; v8::String::Utf8Value n(v8::Local<v8::String>::Cast(name)); if (strcmp(*n, "a") == 0) { - info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "AA")); + info.GetReturnValue().Set(v8_str(info.GetIsolate(), "AA")); return; } else if (strcmp(*n, "b") == 0) { - info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "BB")); + info.GetReturnValue().Set(v8_str(info.GetIsolate(), "BB")); return; } else if (strcmp(*n, "c") == 0) { - info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "CC")); + info.GetReturnValue().Set(v8_str(info.GetIsolate(), "CC")); return; } else { info.GetReturnValue().SetUndefined(); @@ -4329,75 +4505,71 @@ TEST(InterceptorPropertyMirror) { v8::HandleScope scope(isolate); env.ExposeDebug(); + v8::Local<v8::Context> context = env.context(); // Create object with named interceptor. - v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); named->SetHandler(v8::NamedPropertyHandlerConfiguration( NamedGetter, NULL, NULL, NULL, NamedEnum)); - env->Global()->Set( - v8::String::NewFromUtf8(isolate, "intercepted_named"), - named->NewInstance()); + CHECK(env->Global() + ->Set(context, v8_str(isolate, "intercepted_named"), + named->NewInstance(context).ToLocalChecked()) + .FromJust()); // Create object with indexed interceptor. - v8::Handle<v8::ObjectTemplate> indexed = v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> indexed = v8::ObjectTemplate::New(isolate); indexed->SetHandler(v8::IndexedPropertyHandlerConfiguration( IndexedGetter, NULL, NULL, NULL, IndexedEnum)); - env->Global()->Set( - v8::String::NewFromUtf8(isolate, "intercepted_indexed"), - indexed->NewInstance()); + CHECK(env->Global() + ->Set(context, v8_str(isolate, "intercepted_indexed"), + indexed->NewInstance(context).ToLocalChecked()) + .FromJust()); // Create object with both named and indexed interceptor. - v8::Handle<v8::ObjectTemplate> both = v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> both = v8::ObjectTemplate::New(isolate); both->SetHandler(v8::NamedPropertyHandlerConfiguration( NamedGetter, NULL, NULL, NULL, NamedEnum)); both->SetHandler(v8::IndexedPropertyHandlerConfiguration( IndexedGetter, NULL, NULL, NULL, IndexedEnum)); - env->Global()->Set( - v8::String::NewFromUtf8(isolate, "intercepted_both"), - both->NewInstance()); + CHECK(env->Global() + ->Set(context, v8_str(isolate, "intercepted_both"), + both->NewInstance(context).ToLocalChecked()) + .FromJust()); // Get mirrors for the three objects with interceptor. CompileRun( "var named_mirror = debug.MakeMirror(intercepted_named);" "var indexed_mirror = debug.MakeMirror(intercepted_indexed);" "var both_mirror = debug.MakeMirror(intercepted_both)"); - CHECK(CompileRun( - "named_mirror instanceof debug.ObjectMirror")->BooleanValue()); - CHECK(CompileRun( - "indexed_mirror instanceof debug.ObjectMirror")->BooleanValue()); - CHECK(CompileRun( - "both_mirror instanceof debug.ObjectMirror")->BooleanValue()); + CHECK(CompileRun("named_mirror instanceof debug.ObjectMirror") + ->BooleanValue(context) + .FromJust()); + CHECK(CompileRun("indexed_mirror instanceof debug.ObjectMirror") + ->BooleanValue(context) + .FromJust()); + CHECK(CompileRun("both_mirror instanceof debug.ObjectMirror") + ->BooleanValue(context) + .FromJust()); // Get the property names from the interceptors CompileRun( "named_names = named_mirror.propertyNames();" "indexed_names = indexed_mirror.propertyNames();" "both_names = both_mirror.propertyNames()"); - CHECK_EQ(3, CompileRun("named_names.length")->Int32Value()); - CHECK_EQ(2, CompileRun("indexed_names.length")->Int32Value()); - CHECK_EQ(5, CompileRun("both_names.length")->Int32Value()); + CHECK_EQ(3, CompileRun("named_names.length")->Int32Value(context).FromJust()); + CHECK_EQ(2, + CompileRun("indexed_names.length")->Int32Value(context).FromJust()); + CHECK_EQ(5, CompileRun("both_names.length")->Int32Value(context).FromJust()); // Check the expected number of properties. const char* source; source = "named_mirror.properties().length"; - CHECK_EQ(3, CompileRun(source)->Int32Value()); + CHECK_EQ(3, CompileRun(source)->Int32Value(context).FromJust()); source = "indexed_mirror.properties().length"; - CHECK_EQ(2, CompileRun(source)->Int32Value()); + CHECK_EQ(2, CompileRun(source)->Int32Value(context).FromJust()); source = "both_mirror.properties().length"; - CHECK_EQ(5, CompileRun(source)->Int32Value()); - - // 1 is PropertyKind.Named; - source = "both_mirror.properties(1).length"; - CHECK_EQ(3, CompileRun(source)->Int32Value()); - - // 2 is PropertyKind.Indexed; - source = "both_mirror.properties(2).length"; - CHECK_EQ(2, CompileRun(source)->Int32Value()); - - // 3 is PropertyKind.Named | PropertyKind.Indexed; - source = "both_mirror.properties(3).length"; - CHECK_EQ(5, CompileRun(source)->Int32Value()); + CHECK_EQ(5, CompileRun(source)->Int32Value(context).FromJust()); // Get the interceptor properties for the object with only named interceptor. CompileRun("var named_values = named_mirror.properties()"); @@ -4407,10 +4579,10 @@ TEST(InterceptorPropertyMirror) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; SNPrintF(buffer, "named_values[%d] instanceof debug.PropertyMirror", i); - CHECK(CompileRun(buffer.start())->BooleanValue()); + CHECK(CompileRun(buffer.start())->BooleanValue(context).FromJust()); SNPrintF(buffer, "named_values[%d].isNative()", i); - CHECK(CompileRun(buffer.start())->BooleanValue()); + CHECK(CompileRun(buffer.start())->BooleanValue(context).FromJust()); } // Get the interceptor properties for the object with only indexed @@ -4422,7 +4594,7 @@ TEST(InterceptorPropertyMirror) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; SNPrintF(buffer, "indexed_values[%d] instanceof debug.PropertyMirror", i); - CHECK(CompileRun(buffer.start())->BooleanValue()); + CHECK(CompileRun(buffer.start())->BooleanValue(context).FromJust()); } // Get the interceptor properties for the object with both types of @@ -4433,24 +4605,24 @@ TEST(InterceptorPropertyMirror) { for (int i = 0; i < 5; i++) { EmbeddedVector<char, SMALL_STRING_BUFFER_SIZE> buffer; SNPrintF(buffer, "both_values[%d] instanceof debug.PropertyMirror", i); - CHECK(CompileRun(buffer.start())->BooleanValue()); + CHECK(CompileRun(buffer.start())->BooleanValue(context).FromJust()); } // Check the property names. - source = "both_values[0].name() == 'a'"; - CHECK(CompileRun(source)->BooleanValue()); + source = "both_values[0].name() == '1'"; + CHECK(CompileRun(source)->BooleanValue(context).FromJust()); - source = "both_values[1].name() == 'b'"; - CHECK(CompileRun(source)->BooleanValue()); + source = "both_values[1].name() == '10'"; + CHECK(CompileRun(source)->BooleanValue(context).FromJust()); - source = "both_values[2].name() == 'c'"; - CHECK(CompileRun(source)->BooleanValue()); + source = "both_values[2].name() == 'a'"; + CHECK(CompileRun(source)->BooleanValue(context).FromJust()); - source = "both_values[3].name() == 1"; - CHECK(CompileRun(source)->BooleanValue()); + source = "both_values[3].name() == 'b'"; + CHECK(CompileRun(source)->BooleanValue(context).FromJust()); - source = "both_values[4].name() == 10"; - CHECK(CompileRun(source)->BooleanValue()); + source = "both_values[4].name() == 'c'"; + CHECK(CompileRun(source)->BooleanValue(context).FromJust()); } @@ -4461,30 +4633,43 @@ TEST(HiddenPrototypePropertyMirror) { v8::HandleScope scope(isolate); env.ExposeDebug(); - v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); - t0->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "x"), + v8::Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); + t0->InstanceTemplate()->Set(v8_str(isolate, "x"), v8::Number::New(isolate, 0)); - v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); + v8::Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); t1->SetHiddenPrototype(true); - t1->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "y"), + t1->InstanceTemplate()->Set(v8_str(isolate, "y"), v8::Number::New(isolate, 1)); - v8::Handle<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate); + v8::Local<v8::FunctionTemplate> t2 = v8::FunctionTemplate::New(isolate); t2->SetHiddenPrototype(true); - t2->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "z"), + t2->InstanceTemplate()->Set(v8_str(isolate, "z"), v8::Number::New(isolate, 2)); - v8::Handle<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate); - t3->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "u"), + v8::Local<v8::FunctionTemplate> t3 = v8::FunctionTemplate::New(isolate); + t3->InstanceTemplate()->Set(v8_str(isolate, "u"), v8::Number::New(isolate, 3)); + v8::Local<v8::Context> context = env.context(); // Create object and set them on the global object. - v8::Handle<v8::Object> o0 = t0->GetFunction()->NewInstance(); - env->Global()->Set(v8::String::NewFromUtf8(isolate, "o0"), o0); - v8::Handle<v8::Object> o1 = t1->GetFunction()->NewInstance(); - env->Global()->Set(v8::String::NewFromUtf8(isolate, "o1"), o1); - v8::Handle<v8::Object> o2 = t2->GetFunction()->NewInstance(); - env->Global()->Set(v8::String::NewFromUtf8(isolate, "o2"), o2); - v8::Handle<v8::Object> o3 = t3->GetFunction()->NewInstance(); - env->Global()->Set(v8::String::NewFromUtf8(isolate, "o3"), o3); + v8::Local<v8::Object> o0 = t0->GetFunction(context) + .ToLocalChecked() + ->NewInstance(context) + .ToLocalChecked(); + CHECK(env->Global()->Set(context, v8_str(isolate, "o0"), o0).FromJust()); + v8::Local<v8::Object> o1 = t1->GetFunction(context) + .ToLocalChecked() + ->NewInstance(context) + .ToLocalChecked(); + CHECK(env->Global()->Set(context, v8_str(isolate, "o1"), o1).FromJust()); + v8::Local<v8::Object> o2 = t2->GetFunction(context) + .ToLocalChecked() + ->NewInstance(context) + .ToLocalChecked(); + CHECK(env->Global()->Set(context, v8_str(isolate, "o2"), o2).FromJust()); + v8::Local<v8::Object> o3 = t3->GetFunction(context) + .ToLocalChecked() + ->NewInstance(context) + .ToLocalChecked(); + CHECK(env->Global()->Set(context, v8_str(isolate, "o3"), o3).FromJust()); // Get mirrors for the four objects. CompileRun( @@ -4492,43 +4677,62 @@ TEST(HiddenPrototypePropertyMirror) { "var o1_mirror = debug.MakeMirror(o1);" "var o2_mirror = debug.MakeMirror(o2);" "var o3_mirror = debug.MakeMirror(o3)"); - CHECK(CompileRun("o0_mirror instanceof debug.ObjectMirror")->BooleanValue()); - CHECK(CompileRun("o1_mirror instanceof debug.ObjectMirror")->BooleanValue()); - CHECK(CompileRun("o2_mirror instanceof debug.ObjectMirror")->BooleanValue()); - CHECK(CompileRun("o3_mirror instanceof debug.ObjectMirror")->BooleanValue()); + CHECK(CompileRun("o0_mirror instanceof debug.ObjectMirror") + ->BooleanValue(context) + .FromJust()); + CHECK(CompileRun("o1_mirror instanceof debug.ObjectMirror") + ->BooleanValue(context) + .FromJust()); + CHECK(CompileRun("o2_mirror instanceof debug.ObjectMirror") + ->BooleanValue(context) + .FromJust()); + CHECK(CompileRun("o3_mirror instanceof debug.ObjectMirror") + ->BooleanValue(context) + .FromJust()); // Check that each object has one property. - CHECK_EQ(1, CompileRun( - "o0_mirror.propertyNames().length")->Int32Value()); - CHECK_EQ(1, CompileRun( - "o1_mirror.propertyNames().length")->Int32Value()); - CHECK_EQ(1, CompileRun( - "o2_mirror.propertyNames().length")->Int32Value()); - CHECK_EQ(1, CompileRun( - "o3_mirror.propertyNames().length")->Int32Value()); + CHECK_EQ(1, CompileRun("o0_mirror.propertyNames().length") + ->Int32Value(context) + .FromJust()); + CHECK_EQ(1, CompileRun("o1_mirror.propertyNames().length") + ->Int32Value(context) + .FromJust()); + CHECK_EQ(1, CompileRun("o2_mirror.propertyNames().length") + ->Int32Value(context) + .FromJust()); + CHECK_EQ(1, CompileRun("o3_mirror.propertyNames().length") + ->Int32Value(context) + .FromJust()); // Set o1 as prototype for o0. o1 has the hidden prototype flag so all // properties on o1 should be seen on o0. - o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o1); - CHECK_EQ(2, CompileRun( - "o0_mirror.propertyNames().length")->Int32Value()); - CHECK_EQ(0, CompileRun( - "o0_mirror.property('x').value().value()")->Int32Value()); - CHECK_EQ(1, CompileRun( - "o0_mirror.property('y').value().value()")->Int32Value()); + CHECK(o0->Set(context, v8_str(isolate, "__proto__"), o1).FromJust()); + CHECK_EQ(2, CompileRun("o0_mirror.propertyNames().length") + ->Int32Value(context) + .FromJust()); + CHECK_EQ(0, CompileRun("o0_mirror.property('x').value().value()") + ->Int32Value(context) + .FromJust()); + CHECK_EQ(1, CompileRun("o0_mirror.property('y').value().value()") + ->Int32Value(context) + .FromJust()); // Set o2 as prototype for o0 (it will end up after o1 as o1 has the hidden // prototype flag. o2 also has the hidden prototype flag so all properties // on o2 should be seen on o0 as well as properties on o1. - o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o2); - CHECK_EQ(3, CompileRun( - "o0_mirror.propertyNames().length")->Int32Value()); - CHECK_EQ(0, CompileRun( - "o0_mirror.property('x').value().value()")->Int32Value()); - CHECK_EQ(1, CompileRun( - "o0_mirror.property('y').value().value()")->Int32Value()); - CHECK_EQ(2, CompileRun( - "o0_mirror.property('z').value().value()")->Int32Value()); + CHECK(o0->Set(context, v8_str(isolate, "__proto__"), o2).FromJust()); + CHECK_EQ(3, CompileRun("o0_mirror.propertyNames().length") + ->Int32Value(context) + .FromJust()); + CHECK_EQ(0, CompileRun("o0_mirror.property('x').value().value()") + ->Int32Value(context) + .FromJust()); + CHECK_EQ(1, CompileRun("o0_mirror.property('y').value().value()") + ->Int32Value(context) + .FromJust()); + CHECK_EQ(2, CompileRun("o0_mirror.property('z').value().value()") + ->Int32Value(context) + .FromJust()); // Set o3 as prototype for o0 (it will end up after o1 and o2 as both o1 and // o2 has the hidden prototype flag. o3 does not have the hidden prototype @@ -4536,21 +4740,30 @@ TEST(HiddenPrototypePropertyMirror) { // from o1 and o2 should still be seen on o0. // Final prototype chain: o0 -> o1 -> o2 -> o3 // Hidden prototypes: ^^ ^^ - o0->Set(v8::String::NewFromUtf8(isolate, "__proto__"), o3); - CHECK_EQ(3, CompileRun( - "o0_mirror.propertyNames().length")->Int32Value()); - CHECK_EQ(1, CompileRun( - "o3_mirror.propertyNames().length")->Int32Value()); - CHECK_EQ(0, CompileRun( - "o0_mirror.property('x').value().value()")->Int32Value()); - CHECK_EQ(1, CompileRun( - "o0_mirror.property('y').value().value()")->Int32Value()); - CHECK_EQ(2, CompileRun( - "o0_mirror.property('z').value().value()")->Int32Value()); - CHECK(CompileRun("o0_mirror.property('u').isUndefined()")->BooleanValue()); + CHECK(o0->Set(context, v8_str(isolate, "__proto__"), o3).FromJust()); + CHECK_EQ(3, CompileRun("o0_mirror.propertyNames().length") + ->Int32Value(context) + .FromJust()); + CHECK_EQ(1, CompileRun("o3_mirror.propertyNames().length") + ->Int32Value(context) + .FromJust()); + CHECK_EQ(0, CompileRun("o0_mirror.property('x').value().value()") + ->Int32Value(context) + .FromJust()); + CHECK_EQ(1, CompileRun("o0_mirror.property('y').value().value()") + ->Int32Value(context) + .FromJust()); + CHECK_EQ(2, CompileRun("o0_mirror.property('z').value().value()") + ->Int32Value(context) + .FromJust()); + CHECK(CompileRun("o0_mirror.property('u').isUndefined()") + ->BooleanValue(context) + .FromJust()); // The prototype (__proto__) for o0 should be o3 as o1 and o2 are hidden. - CHECK(CompileRun("o0_mirror.protoObject() == o3_mirror")->BooleanValue()); + CHECK(CompileRun("o0_mirror.protoObject() == o3_mirror") + ->BooleanValue(context) + .FromJust()); } @@ -4568,29 +4781,35 @@ TEST(NativeGetterPropertyMirror) { v8::HandleScope scope(isolate); env.ExposeDebug(); - v8::Handle<v8::String> name = v8::String::NewFromUtf8(isolate, "x"); + v8::Local<v8::Context> context = env.context(); + v8::Local<v8::String> name = v8_str(isolate, "x"); // Create object with named accessor. - v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); - named->SetAccessor(name, &ProtperyXNativeGetter, NULL, - v8::Handle<v8::Value>(), v8::DEFAULT, v8::None); + v8::Local<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); + named->SetAccessor(name, &ProtperyXNativeGetter, NULL, v8::Local<v8::Value>(), + v8::DEFAULT, v8::None); // Create object with named property getter. - env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"), - named->NewInstance()); - CHECK_EQ(10, CompileRun("instance.x")->Int32Value()); + CHECK(env->Global() + ->Set(context, v8_str(isolate, "instance"), + named->NewInstance(context).ToLocalChecked()) + .FromJust()); + CHECK_EQ(10, CompileRun("instance.x")->Int32Value(context).FromJust()); // Get mirror for the object with property getter. CompileRun("var instance_mirror = debug.MakeMirror(instance);"); - CHECK(CompileRun( - "instance_mirror instanceof debug.ObjectMirror")->BooleanValue()); + CHECK(CompileRun("instance_mirror instanceof debug.ObjectMirror") + ->BooleanValue(context) + .FromJust()); CompileRun("var named_names = instance_mirror.propertyNames();"); - CHECK_EQ(1, CompileRun("named_names.length")->Int32Value()); - CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue()); - CHECK(CompileRun( - "instance_mirror.property('x').value().isNumber()")->BooleanValue()); - CHECK(CompileRun( - "instance_mirror.property('x').value().value() == 10")->BooleanValue()); + CHECK_EQ(1, CompileRun("named_names.length")->Int32Value(context).FromJust()); + CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue(context).FromJust()); + CHECK(CompileRun("instance_mirror.property('x').value().isNumber()") + ->BooleanValue(context) + .FromJust()); + CHECK(CompileRun("instance_mirror.property('x').value().value() == 10") + ->BooleanValue(context) + .FromJust()); } @@ -4608,30 +4827,37 @@ TEST(NativeGetterThrowingErrorPropertyMirror) { v8::HandleScope scope(isolate); env.ExposeDebug(); - v8::Handle<v8::String> name = v8::String::NewFromUtf8(isolate, "x"); + v8::Local<v8::Context> context = env.context(); + v8::Local<v8::String> name = v8_str(isolate, "x"); // Create object with named accessor. - v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); + v8::Local<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); named->SetAccessor(name, &ProtperyXNativeGetterThrowingError, NULL, - v8::Handle<v8::Value>(), v8::DEFAULT, v8::None); + v8::Local<v8::Value>(), v8::DEFAULT, v8::None); // Create object with named property getter. - env->Global()->Set(v8::String::NewFromUtf8(isolate, "instance"), - named->NewInstance()); + CHECK(env->Global() + ->Set(context, v8_str(isolate, "instance"), + named->NewInstance(context).ToLocalChecked()) + .FromJust()); // Get mirror for the object with property getter. CompileRun("var instance_mirror = debug.MakeMirror(instance);"); - CHECK(CompileRun( - "instance_mirror instanceof debug.ObjectMirror")->BooleanValue()); + CHECK(CompileRun("instance_mirror instanceof debug.ObjectMirror") + ->BooleanValue(context) + .FromJust()); CompileRun("named_names = instance_mirror.propertyNames();"); - CHECK_EQ(1, CompileRun("named_names.length")->Int32Value()); - CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue()); - CHECK(CompileRun( - "instance_mirror.property('x').value().isError()")->BooleanValue()); + CHECK_EQ(1, CompileRun("named_names.length")->Int32Value(context).FromJust()); + CHECK(CompileRun("named_names[0] == 'x'")->BooleanValue(context).FromJust()); + CHECK(CompileRun("instance_mirror.property('x').value().isError()") + ->BooleanValue(context) + .FromJust()); // Check that the message is that passed to the Error constructor. - CHECK(CompileRun( - "instance_mirror.property('x').value().message() == 'Error message'")-> - BooleanValue()); + CHECK( + CompileRun( + "instance_mirror.property('x').value().message() == 'Error message'") + ->BooleanValue(context) + .FromJust()); } @@ -4645,81 +4871,97 @@ TEST(NoHiddenProperties) { v8::HandleScope scope(isolate); env.ExposeDebug(); + v8::Local<v8::Context> context = env.context(); // Create an object in the global scope. const char* source = "var obj = {a: 1};"; - v8::Script::Compile(v8::String::NewFromUtf8(isolate, source)) - ->Run(); + v8::Script::Compile(context, v8_str(isolate, source)) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(isolate, "obj"))); + env->Global()->Get(context, v8_str(isolate, "obj")).ToLocalChecked()); // Set a hidden property on the object. - obj->SetPrivate(env.context(), - v8::Private::New(isolate, v8::String::NewFromUtf8( - isolate, "v8::test-debug::a")), - v8::Int32::New(isolate, 11)) + obj->SetPrivate( + env.context(), + v8::Private::New(isolate, v8_str(isolate, "v8::test-debug::a")), + v8::Int32::New(isolate, 11)) .FromJust(); // Get mirror for the object with property getter. CompileRun("var obj_mirror = debug.MakeMirror(obj);"); - CHECK(CompileRun( - "obj_mirror instanceof debug.ObjectMirror")->BooleanValue()); + CHECK(CompileRun("obj_mirror instanceof debug.ObjectMirror") + ->BooleanValue(context) + .FromJust()); CompileRun("var named_names = obj_mirror.propertyNames();"); // There should be exactly one property. But there is also an unnamed // property whose value is hidden properties dictionary. The latter // property should not be in the list of reguar properties. - CHECK_EQ(1, CompileRun("named_names.length")->Int32Value()); - CHECK(CompileRun("named_names[0] == 'a'")->BooleanValue()); - CHECK(CompileRun( - "obj_mirror.property('a').value().value() == 1")->BooleanValue()); + CHECK_EQ(1, CompileRun("named_names.length")->Int32Value(context).FromJust()); + CHECK(CompileRun("named_names[0] == 'a'")->BooleanValue(context).FromJust()); + CHECK(CompileRun("obj_mirror.property('a').value().value() == 1") + ->BooleanValue(context) + .FromJust()); // Object created by t0 will become hidden prototype of object 'obj'. - v8::Handle<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); - t0->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "b"), + v8::Local<v8::FunctionTemplate> t0 = v8::FunctionTemplate::New(isolate); + t0->InstanceTemplate()->Set(v8_str(isolate, "b"), v8::Number::New(isolate, 2)); t0->SetHiddenPrototype(true); - v8::Handle<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); - t1->InstanceTemplate()->Set(v8::String::NewFromUtf8(isolate, "c"), + v8::Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New(isolate); + t1->InstanceTemplate()->Set(v8_str(isolate, "c"), v8::Number::New(isolate, 3)); // Create proto objects, add hidden properties to them and set them on // the global object. - v8::Handle<v8::Object> protoObj = t0->GetFunction()->NewInstance(); + v8::Local<v8::Object> protoObj = t0->GetFunction(context) + .ToLocalChecked() + ->NewInstance(context) + .ToLocalChecked(); protoObj->SetPrivate( env.context(), - v8::Private::New(isolate, v8::String::NewFromUtf8( - isolate, "v8::test-debug::b")), + v8::Private::New(isolate, v8_str(isolate, "v8::test-debug::b")), v8::Int32::New(isolate, 12)) .FromJust(); - env->Global()->Set(v8::String::NewFromUtf8(isolate, "protoObj"), - protoObj); - v8::Handle<v8::Object> grandProtoObj = t1->GetFunction()->NewInstance(); - grandProtoObj->SetPrivate( - env.context(), - v8::Private::New(isolate, v8::String::NewFromUtf8( - isolate, "v8::test-debug::c")), - v8::Int32::New(isolate, 13)) + CHECK(env->Global() + ->Set(context, v8_str(isolate, "protoObj"), protoObj) + .FromJust()); + v8::Local<v8::Object> grandProtoObj = t1->GetFunction(context) + .ToLocalChecked() + ->NewInstance(context) + .ToLocalChecked(); + grandProtoObj->SetPrivate(env.context(), + v8::Private::New( + isolate, v8_str(isolate, "v8::test-debug::c")), + v8::Int32::New(isolate, 13)) .FromJust(); - env->Global()->Set(v8::String::NewFromUtf8(isolate, "grandProtoObj"), - grandProtoObj); + CHECK(env->Global() + ->Set(context, v8_str(isolate, "grandProtoObj"), grandProtoObj) + .FromJust()); // Setting prototypes: obj->protoObj->grandProtoObj - protoObj->Set(v8::String::NewFromUtf8(isolate, "__proto__"), - grandProtoObj); - obj->Set(v8::String::NewFromUtf8(isolate, "__proto__"), protoObj); + CHECK(protoObj->Set(context, v8_str(isolate, "__proto__"), grandProtoObj) + .FromJust()); + CHECK(obj->Set(context, v8_str(isolate, "__proto__"), protoObj).FromJust()); // Get mirror for the object with property getter. CompileRun("var obj_mirror = debug.MakeMirror(obj);"); - CHECK(CompileRun( - "obj_mirror instanceof debug.ObjectMirror")->BooleanValue()); + CHECK(CompileRun("obj_mirror instanceof debug.ObjectMirror") + ->BooleanValue(context) + .FromJust()); CompileRun("var named_names = obj_mirror.propertyNames();"); // There should be exactly two properties - one from the object itself and // another from its hidden prototype. - CHECK_EQ(2, CompileRun("named_names.length")->Int32Value()); + CHECK_EQ(2, CompileRun("named_names.length")->Int32Value(context).FromJust()); CHECK(CompileRun("named_names.sort(); named_names[0] == 'a' &&" - "named_names[1] == 'b'")->BooleanValue()); - CHECK(CompileRun( - "obj_mirror.property('a').value().value() == 1")->BooleanValue()); - CHECK(CompileRun( - "obj_mirror.property('b').value().value() == 2")->BooleanValue()); + "named_names[1] == 'b'") + ->BooleanValue(context) + .FromJust()); + CHECK(CompileRun("obj_mirror.property('a').value().value() == 1") + ->BooleanValue(context) + .FromJust()); + CHECK(CompileRun("obj_mirror.property('b').value().value() == 2") + ->BooleanValue(context) + .FromJust()); } @@ -4889,7 +5131,7 @@ class MessageQueueDebuggerThread : public v8::base::Thread { static void MessageHandler(const v8::Debug::Message& message) { - v8::Handle<v8::String> json = message.GetJSON(); + v8::Local<v8::String> json = message.GetJSON(); v8::String::Utf8Value utf8(json); if (IsBreakEventMessage(*utf8)) { // Lets test script wait until break occurs to send commands. @@ -4995,7 +5237,7 @@ TEST(MessageQueues) { // Create a V8 environment DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetMessageHandler(MessageHandler); + v8::Debug::SetMessageHandler(env->GetIsolate(), MessageHandler); message_queue_debugger_thread.Start(); const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;"; @@ -5089,7 +5331,7 @@ TEST(SendClientDataToHandler) { v8::HandleScope scope(isolate); TestClientData::ResetCounters(); handled_client_data_instances_count = 0; - v8::Debug::SetMessageHandler(MessageHandlerCountingClientData); + v8::Debug::SetMessageHandler(isolate, MessageHandlerCountingClientData); const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;"; const int kBufferSize = 1000; uint16_t buffer[kBufferSize]; @@ -5171,7 +5413,7 @@ static void ThreadedMessageHandler(const v8::Debug::Message& message) { if (IsBreakEventMessage(print_buffer)) { // Check that we are inside the while loop. int source_line = GetSourceLineFromBreakEventMessage(print_buffer); - CHECK(8 <= source_line && source_line <= 13); + CHECK(4 <= source_line && source_line <= 10); threaded_debugging_barriers.barrier_2.Wait(); } } @@ -5180,10 +5422,6 @@ static void ThreadedMessageHandler(const v8::Debug::Message& message) { void V8Thread::Run() { const char* source = "flag = true;\n" - "function bar( new_value ) {\n" - " flag = new_value;\n" - " return \"Return from bar(\" + new_value + \")\";\n" - "}\n" "\n" "function foo() {\n" " var x = 1;\n" @@ -5205,13 +5443,13 @@ void V8Thread::Run() { v8::Isolate::Scope isolate_scope(isolate_); DebugLocalContext env(isolate_); v8::HandleScope scope(isolate_); - v8::Debug::SetMessageHandler(&ThreadedMessageHandler); - v8::Handle<v8::ObjectTemplate> global_template = + v8::Debug::SetMessageHandler(isolate_, &ThreadedMessageHandler); + v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(env->GetIsolate()); global_template->Set( - v8::String::NewFromUtf8(env->GetIsolate(), "ThreadedAtBarrier1"), + v8_str(env->GetIsolate(), "ThreadedAtBarrier1"), v8::FunctionTemplate::New(isolate_, ThreadedAtBarrier1)); - v8::Handle<v8::Context> context = + v8::Local<v8::Context> context = v8::Context::New(isolate_, NULL, global_template); v8::Context::Scope context_scope(context); @@ -5226,10 +5464,11 @@ void DebuggerThread::Run() { const int kBufSize = 1000; uint16_t buffer[kBufSize]; - const char* command_1 = "{\"seq\":102," + const char* command_1 = + "{\"seq\":102," "\"type\":\"request\"," "\"command\":\"evaluate\"," - "\"arguments\":{\"expression\":\"bar(false)\"}}"; + "\"arguments\":{\"expression\":\"flag = false\"}}"; const char* command_2 = "{\"seq\":103," "\"type\":\"request\"," "\"command\":\"continue\"}"; @@ -5338,7 +5577,7 @@ void BreakpointsV8Thread::Run() { v8::Isolate::Scope isolate_scope(isolate_); DebugLocalContext env(isolate_); v8::HandleScope scope(isolate_); - v8::Debug::SetMessageHandler(&BreakpointsMessageHandler); + v8::Debug::SetMessageHandler(isolate_, &BreakpointsMessageHandler); CompileRun(source_1); breakpoints_barriers->barrier_1.Wait(); @@ -5494,7 +5733,7 @@ TEST(RecursiveBreakpointsGlobal) { TEST(SetDebugEventListenerOnUninitializedVM) { - v8::Debug::SetDebugEventListener(DummyDebugEventListener); + v8::Debug::SetDebugEventListener(CcTest::isolate(), DummyDebugEventListener); } @@ -5503,7 +5742,7 @@ static void DummyMessageHandler(const v8::Debug::Message& message) { TEST(SetMessageHandlerOnUninitializedVM) { - v8::Debug::SetMessageHandler(DummyMessageHandler); + v8::Debug::SetMessageHandler(CcTest::isolate(), DummyMessageHandler); } @@ -5515,7 +5754,7 @@ static const char* debugger_call_with_data_source = " if (data) return data;" " throw 'No data!'" "}"; -v8::Handle<v8::Function> debugger_call_with_data; +v8::Local<v8::Function> debugger_call_with_data; // Source for a JavaScript function which returns the data parameter of a @@ -5528,23 +5767,32 @@ static const char* debugger_call_with_closure_source = " exec_state.y = x;" " return exec_state.y" "})"; -v8::Handle<v8::Function> debugger_call_with_closure; +v8::Local<v8::Function> debugger_call_with_closure; // Function to retrieve the number of JavaScript frames by calling a JavaScript // in the debugger. static void CheckFrameCount(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK(v8::Debug::Call(frame_count)->IsNumber()); - CHECK_EQ(args[0]->Int32Value(), - v8::Debug::Call(frame_count)->Int32Value()); + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); + CHECK(v8::Debug::Call(context, frame_count).ToLocalChecked()->IsNumber()); + CHECK_EQ(args[0]->Int32Value(context).FromJust(), + v8::Debug::Call(context, frame_count) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); } // Function to retrieve the source line of the top JavaScript frame by calling a // JavaScript function in the debugger. static void CheckSourceLine(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK(v8::Debug::Call(frame_source_line)->IsNumber()); - CHECK_EQ(args[0]->Int32Value(), - v8::Debug::Call(frame_source_line)->Int32Value()); + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); + CHECK( + v8::Debug::Call(context, frame_source_line).ToLocalChecked()->IsNumber()); + CHECK_EQ(args[0]->Int32Value(context).FromJust(), + v8::Debug::Call(context, frame_source_line) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); } @@ -5553,13 +5801,15 @@ static void CheckSourceLine(const v8::FunctionCallbackInfo<v8::Value>& args) { // can throw exceptions. static void CheckDataParameter( const v8::FunctionCallbackInfo<v8::Value>& args) { - v8::Handle<v8::String> data = - v8::String::NewFromUtf8(args.GetIsolate(), "Test"); - CHECK(v8::Debug::Call(debugger_call_with_data, data)->IsString()); + v8::Local<v8::String> data = v8_str(args.GetIsolate(), "Test"); + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); + CHECK(v8::Debug::Call(context, debugger_call_with_data, data) + .ToLocalChecked() + ->IsString()); for (int i = 0; i < 3; i++) { v8::TryCatch catcher(args.GetIsolate()); - CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty()); + CHECK(v8::Debug::Call(context, debugger_call_with_data).IsEmpty()); CHECK(catcher.HasCaught()); CHECK(catcher.Exception()->IsString()); } @@ -5568,8 +5818,14 @@ static void CheckDataParameter( // Function to test using a JavaScript with closure in the debugger. static void CheckClosure(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK(v8::Debug::Call(debugger_call_with_closure)->IsNumber()); - CHECK_EQ(3, v8::Debug::Call(debugger_call_with_closure)->Int32Value()); + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); + CHECK(v8::Debug::Call(context, debugger_call_with_closure) + .ToLocalChecked() + ->IsNumber()); + CHECK_EQ(3, v8::Debug::Call(context, debugger_call_with_closure) + .ToLocalChecked() + ->Int32Value(context) + .FromJust()); } @@ -5579,94 +5835,122 @@ TEST(CallFunctionInDebugger) { // CheckSourceLine and CheckDataParameter installed. v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(isolate); - global_template->Set( - v8::String::NewFromUtf8(isolate, "CheckFrameCount"), - v8::FunctionTemplate::New(isolate, CheckFrameCount)); - global_template->Set( - v8::String::NewFromUtf8(isolate, "CheckSourceLine"), - v8::FunctionTemplate::New(isolate, CheckSourceLine)); - global_template->Set( - v8::String::NewFromUtf8(isolate, "CheckDataParameter"), - v8::FunctionTemplate::New(isolate, CheckDataParameter)); - global_template->Set( - v8::String::NewFromUtf8(isolate, "CheckClosure"), - v8::FunctionTemplate::New(isolate, CheckClosure)); - v8::Handle<v8::Context> context = v8::Context::New(isolate, - NULL, - global_template); + global_template->Set(v8_str(isolate, "CheckFrameCount"), + v8::FunctionTemplate::New(isolate, CheckFrameCount)); + global_template->Set(v8_str(isolate, "CheckSourceLine"), + v8::FunctionTemplate::New(isolate, CheckSourceLine)); + global_template->Set(v8_str(isolate, "CheckDataParameter"), + v8::FunctionTemplate::New(isolate, CheckDataParameter)); + global_template->Set(v8_str(isolate, "CheckClosure"), + v8::FunctionTemplate::New(isolate, CheckClosure)); + v8::Local<v8::Context> context = + v8::Context::New(isolate, NULL, global_template); v8::Context::Scope context_scope(context); // Compile a function for checking the number of JavaScript frames. - v8::Script::Compile( - v8::String::NewFromUtf8(isolate, frame_count_source))->Run(); - frame_count = v8::Local<v8::Function>::Cast(context->Global()->Get( - v8::String::NewFromUtf8(isolate, "frame_count"))); + v8::Script::Compile(context, v8_str(isolate, frame_count_source)) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); + frame_count = v8::Local<v8::Function>::Cast( + context->Global() + ->Get(context, v8_str(isolate, "frame_count")) + .ToLocalChecked()); // Compile a function for returning the source line for the top frame. - v8::Script::Compile(v8::String::NewFromUtf8(isolate, - frame_source_line_source))->Run(); - frame_source_line = v8::Local<v8::Function>::Cast(context->Global()->Get( - v8::String::NewFromUtf8(isolate, "frame_source_line"))); + v8::Script::Compile(context, v8_str(isolate, frame_source_line_source)) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); + frame_source_line = v8::Local<v8::Function>::Cast( + context->Global() + ->Get(context, v8_str(isolate, "frame_source_line")) + .ToLocalChecked()); // Compile a function returning the data parameter. - v8::Script::Compile(v8::String::NewFromUtf8(isolate, - debugger_call_with_data_source)) - ->Run(); + v8::Script::Compile(context, v8_str(isolate, debugger_call_with_data_source)) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); debugger_call_with_data = v8::Local<v8::Function>::Cast( - context->Global()->Get(v8::String::NewFromUtf8( - isolate, "debugger_call_with_data"))); + context->Global() + ->Get(context, v8_str(isolate, "debugger_call_with_data")) + .ToLocalChecked()); // Compile a function capturing closure. - debugger_call_with_closure = - v8::Local<v8::Function>::Cast(v8::Script::Compile( - v8::String::NewFromUtf8(isolate, - debugger_call_with_closure_source))->Run()); + debugger_call_with_closure = v8::Local<v8::Function>::Cast( + v8::Script::Compile(context, + v8_str(isolate, debugger_call_with_closure_source)) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked()); // Calling a function through the debugger returns 0 frames if there are // no JavaScript frames. - CHECK(v8::Integer::New(isolate, 0)->Equals(v8::Debug::Call(frame_count))); + CHECK(v8::Integer::New(isolate, 0) + ->Equals(context, + v8::Debug::Call(context, frame_count).ToLocalChecked()) + .FromJust()); // Test that the number of frames can be retrieved. - v8::Script::Compile( - v8::String::NewFromUtf8(isolate, "CheckFrameCount(1)"))->Run(); - v8::Script::Compile(v8::String::NewFromUtf8(isolate, - "function f() {" - " CheckFrameCount(2);" - "}; f()"))->Run(); + v8::Script::Compile(context, v8_str(isolate, "CheckFrameCount(1)")) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); + v8::Script::Compile(context, v8_str(isolate, + "function f() {" + " CheckFrameCount(2);" + "}; f()")) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); // Test that the source line can be retrieved. - v8::Script::Compile( - v8::String::NewFromUtf8(isolate, "CheckSourceLine(0)"))->Run(); - v8::Script::Compile(v8::String::NewFromUtf8(isolate, - "function f() {\n" - " CheckSourceLine(1)\n" - " CheckSourceLine(2)\n" - " CheckSourceLine(3)\n" - "}; f()"))->Run(); + v8::Script::Compile(context, v8_str(isolate, "CheckSourceLine(0)")) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); + v8::Script::Compile(context, v8_str(isolate, + "function f() {\n" + " CheckSourceLine(1)\n" + " CheckSourceLine(2)\n" + " CheckSourceLine(3)\n" + "}; f()")) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); // Test that a parameter can be passed to a function called in the debugger. - v8::Script::Compile(v8::String::NewFromUtf8(isolate, - "CheckDataParameter()"))->Run(); + v8::Script::Compile(context, v8_str(isolate, "CheckDataParameter()")) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); // Test that a function with closure can be run in the debugger. - v8::Script::Compile( - v8::String::NewFromUtf8(isolate, "CheckClosure()"))->Run(); + v8::Script::Compile(context, v8_str(isolate, "CheckClosure()")) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); // Test that the source line is correct when there is a line offset. - v8::ScriptOrigin origin(v8::String::NewFromUtf8(isolate, "test"), + v8::ScriptOrigin origin(v8_str(isolate, "test"), v8::Integer::New(isolate, 7)); - v8::Script::Compile( - v8::String::NewFromUtf8(isolate, "CheckSourceLine(7)"), &origin) - ->Run(); - v8::Script::Compile(v8::String::NewFromUtf8(isolate, - "function f() {\n" - " CheckSourceLine(8)\n" - " CheckSourceLine(9)\n" - " CheckSourceLine(10)\n" - "}; f()"), - &origin)->Run(); + v8::Script::Compile(context, v8_str(isolate, "CheckSourceLine(7)"), &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); + v8::Script::Compile(context, v8_str(isolate, + "function f() {\n" + " CheckSourceLine(8)\n" + " CheckSourceLine(9)\n" + " CheckSourceLine(10)\n" + "}; f()"), + &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); } @@ -5689,11 +5973,13 @@ TEST(DebuggerUnload) { DebugLocalContext env; // Check debugger is unloaded before it is used. - CheckDebuggerUnloaded(); + CheckDebuggerUnloaded(env->GetIsolate()); // Set a debug event listener. break_point_hit_count = 0; - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); + v8::Local<v8::Context> context = env.context(); { v8::HandleScope scope(env->GetIsolate()); // Create a couple of functions for the test. @@ -5710,41 +5996,44 @@ TEST(DebuggerUnload) { // Make sure that the break points are there. break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); - bar->Call(env->Global(), 0, NULL); + bar->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(4, break_point_hit_count); } // Remove the debug event listener without clearing breakpoints. Do this // outside a handle scope. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(true); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate(), true); // Now set a debug message handler. break_point_hit_count = 0; - v8::Debug::SetMessageHandler(MessageHandlerBreakPointHitCount); + v8::Debug::SetMessageHandler(env->GetIsolate(), + MessageHandlerBreakPointHitCount); { v8::HandleScope scope(env->GetIsolate()); // Get the test functions again. v8::Local<v8::Function> foo(v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "foo")) + .ToLocalChecked())); - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(0, break_point_hit_count); // Set break points and run again. SetBreakPoint(foo, 0); SetBreakPoint(foo, 4); - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); } // Remove the debug message handler without clearing breakpoints. Do this // outside a handle scope. - v8::Debug::SetMessageHandler(NULL); - CheckDebuggerUnloaded(true); + v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate(), true); } @@ -5783,10 +6072,10 @@ TEST(DebuggerClearMessageHandler) { v8::HandleScope scope(env->GetIsolate()); // Check debugger is unloaded before it is used. - CheckDebuggerUnloaded(); + CheckDebuggerUnloaded(env->GetIsolate()); // Set a debug message handler. - v8::Debug::SetMessageHandler(MessageHandlerHitCount); + v8::Debug::SetMessageHandler(env->GetIsolate(), MessageHandlerHitCount); // Run code to throw a unhandled exception. This should end up in the message // handler. @@ -5797,7 +6086,7 @@ TEST(DebuggerClearMessageHandler) { // Clear debug message handler. message_handler_hit_count = 0; - v8::Debug::SetMessageHandler(NULL); + v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr); // Run code to throw a unhandled exception. This should end up in the message // handler. @@ -5806,7 +6095,7 @@ TEST(DebuggerClearMessageHandler) { // The message handler should not be called more. CHECK_EQ(0, message_handler_hit_count); - CheckDebuggerUnloaded(true); + CheckDebuggerUnloaded(env->GetIsolate(), true); } @@ -5816,7 +6105,7 @@ static void MessageHandlerClearingMessageHandler( message_handler_hit_count++; // Clear debug message handler. - v8::Debug::SetMessageHandler(NULL); + v8::Debug::SetMessageHandler(message.GetIsolate(), nullptr); } @@ -5826,10 +6115,11 @@ TEST(DebuggerClearMessageHandlerWhileActive) { v8::HandleScope scope(env->GetIsolate()); // Check debugger is unloaded before it is used. - CheckDebuggerUnloaded(); + CheckDebuggerUnloaded(env->GetIsolate()); // Set a debug message handler. - v8::Debug::SetMessageHandler(MessageHandlerClearingMessageHandler); + v8::Debug::SetMessageHandler(env->GetIsolate(), + MessageHandlerClearingMessageHandler); // Run code to throw a unhandled exception. This should end up in the message // handler. @@ -5838,7 +6128,7 @@ TEST(DebuggerClearMessageHandlerWhileActive) { // The message handler should be called. CHECK_EQ(1, message_handler_hit_count); - CheckDebuggerUnloaded(true); + CheckDebuggerUnloaded(env->GetIsolate(), true); } @@ -5861,12 +6151,12 @@ TEST(DebugGetLoadedScripts) { v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); + v8::Local<v8::Context> context = env.context(); EmptyExternalStringResource source_ext_str; v8::Local<v8::String> source = - v8::String::NewExternal(env->GetIsolate(), &source_ext_str); - v8::Handle<v8::Script> evil_script(v8::Script::Compile(source)); - // "use" evil_script to make the compiler happy. - USE(evil_script); + v8::String::NewExternalTwoByte(env->GetIsolate(), &source_ext_str) + .ToLocalChecked(); + CHECK(v8::Script::Compile(context, source).IsEmpty()); Handle<i::ExternalTwoByteString> i_source( i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source))); // This situation can happen if source was an external string disposed @@ -5875,7 +6165,7 @@ TEST(DebugGetLoadedScripts) { bool allow_natives_syntax = i::FLAG_allow_natives_syntax; i::FLAG_allow_natives_syntax = true; - EnableDebugger(); + EnableDebugger(env->GetIsolate()); v8::MaybeLocal<v8::Value> result = CompileRun(env.context(), "var scripts = %DebugGetLoadedScripts();" @@ -5891,15 +6181,16 @@ TEST(DebugGetLoadedScripts) { " }" "}"); CHECK(!result.IsEmpty()); - DisableDebugger(); + DisableDebugger(env->GetIsolate()); // Must not crash while accessing line_ends. i::FLAG_allow_natives_syntax = allow_natives_syntax; // Some scripts are retrieved - at least the number of native scripts. - CHECK_GT((*env) - ->Global() - ->Get(v8::String::NewFromUtf8(env->GetIsolate(), "count")) - ->Int32Value(), + CHECK_GT(env->Global() + ->Get(context, v8_str(env->GetIsolate(), "count")) + .ToLocalChecked() + ->Int32Value(context) + .FromJust(), 8); } @@ -5916,63 +6207,82 @@ TEST(ScriptNameAndData) { frame_script_name_source, "frame_script_name"); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakPointHitCount); + v8::Local<v8::Context> context = env.context(); // Test function source. - v8::Local<v8::String> script = v8::String::NewFromUtf8(env->GetIsolate(), - "function f() {\n" - " debugger;\n" - "}\n"); + v8::Local<v8::String> script = v8_str(env->GetIsolate(), + "function f() {\n" + " debugger;\n" + "}\n"); v8::ScriptOrigin origin1 = - v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "name")); - v8::Handle<v8::Script> script1 = v8::Script::Compile(script, &origin1); - script1->Run(); + v8::ScriptOrigin(v8_str(env->GetIsolate(), "name")); + v8::Local<v8::Script> script1 = + v8::Script::Compile(context, script, &origin1).ToLocalChecked(); + script1->Run(context).ToLocalChecked(); v8::Local<v8::Function> f; f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); CHECK_EQ(0, strcmp("name", last_script_name_hit)); // Compile the same script again without setting data. As the compilation // cache is disabled when debugging expect the data to be missing. - v8::Script::Compile(script, &origin1)->Run(); + v8::Script::Compile(context, script, &origin1) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); - f->Call(env->Global(), 0, NULL); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, break_point_hit_count); CHECK_EQ(0, strcmp("name", last_script_name_hit)); - v8::Local<v8::String> data_obj_source = v8::String::NewFromUtf8( - env->GetIsolate(), - "({ a: 'abc',\n" - " b: 123,\n" - " toString: function() { return this.a + ' ' + this.b; }\n" - "})\n"); - v8::Script::Compile(data_obj_source)->Run(); + v8::Local<v8::String> data_obj_source = + v8_str(env->GetIsolate(), + "({ a: 'abc',\n" + " b: 123,\n" + " toString: function() { return this.a + ' ' + this.b; }\n" + "})\n"); + v8::Script::Compile(context, data_obj_source) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); v8::ScriptOrigin origin2 = - v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "new name")); - v8::Handle<v8::Script> script2 = v8::Script::Compile(script, &origin2); - script2->Run(); + v8::ScriptOrigin(v8_str(env->GetIsolate(), "new name")); + v8::Local<v8::Script> script2 = + v8::Script::Compile(context, script, &origin2).ToLocalChecked(); + script2->Run(context).ToLocalChecked(); f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); - f->Call(env->Global(), 0, NULL); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(3, break_point_hit_count); CHECK_EQ(0, strcmp("new name", last_script_name_hit)); - v8::Handle<v8::Script> script3 = v8::Script::Compile(script, &origin2); - script3->Run(); + v8::Local<v8::Script> script3 = + v8::Script::Compile(context, script, &origin2).ToLocalChecked(); + script3->Run(context).ToLocalChecked(); f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); - f->Call(env->Global(), 0, NULL); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(4, break_point_hit_count); } -static v8::Handle<v8::Context> expected_context; -static v8::Handle<v8::Value> expected_context_data; +static v8::Local<v8::Context> expected_context; +static v8::Local<v8::Value> expected_context_data; // Check that the expected context is the one generating the debug event. @@ -6001,23 +6311,23 @@ TEST(ContextData) { v8::HandleScope scope(isolate); // Create two contexts. - v8::Handle<v8::Context> context_1; - v8::Handle<v8::Context> context_2; - v8::Handle<v8::ObjectTemplate> global_template = - v8::Handle<v8::ObjectTemplate>(); - v8::Handle<v8::Value> global_object = v8::Handle<v8::Value>(); + v8::Local<v8::Context> context_1; + v8::Local<v8::Context> context_2; + v8::Local<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate>(); + v8::Local<v8::Value> global_object = v8::Local<v8::Value>(); context_1 = v8::Context::New(isolate, NULL, global_template, global_object); context_2 = v8::Context::New(isolate, NULL, global_template, global_object); - v8::Debug::SetMessageHandler(ContextCheckMessageHandler); + v8::Debug::SetMessageHandler(isolate, ContextCheckMessageHandler); // Default data value is undefined. CHECK(context_1->GetEmbedderData(0)->IsUndefined()); CHECK(context_2->GetEmbedderData(0)->IsUndefined()); // Set and check different data values. - v8::Handle<v8::String> data_1 = v8::String::NewFromUtf8(isolate, "1"); - v8::Handle<v8::String> data_2 = v8::String::NewFromUtf8(isolate, "2"); + v8::Local<v8::String> data_1 = v8_str(isolate, "1"); + v8::Local<v8::String> data_2 = v8_str(isolate, "2"); context_1->SetEmbedderData(0, data_1); context_2->SetEmbedderData(0, data_2); CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1)); @@ -6032,7 +6342,7 @@ TEST(ContextData) { expected_context = context_1; expected_context_data = data_1; v8::Local<v8::Function> f = CompileFunction(isolate, source, "f"); - f->Call(context_1->Global(), 0, NULL); + f->Call(context_1, context_1->Global(), 0, NULL).ToLocalChecked(); } @@ -6042,14 +6352,14 @@ TEST(ContextData) { expected_context = context_2; expected_context_data = data_2; v8::Local<v8::Function> f = CompileFunction(isolate, source, "f"); - f->Call(context_2->Global(), 0, NULL); + f->Call(context_2, context_2->Global(), 0, NULL).ToLocalChecked(); } // Two times compile event and two times break event. CHECK_GT(message_handler_hit_count, 4); - v8::Debug::SetMessageHandler(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetMessageHandler(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -6078,22 +6388,27 @@ TEST(DebugBreakInMessageHandler) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetMessageHandler(DebugBreakMessageHandler); + v8::Debug::SetMessageHandler(env->GetIsolate(), DebugBreakMessageHandler); + v8::Local<v8::Context> context = env.context(); // Test functions. const char* script = "function f() { debugger; g(); } function g() { }"; CompileRun(script); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g"))); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "g")) + .ToLocalChecked()); // Call f then g. The debugger statement in f will cause a break which will // cause another break. - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, message_handler_break_hit_count); // Calling g will not cause any additional breaks. - g->Call(env->Global(), 0, NULL); + g->Call(context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(2, message_handler_break_hit_count); } @@ -6104,8 +6419,8 @@ TEST(DebugBreakInMessageHandler) { static void DebugEventDebugBreak( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); - v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); - + v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); if (event == v8::Break) { break_point_hit_count++; @@ -6113,17 +6428,17 @@ static void DebugEventDebugBreak( if (!frame_function_name.IsEmpty()) { // Get the name of the function. const int argc = 2; - v8::Handle<v8::Value> argv[argc] = { - exec_state, v8::Integer::New(CcTest::isolate(), 0) - }; - v8::Handle<v8::Value> result = frame_function_name->Call(exec_state, - argc, argv); + v8::Local<v8::Value> argv[argc] = { + exec_state, v8::Integer::New(CcTest::isolate(), 0)}; + v8::Local<v8::Value> result = + frame_function_name->Call(context, exec_state, argc, argv) + .ToLocalChecked(); if (result->IsUndefined()) { last_function_hit[0] = '\0'; } else { CHECK(result->IsString()); - v8::Handle<v8::String> function_name( - result->ToString(CcTest::isolate())); + v8::Local<v8::String> function_name( + result->ToString(context).ToLocalChecked()); function_name->WriteUtf8(last_function_hit); } } @@ -6140,7 +6455,7 @@ TEST(RegExpDebugBreak) { // This test only applies to native regexps. DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - + v8::Local<v8::Context> context = env.context(); // Create a function for checking the function when hitting a break point. frame_function_name = CompileFunction(&env, frame_function_name_source, @@ -6154,14 +6469,15 @@ TEST(RegExpDebugBreak) { v8::Local<v8::Function> f = CompileFunction(env->GetIsolate(), script, "f"); const int argc = 1; - v8::Handle<v8::Value> argv[argc] = { - v8::String::NewFromUtf8(env->GetIsolate(), " /* xxx */ a=0;")}; - v8::Local<v8::Value> result = f->Call(env->Global(), argc, argv); - CHECK_EQ(12, result->Int32Value()); + v8::Local<v8::Value> argv[argc] = { + v8_str(env->GetIsolate(), " /* xxx */ a=0;")}; + v8::Local<v8::Value> result = + f->Call(context, env->Global(), argc, argv).ToLocalChecked(); + CHECK_EQ(12, result->Int32Value(context).FromJust()); - v8::Debug::SetDebugEventListener(DebugEventDebugBreak); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventDebugBreak); v8::Debug::DebugBreak(env->GetIsolate()); - result = f->Call(env->Global(), argc, argv); + result = f->Call(context, env->Global(), argc, argv).ToLocalChecked(); // Check that there was only one break event. Matching RegExp should not // cause Break events. @@ -6175,20 +6491,19 @@ TEST(RegExpDebugBreak) { static void ExecuteScriptForContextCheck( v8::Debug::MessageHandler message_handler) { // Create a context. - v8::Handle<v8::Context> context_1; - v8::Handle<v8::ObjectTemplate> global_template = - v8::Handle<v8::ObjectTemplate>(); + v8::Local<v8::Context> context_1; + v8::Local<v8::ObjectTemplate> global_template = + v8::Local<v8::ObjectTemplate>(); context_1 = v8::Context::New(CcTest::isolate(), NULL, global_template); - v8::Debug::SetMessageHandler(message_handler); + v8::Debug::SetMessageHandler(CcTest::isolate(), message_handler); // Default data value is undefined. CHECK(context_1->GetEmbedderData(0)->IsUndefined()); // Set and check a data value. - v8::Handle<v8::String> data_1 = - v8::String::NewFromUtf8(CcTest::isolate(), "1"); + v8::Local<v8::String> data_1 = v8_str(CcTest::isolate(), "1"); context_1->SetEmbedderData(0, data_1); CHECK(context_1->GetEmbedderData(0)->StrictEquals(data_1)); @@ -6201,10 +6516,10 @@ static void ExecuteScriptForContextCheck( expected_context = context_1; expected_context_data = data_1; v8::Local<v8::Function> f = CompileFunction(CcTest::isolate(), source, "f"); - f->Call(context_1->Global(), 0, NULL); + f->Call(context_1, context_1->Global(), 0, NULL).ToLocalChecked(); } - v8::Debug::SetMessageHandler(NULL); + v8::Debug::SetMessageHandler(CcTest::isolate(), nullptr); } @@ -6219,7 +6534,7 @@ TEST(EvalContextData) { // One time compile event and one time break event. CHECK_GT(message_handler_hit_count, 2); - CheckDebuggerUnloaded(); + CheckDebuggerUnloaded(CcTest::isolate()); } @@ -6287,7 +6602,7 @@ TEST(NestedBreakEventContextData) { // One break from the source and another from the evaluate request. CHECK_EQ(break_count, 2); - CheckDebuggerUnloaded(); + CheckDebuggerUnloaded(CcTest::isolate()); } @@ -6310,22 +6625,27 @@ static void AfterCompileMessageHandler(const v8::Debug::Message& message) { TEST(AfterCompileMessageWhenMessageHandlerIsReset) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::Context> context = env.context(); after_compile_message_count = 0; const char* script = "var a=1"; - v8::Debug::SetMessageHandler(AfterCompileMessageHandler); - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) - ->Run(); - v8::Debug::SetMessageHandler(NULL); + v8::Debug::SetMessageHandler(env->GetIsolate(), AfterCompileMessageHandler); + v8::Script::Compile(context, v8_str(env->GetIsolate(), script)) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); + v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr); - v8::Debug::SetMessageHandler(AfterCompileMessageHandler); + v8::Debug::SetMessageHandler(env->GetIsolate(), AfterCompileMessageHandler); v8::Debug::DebugBreak(env->GetIsolate()); - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) - ->Run(); + v8::Script::Compile(context, v8_str(env->GetIsolate(), script)) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); // Setting listener to NULL should cause debugger unload. - v8::Debug::SetMessageHandler(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); // Compilation cache should be disabled when debugger is active. CHECK_EQ(2, after_compile_message_count); @@ -6358,7 +6678,8 @@ TEST(SyntaxErrorMessageOnSyntaxException) { // For this test, we want to break on uncaught exceptions: ChangeBreakOnException(false, true); - v8::Debug::SetDebugEventListener(CompileErrorEventCounter); + v8::Debug::SetDebugEventListener(env->GetIsolate(), CompileErrorEventCounter); + v8::Local<v8::Context> context = env.context(); CompileErrorEventCounterClear(); @@ -6366,24 +6687,29 @@ TEST(SyntaxErrorMessageOnSyntaxException) { CHECK_EQ(0, compile_error_event_count); // Throws SyntaxError: Unexpected end of input - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "+++")); + CHECK( + v8::Script::Compile(context, v8_str(env->GetIsolate(), "+++")).IsEmpty()); CHECK_EQ(1, compile_error_event_count); - v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), "/sel\\/: \\")); + CHECK(v8::Script::Compile(context, v8_str(env->GetIsolate(), "/sel\\/: \\")) + .IsEmpty()); CHECK_EQ(2, compile_error_event_count); - v8::Local<v8::Script> script = v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), "JSON.parse('1234:')")); + v8::Local<v8::Script> script = + v8::Script::Compile(context, + v8_str(env->GetIsolate(), "JSON.parse('1234:')")) + .ToLocalChecked(); CHECK_EQ(2, compile_error_event_count); - script->Run(); + CHECK(script->Run(context).IsEmpty()); CHECK_EQ(3, compile_error_event_count); - v8::Script::Compile( - v8::String::NewFromUtf8(env->GetIsolate(), "new RegExp('/\\/\\\\');")); + v8::Script::Compile(context, + v8_str(env->GetIsolate(), "new RegExp('/\\/\\\\');")) + .ToLocalChecked(); CHECK_EQ(3, compile_error_event_count); - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), "throw 1;")); + v8::Script::Compile(context, v8_str(env->GetIsolate(), "throw 1;")) + .ToLocalChecked(); CHECK_EQ(3, compile_error_event_count); } @@ -6392,23 +6718,28 @@ TEST(SyntaxErrorMessageOnSyntaxException) { TEST(BreakMessageWhenMessageHandlerIsReset) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::Context> context = env.context(); after_compile_message_count = 0; const char* script = "function f() {};"; - v8::Debug::SetMessageHandler(AfterCompileMessageHandler); - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) - ->Run(); - v8::Debug::SetMessageHandler(NULL); + v8::Debug::SetMessageHandler(env->GetIsolate(), AfterCompileMessageHandler); + v8::Script::Compile(context, v8_str(env->GetIsolate(), script)) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); + v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr); - v8::Debug::SetMessageHandler(AfterCompileMessageHandler); + v8::Debug::SetMessageHandler(env->GetIsolate(), AfterCompileMessageHandler); v8::Debug::DebugBreak(env->GetIsolate()); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); - f->Call(env->Global(), 0, NULL); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // Setting message handler to NULL should cause debugger unload. - v8::Debug::SetMessageHandler(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); // Compilation cache should be disabled when debugger is active. CHECK_EQ(1, after_compile_message_count); @@ -6429,25 +6760,30 @@ TEST(ExceptionMessageWhenMessageHandlerIsReset) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::Context> context = env.context(); // For this test, we want to break on uncaught exceptions: ChangeBreakOnException(false, true); exception_event_count = 0; const char* script = "function f() {throw new Error()};"; - v8::Debug::SetMessageHandler(AfterCompileMessageHandler); - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script)) - ->Run(); - v8::Debug::SetMessageHandler(NULL); + v8::Debug::SetMessageHandler(env->GetIsolate(), AfterCompileMessageHandler); + v8::Script::Compile(context, v8_str(env->GetIsolate(), script)) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); + v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr); - v8::Debug::SetMessageHandler(ExceptionMessageHandler); + v8::Debug::SetMessageHandler(env->GetIsolate(), ExceptionMessageHandler); v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f"))); - f->Call(env->Global(), 0, NULL); + env->Global() + ->Get(context, v8_str(env->GetIsolate(), "f")) + .ToLocalChecked()); + CHECK(f->Call(context, env->Global(), 0, NULL).IsEmpty()); // Setting message handler to NULL should cause debugger unload. - v8::Debug::SetMessageHandler(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); CHECK_EQ(1, exception_event_count); } @@ -6462,7 +6798,8 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) { const char* script = "function f() {};"; const char* resource_name = "test_resource"; - v8::Debug::SetMessageHandler(AfterCompileMessageHandler); + v8::Debug::SetMessageHandler(env->GetIsolate(), AfterCompileMessageHandler); + v8::Local<v8::Context> context = env.context(); // Set a couple of provisional breakpoint on lines out of the script lines // range. @@ -6473,14 +6810,15 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) { after_compile_message_count = 0; - v8::ScriptOrigin origin( - v8::String::NewFromUtf8(env->GetIsolate(), resource_name), - v8::Integer::New(env->GetIsolate(), 10), - v8::Integer::New(env->GetIsolate(), 1)); + v8::ScriptOrigin origin(v8_str(env->GetIsolate(), resource_name), + v8::Integer::New(env->GetIsolate(), 10), + v8::Integer::New(env->GetIsolate(), 1)); // Compile a script whose first line number is greater than the breakpoints' // lines. - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), script), - &origin)->Run(); + v8::Script::Compile(context, v8_str(env->GetIsolate(), script), &origin) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); // If the script is compiled successfully there is exactly one after compile // event. In case of an exception in debugger code after compile event is not @@ -6489,7 +6827,7 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) { ClearBreakPointFromJS(env->GetIsolate(), sbp1); ClearBreakPointFromJS(env->GetIsolate(), sbp2); - v8::Debug::SetMessageHandler(NULL); + v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr); } @@ -6521,9 +6859,10 @@ static void BreakMessageHandler(const v8::Debug::Message& message) { TEST(NoDebugBreakInAfterCompileMessageHandler) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::Context> context = env.context(); // Register a debug event listener which sets the break flag and counts. - v8::Debug::SetMessageHandler(BreakMessageHandler); + v8::Debug::SetMessageHandler(env->GetIsolate(), BreakMessageHandler); // Set the debug break flag. v8::Debug::DebugBreak(env->GetIsolate()); @@ -6537,13 +6876,13 @@ TEST(NoDebugBreakInAfterCompileMessageHandler) { // Set the debug break flag again. v8::Debug::DebugBreak(env->GetIsolate()); - f->Call(env->Global(), 0, NULL); + f->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // There should be one more break event when the script is evaluated in 'f'. CHECK_EQ(2, break_point_hit_count); // Get rid of the debug message handler. - v8::Debug::SetMessageHandler(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetMessageHandler(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -6562,7 +6901,7 @@ TEST(ProcessDebugMessages) { counting_message_handler_counter = 0; - v8::Debug::SetMessageHandler(CountingMessageHandler); + v8::Debug::SetMessageHandler(isolate, CountingMessageHandler); const int kBufferSize = 1000; uint16_t buffer[kBufferSize]; @@ -6576,7 +6915,7 @@ TEST(ProcessDebugMessages) { isolate, buffer, AsciiToUtf16(scripts_command, buffer)); CHECK_EQ(0, counting_message_handler_counter); - v8::Debug::ProcessDebugMessages(); + v8::Debug::ProcessDebugMessages(isolate); // At least one message should come CHECK_GE(counting_message_handler_counter, 1); @@ -6587,13 +6926,13 @@ TEST(ProcessDebugMessages) { v8::Debug::SendCommand( isolate, buffer, AsciiToUtf16(scripts_command, buffer)); CHECK_EQ(0, counting_message_handler_counter); - v8::Debug::ProcessDebugMessages(); + v8::Debug::ProcessDebugMessages(isolate); // At least two messages should come CHECK_GE(counting_message_handler_counter, 2); // Get rid of the debug message handler. - v8::Debug::SetMessageHandler(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetMessageHandler(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -6639,7 +6978,7 @@ class SendCommandThread : public v8::base::Thread { timer.Elapsed().InMillisecondsF()); } - v8::V8::TerminateExecution(isolate_); + isolate_->TerminateExecution(); } void StartSending() { semaphore_.Signal(); } @@ -6660,24 +6999,28 @@ TEST(ProcessDebugMessagesThreaded) { DebugLocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); + v8::Local<v8::Context> context = env.context(); counting_message_handler_counter = 0; v8::Debug::SetMessageHandler( - SendCommandThread::CountingAndSignallingMessageHandler); + isolate, SendCommandThread::CountingAndSignallingMessageHandler); send_command_thread_ = new SendCommandThread(isolate); send_command_thread_->Start(); - v8::Handle<v8::FunctionTemplate> start = + v8::Local<v8::FunctionTemplate> start = v8::FunctionTemplate::New(isolate, StartSendingCommands); - env->Global()->Set(v8_str("start"), start->GetFunction()); + CHECK(env->Global() + ->Set(context, v8_str("start"), + start->GetFunction(context).ToLocalChecked()) + .FromJust()); CompileRun("start(); while (true) { }"); CHECK_EQ(20, counting_message_handler_counter); - v8::Debug::SetMessageHandler(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetMessageHandler(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -6703,8 +7046,9 @@ TEST(Backtrace) { DebugLocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); + v8::Local<v8::Context> context = env.context(); - v8::Debug::SetMessageHandler(BacktraceData::MessageHandler); + v8::Debug::SetMessageHandler(isolate, BacktraceData::MessageHandler); const int kBufferSize = 1000; uint16_t buffer[kBufferSize]; @@ -6720,12 +7064,11 @@ TEST(Backtrace) { buffer, AsciiToUtf16(scripts_command, buffer), NULL); - v8::Debug::ProcessDebugMessages(); + v8::Debug::ProcessDebugMessages(isolate); CHECK_EQ(BacktraceData::frame_counter, 0); - v8::Handle<v8::String> void0 = - v8::String::NewFromUtf8(env->GetIsolate(), "void(0)"); - v8::Handle<v8::Script> script = CompileWithOrigin(void0, void0); + v8::Local<v8::String> void0 = v8_str(env->GetIsolate(), "void(0)"); + v8::Local<v8::Script> script = CompileWithOrigin(void0, void0); // Check backtrace from "void(0)" script. BacktraceData::frame_counter = -10; @@ -6734,12 +7077,12 @@ TEST(Backtrace) { buffer, AsciiToUtf16(scripts_command, buffer), NULL); - script->Run(); + script->Run(context).ToLocalChecked(); CHECK_EQ(BacktraceData::frame_counter, 1); // Get rid of the debug message handler. - v8::Debug::SetMessageHandler(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetMessageHandler(isolate, nullptr); + CheckDebuggerUnloaded(isolate); } @@ -6747,19 +7090,23 @@ TEST(GetMirror) { DebugLocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::Handle<v8::Value> obj = - v8::Debug::GetMirror(v8::String::NewFromUtf8(isolate, "hodja")); + v8::Local<v8::Context> context = env.context(); + v8::Local<v8::Value> obj = + v8::Debug::GetMirror(context, v8_str(isolate, "hodja")).ToLocalChecked(); v8::ScriptCompiler::Source source(v8_str( "function runTest(mirror) {" " return mirror.isString() && (mirror.length() == 5);" "}" "" "runTest;")); - v8::Handle<v8::Function> run_test = v8::Handle<v8::Function>::Cast( - v8::ScriptCompiler::CompileUnbound(isolate, &source) + v8::Local<v8::Function> run_test = v8::Local<v8::Function>::Cast( + v8::ScriptCompiler::CompileUnboundScript(isolate, &source) + .ToLocalChecked() ->BindToCurrentContext() - ->Run()); - v8::Handle<v8::Value> result = run_test->Call(env->Global(), 1, &obj); + ->Run(context) + .ToLocalChecked()); + v8::Local<v8::Value> result = + run_test->Call(context, env->Global(), 1, &obj).ToLocalChecked(); CHECK(result->IsTrue()); } @@ -6768,6 +7115,7 @@ TEST(GetMirror) { TEST(DebugBreakFunctionApply) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::Context> context = env.context(); // Create a function for testing breaking in apply. v8::Local<v8::Function> foo = CompileFunction( @@ -6778,7 +7126,7 @@ TEST(DebugBreakFunctionApply) { "foo"); // Register a debug event listener which steps and counts. - v8::Debug::SetDebugEventListener(DebugEventBreakMax); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventBreakMax); // Set the debug break flag before calling the code using function.apply. v8::Debug::DebugBreak(env->GetIsolate()); @@ -6787,18 +7135,18 @@ TEST(DebugBreakFunctionApply) { // where this test would enter an infinite loop. break_point_hit_count = 0; max_break_point_hit_count = 10000; // 10000 => infinite loop. - foo->Call(env->Global(), 0, NULL); + foo->Call(context, env->Global(), 0, NULL).ToLocalChecked(); // When keeping the debug break several break will happen. CHECK_GT(break_point_hit_count, 1); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } -v8::Handle<v8::Context> debugee_context; -v8::Handle<v8::Context> debugger_context; +v8::Local<v8::Context> debugee_context; +v8::Local<v8::Context> debugger_context; // Property getter that checks that current and calling contexts @@ -6807,7 +7155,7 @@ static void NamedGetterWithCallingContextCheck( v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info) { CHECK_EQ(0, strcmp(*v8::String::Utf8Value(name), "a")); - v8::Handle<v8::Context> current = info.GetIsolate()->GetCurrentContext(); + v8::Local<v8::Context> current = info.GetIsolate()->GetCurrentContext(); CHECK(current == debugee_context); CHECK(current != debugger_context); info.GetReturnValue().Set(1); @@ -6820,18 +7168,19 @@ static void NamedGetterWithCallingContextCheck( static void DebugEventGetAtgumentPropertyValue( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); - v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); + v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); if (event == v8::Break) { break_point_hit_count++; CHECK(debugger_context == CcTest::isolate()->GetCurrentContext()); - v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(CompileRun( + v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(CompileRun( "(function(exec_state) {\n" " return (exec_state.frame(0).argumentValue(0).property('a').\n" " value().value() == 1);\n" "})")); const int argc = 1; - v8::Handle<v8::Value> argv[argc] = { exec_state }; - v8::Handle<v8::Value> result = func->Call(exec_state, argc, argv); + v8::Local<v8::Value> argv[argc] = {exec_state}; + v8::Local<v8::Value> result = + func->Call(debugger_context, exec_state, argc, argv).ToLocalChecked(); CHECK(result->IsTrue()); } } @@ -6851,14 +7200,15 @@ TEST(CallingContextIsNotDebugContext) { debugger_context = v8::Utils::ToLocal(debug->debug_context()); // Create object with 'a' property accessor. - v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); - named->SetAccessor(v8::String::NewFromUtf8(isolate, "a"), - NamedGetterWithCallingContextCheck); - env->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"), - named->NewInstance()); + v8::Local<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate); + named->SetAccessor(v8_str(isolate, "a"), NamedGetterWithCallingContextCheck); + CHECK(env->Global() + ->Set(debugee_context, v8_str(isolate, "obj"), + named->NewInstance(debugee_context).ToLocalChecked()) + .FromJust()); // Register the debug event listener - v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue); + v8::Debug::SetDebugEventListener(isolate, DebugEventGetAtgumentPropertyValue); // Create a function that invokes debugger. v8::Local<v8::Function> foo = CompileFunction( @@ -6868,38 +7218,44 @@ TEST(CallingContextIsNotDebugContext) { "foo"); break_point_hit_count = 0; - foo->Call(env->Global(), 0, NULL); + foo->Call(debugee_context, env->Global(), 0, NULL).ToLocalChecked(); CHECK_EQ(1, break_point_hit_count); - v8::Debug::SetDebugEventListener(NULL); - debugee_context = v8::Handle<v8::Context>(); - debugger_context = v8::Handle<v8::Context>(); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + debugee_context = v8::Local<v8::Context>(); + debugger_context = v8::Local<v8::Context>(); + CheckDebuggerUnloaded(isolate); } TEST(DebugContextIsPreservedBetweenAccesses) { v8::HandleScope scope(CcTest::isolate()); - v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount); - v8::Local<v8::Context> context1 = v8::Debug::GetDebugContext(); - v8::Local<v8::Context> context2 = v8::Debug::GetDebugContext(); + v8::Debug::SetDebugEventListener(CcTest::isolate(), + DebugEventBreakPointHitCount); + v8::Local<v8::Context> context1 = + v8::Debug::GetDebugContext(CcTest::isolate()); + v8::Local<v8::Context> context2 = + v8::Debug::GetDebugContext(CcTest::isolate()); CHECK(v8::Utils::OpenHandle(*context1).is_identical_to( v8::Utils::OpenHandle(*context2))); - v8::Debug::SetDebugEventListener(NULL); + v8::Debug::SetDebugEventListener(CcTest::isolate(), nullptr); } TEST(NoDebugContextWhenDebuggerDisabled) { v8::HandleScope scope(CcTest::isolate()); - v8::Local<v8::Context> context = v8::Debug::GetDebugContext(); + v8::Local<v8::Context> context = + v8::Debug::GetDebugContext(CcTest::isolate()); CHECK(context.IsEmpty()); } -static v8::Handle<v8::Value> expected_callback_data; +static v8::Local<v8::Value> expected_callback_data; static void DebugEventContextChecker(const v8::Debug::EventDetails& details) { CHECK(details.GetEventContext() == expected_context); - CHECK(expected_callback_data->Equals(details.GetCallbackData())); + CHECK(expected_callback_data->Equals(details.GetEventContext(), + details.GetCallbackData()) + .FromJust()); } @@ -6909,15 +7265,18 @@ TEST(DebugEventContext) { v8::HandleScope scope(isolate); expected_context = v8::Context::New(isolate); expected_callback_data = v8::Int32::New(isolate, 2010); - v8::Debug::SetDebugEventListener(DebugEventContextChecker, - expected_callback_data); + v8::Debug::SetDebugEventListener(isolate, DebugEventContextChecker, + expected_callback_data); v8::Context::Scope context_scope(expected_context); - v8::Script::Compile( - v8::String::NewFromUtf8(isolate, "(function(){debugger;})();"))->Run(); + v8::Script::Compile(expected_context, + v8_str(isolate, "(function(){debugger;})();")) + .ToLocalChecked() + ->Run(expected_context) + .ToLocalChecked(); expected_context.Clear(); - v8::Debug::SetDebugEventListener(NULL); - expected_context_data = v8::Handle<v8::Value>(); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(isolate, nullptr); + expected_context_data = v8::Local<v8::Value>(); + CheckDebuggerUnloaded(isolate); } @@ -6926,21 +7285,22 @@ static bool debug_event_break_deoptimize_done = false; static void DebugEventBreakDeoptimize( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); - v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); + v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); if (event == v8::Break) { if (!frame_function_name.IsEmpty()) { // Get the name of the function. const int argc = 2; - v8::Handle<v8::Value> argv[argc] = { - exec_state, v8::Integer::New(CcTest::isolate(), 0) - }; - v8::Handle<v8::Value> result = - frame_function_name->Call(exec_state, argc, argv); + v8::Local<v8::Value> argv[argc] = { + exec_state, v8::Integer::New(CcTest::isolate(), 0)}; + v8::Local<v8::Value> result = + frame_function_name->Call(context, exec_state, argc, argv) + .ToLocalChecked(); if (!result->IsUndefined()) { char fn[80]; CHECK(result->IsString()); - v8::Handle<v8::String> function_name( - result->ToString(CcTest::isolate())); + v8::Local<v8::String> function_name( + result->ToString(context).ToLocalChecked()); function_name->WriteUtf8(fn); if (strcmp(fn, "bar") == 0) { i::Deoptimizer::DeoptimizeAll(CcTest::i_isolate()); @@ -6960,6 +7320,7 @@ TEST(DeoptimizeDuringDebugBreak) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); + v8::Local<v8::Context> context = env.context(); // Create a function for checking the function when hitting a break point. frame_function_name = CompileFunction(&env, @@ -6971,19 +7332,20 @@ TEST(DeoptimizeDuringDebugBreak) { // This tests lazy deoptimization bailout for the stack check, as the first // time in function bar when using debug break and no break points will be at // the initial stack check. - v8::Debug::SetDebugEventListener(DebugEventBreakDeoptimize); + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugEventBreakDeoptimize); // Compile and run function bar which will optimize it for some flag settings. v8::Local<v8::Function> f = CompileFunction(&env, "function bar(){}", "bar"); - f->Call(v8::Undefined(env->GetIsolate()), 0, NULL); + f->Call(context, v8::Undefined(env->GetIsolate()), 0, NULL).ToLocalChecked(); // Set debug break and call bar again. v8::Debug::DebugBreak(env->GetIsolate()); - f->Call(v8::Undefined(env->GetIsolate()), 0, NULL); + f->Call(context, v8::Undefined(env->GetIsolate()), 0, NULL).ToLocalChecked(); CHECK(debug_event_break_deoptimize_done); - v8::Debug::SetDebugEventListener(NULL); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); } @@ -6991,46 +7353,58 @@ static void DebugEventBreakWithOptimizedStack( const v8::Debug::EventDetails& event_details) { v8::Isolate* isolate = event_details.GetEventContext()->GetIsolate(); v8::DebugEvent event = event_details.GetEvent(); - v8::Handle<v8::Object> exec_state = event_details.GetExecutionState(); + v8::Local<v8::Object> exec_state = event_details.GetExecutionState(); + v8::Local<v8::Context> context = isolate->GetCurrentContext(); if (event == v8::Break) { if (!frame_function_name.IsEmpty()) { for (int i = 0; i < 2; i++) { const int argc = 2; - v8::Handle<v8::Value> argv[argc] = { - exec_state, v8::Integer::New(isolate, i) - }; + v8::Local<v8::Value> argv[argc] = {exec_state, + v8::Integer::New(isolate, i)}; // Get the name of the function in frame i. - v8::Handle<v8::Value> result = - frame_function_name->Call(exec_state, argc, argv); + v8::Local<v8::Value> result = + frame_function_name->Call(context, exec_state, argc, argv) + .ToLocalChecked(); CHECK(result->IsString()); - v8::Handle<v8::String> function_name(result->ToString(isolate)); - CHECK(function_name->Equals(v8::String::NewFromUtf8(isolate, "loop"))); + v8::Local<v8::String> function_name( + result->ToString(context).ToLocalChecked()); + CHECK( + function_name->Equals(context, v8_str(isolate, "loop")).FromJust()); // Get the name of the first argument in frame i. - result = frame_argument_name->Call(exec_state, argc, argv); + result = frame_argument_name->Call(context, exec_state, argc, argv) + .ToLocalChecked(); CHECK(result->IsString()); - v8::Handle<v8::String> argument_name(result->ToString(isolate)); - CHECK(argument_name->Equals(v8::String::NewFromUtf8(isolate, "count"))); + v8::Local<v8::String> argument_name( + result->ToString(context).ToLocalChecked()); + CHECK(argument_name->Equals(context, v8_str(isolate, "count")) + .FromJust()); // Get the value of the first argument in frame i. If the // funtion is optimized the value will be undefined, otherwise // the value will be '1 - i'. // // TODO(3141533): We should be able to get the real value for // optimized frames. - result = frame_argument_value->Call(exec_state, argc, argv); - CHECK(result->IsUndefined() || (result->Int32Value() == 1 - i)); + result = frame_argument_value->Call(context, exec_state, argc, argv) + .ToLocalChecked(); + CHECK(result->IsUndefined() || + (result->Int32Value(context).FromJust() == 1 - i)); // Get the name of the first local variable. - result = frame_local_name->Call(exec_state, argc, argv); + result = frame_local_name->Call(context, exec_state, argc, argv) + .ToLocalChecked(); CHECK(result->IsString()); - v8::Handle<v8::String> local_name(result->ToString(isolate)); - CHECK(local_name->Equals(v8::String::NewFromUtf8(isolate, "local"))); + v8::Local<v8::String> local_name( + result->ToString(context).ToLocalChecked()); + CHECK(local_name->Equals(context, v8_str(isolate, "local")).FromJust()); // Get the value of the first local variable. If the function // is optimized the value will be undefined, otherwise it will // be 42. // // TODO(3141533): We should be able to get the real value for // optimized frames. - result = frame_local_value->Call(exec_state, argc, argv); - CHECK(result->IsUndefined() || (result->Int32Value() == 42)); + result = frame_local_value->Call(context, exec_state, argc, argv) + .ToLocalChecked(); + CHECK(result->IsUndefined() || + (result->Int32Value(context).FromJust() == 42)); } } } @@ -7038,7 +7412,8 @@ static void DebugEventBreakWithOptimizedStack( static void ScheduleBreak(const v8::FunctionCallbackInfo<v8::Value>& args) { - v8::Debug::SetDebugEventListener(DebugEventBreakWithOptimizedStack); + v8::Debug::SetDebugEventListener(args.GetIsolate(), + DebugEventBreakWithOptimizedStack); v8::Debug::DebugBreak(args.GetIsolate()); } @@ -7046,6 +7421,7 @@ static void ScheduleBreak(const v8::FunctionCallbackInfo<v8::Value>& args) { TEST(DebugBreakStackInspection) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::Context> context = env.context(); frame_function_name = CompileFunction(&env, frame_function_name_source, "frame_function_name"); @@ -7059,11 +7435,13 @@ TEST(DebugBreakStackInspection) { frame_local_value = CompileFunction(&env, frame_local_value_source, "frame_local_value"); - v8::Handle<v8::FunctionTemplate> schedule_break_template = + v8::Local<v8::FunctionTemplate> schedule_break_template = v8::FunctionTemplate::New(env->GetIsolate(), ScheduleBreak); - v8::Handle<v8::Function> schedule_break = - schedule_break_template->GetFunction(); - env->Global()->Set(v8_str("scheduleBreak"), schedule_break); + v8::Local<v8::Function> schedule_break = + schedule_break_template->GetFunction(context).ToLocalChecked(); + CHECK(env->Global() + ->Set(context, v8_str("scheduleBreak"), schedule_break) + .FromJust()); const char* src = "function loop(count) {" @@ -7071,7 +7449,10 @@ TEST(DebugBreakStackInspection) { " if (count < 1) { scheduleBreak(); loop(count + 1); }" "}" "loop(0);"; - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), src))->Run(); + v8::Script::Compile(context, v8_str(env->GetIsolate(), src)) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); } @@ -7112,7 +7493,7 @@ static void TestDebugBreakInLoop(const char* loop_head, CompileRun("f();"); CHECK_EQ(kBreaksPerTest, break_point_hit_count); - CHECK(!v8::V8::IsExecutionTerminating()); + CHECK(!CcTest::isolate()->IsExecutionTerminating()); } } } @@ -7142,7 +7523,7 @@ void DebugBreakLoop(const char* loop_header, const char** loop_bodies, v8::HandleScope scope(env->GetIsolate()); // Register a debug event listener which sets the break flag and counts. - v8::Debug::SetDebugEventListener(DebugEventBreakMax); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventBreakMax); CompileRun( "var a = 1;\n" @@ -7152,8 +7533,8 @@ void DebugBreakLoop(const char* loop_header, const char** loop_bodies, TestDebugBreakInLoop(loop_header, loop_bodies, loop_footer); // Get rid of the debug event listener. - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -7218,6 +7599,7 @@ v8::Local<v8::Script> inline_script; static void DebugBreakInlineListener( const v8::Debug::EventDetails& event_details) { v8::DebugEvent event = event_details.GetEvent(); + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); if (event != v8::Break) return; int expected_frame_count = 4; @@ -7233,7 +7615,7 @@ static void DebugBreakInlineListener( SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id); v8::Local<v8::Value> result = CompileRun(script); - int frame_count = result->Int32Value(); + int frame_count = result->Int32Value(context).FromJust(); CHECK_EQ(expected_frame_count, frame_count); for (int i = 0; i < frame_count; i++) { @@ -7242,10 +7624,11 @@ static void DebugBreakInlineListener( SNPrintF(script_vector, "%%GetFrameDetails(%d, %d)[5]", break_id, i); v8::Local<v8::Value> result = CompileRun(script); CHECK_EQ(expected_line_number[i], - i::Script::GetLineNumber(source_script, result->Int32Value())); + i::Script::GetLineNumber(source_script, + result->Int32Value(context).FromJust())); } - v8::Debug::SetDebugEventListener(NULL); - v8::V8::TerminateExecution(CcTest::isolate()); + v8::Debug::SetDebugEventListener(CcTest::isolate(), nullptr); + CcTest::isolate()->TerminateExecution(); } @@ -7253,6 +7636,7 @@ TEST(DebugBreakInline) { i::FLAG_allow_natives_syntax = true; DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); + v8::Local<v8::Context> context = env.context(); const char* source = "function debug(b) { \n" " if (b) debugger; \n" @@ -7267,10 +7651,11 @@ TEST(DebugBreakInline) { "g(false); \n" "%OptimizeFunctionOnNextCall(g); \n" "g(true);"; - v8::Debug::SetDebugEventListener(DebugBreakInlineListener); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugBreakInlineListener); inline_script = - v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), source)); - inline_script->Run(); + v8::Script::Compile(context, v8_str(env->GetIsolate(), source)) + .ToLocalChecked(); + inline_script->Run(context).ToLocalChecked(); } @@ -7301,7 +7686,7 @@ TEST(Regress131642) { // on the stack. DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetDebugEventListener(DebugEventStepNext); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugEventStepNext); // We step through the first script. It exits through an exception. We run // this inside a new frame to record a different FP than the second script @@ -7313,7 +7698,7 @@ TEST(Regress131642) { const char* script_2 = "[0].forEach(function() { });"; CompileRun(script_2); - v8::Debug::SetDebugEventListener(NULL); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); } @@ -7335,15 +7720,15 @@ TEST(DebuggerCreatesContextIffActive) { v8::HandleScope scope(env->GetIsolate()); CHECK_EQ(1, v8::internal::CountNativeContexts()); - v8::Debug::SetDebugEventListener(NULL); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); CompileRun("debugger;"); CHECK_EQ(1, v8::internal::CountNativeContexts()); - v8::Debug::SetDebugEventListener(NopListener); + v8::Debug::SetDebugEventListener(env->GetIsolate(), NopListener); CompileRun("debugger;"); CHECK_EQ(2, v8::internal::CountNativeContexts()); - v8::Debug::SetDebugEventListener(NULL); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); } @@ -7373,7 +7758,7 @@ TEST(PrecompiledFunction) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); env.ExposeDebug(); - v8::Debug::SetDebugEventListener(DebugBreakInlineListener); + v8::Debug::SetDebugEventListener(env->GetIsolate(), DebugBreakInlineListener); v8::Local<v8::Function> break_here = CompileFunction(&env, "function break_here(){}", "break_here"); @@ -7395,8 +7780,8 @@ TEST(PrecompiledFunction) { v8::String::Utf8Value utf8(result); CHECK_EQ(0, strcmp("bar", *utf8)); - v8::Debug::SetDebugEventListener(NULL); - CheckDebuggerUnloaded(); + v8::Debug::SetDebugEventListener(env->GetIsolate(), nullptr); + CheckDebuggerUnloaded(env->GetIsolate()); } @@ -7414,12 +7799,16 @@ static void AddDebugBreak(const v8::FunctionCallbackInfo<v8::Value>& args) { TEST(DebugBreakStackTrace) { DebugLocalContext env; v8::HandleScope scope(env->GetIsolate()); - v8::Debug::SetDebugEventListener(DebugBreakStackTraceListener); - v8::Handle<v8::FunctionTemplate> add_debug_break_template = + v8::Debug::SetDebugEventListener(env->GetIsolate(), + DebugBreakStackTraceListener); + v8::Local<v8::Context> context = env.context(); + v8::Local<v8::FunctionTemplate> add_debug_break_template = v8::FunctionTemplate::New(env->GetIsolate(), AddDebugBreak); - v8::Handle<v8::Function> add_debug_break = - add_debug_break_template->GetFunction(); - env->Global()->Set(v8_str("add_debug_break"), add_debug_break); + v8::Local<v8::Function> add_debug_break = + add_debug_break_template->GetFunction(context).ToLocalChecked(); + CHECK(env->Global() + ->Set(context, v8_str("add_debug_break"), add_debug_break) + .FromJust()); CompileRun("(function loop() {" " for (var j = 0; j < 1000; j++) {" @@ -7453,7 +7842,7 @@ class TerminationThread : public v8::base::Thread { virtual void Run() { terminate_requested_semaphore.Wait(); - v8::V8::TerminateExecution(isolate_); + isolate_->TerminateExecution(); terminate_fired_semaphore.Signal(); } @@ -7466,7 +7855,7 @@ TEST(DebugBreakOffThreadTerminate) { DebugLocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::Debug::SetDebugEventListener(DebugBreakTriggerTerminate); + v8::Debug::SetDebugEventListener(isolate, DebugBreakTriggerTerminate); TerminationThread terminator(isolate); terminator.Start(); v8::TryCatch try_catch(env->GetIsolate()); @@ -7495,19 +7884,23 @@ TEST(DebugPromiseInterceptedByTryCatch) { DebugLocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::Debug::SetDebugEventListener(&DebugEventExpectNoException); + v8::Debug::SetDebugEventListener(isolate, &DebugEventExpectNoException); + v8::Local<v8::Context> context = env.context(); ChangeBreakOnException(false, true); - v8::Handle<v8::FunctionTemplate> fun = + v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate, TryCatchWrappedThrowCallback); - env->Global()->Set(v8_str("fun"), fun->GetFunction()); + CHECK(env->Global() + ->Set(context, v8_str("fun"), + fun->GetFunction(context).ToLocalChecked()) + .FromJust()); CompileRun("var p = new Promise(function(res, rej) { fun(); res(); });"); CompileRun( "var r;" "p.chain(function() { r = 'resolved'; }," " function() { r = 'rejected'; });"); - CHECK(CompileRun("r")->Equals(v8_str("resolved"))); + CHECK(CompileRun("r")->Equals(context, v8_str("resolved")).FromJust()); } @@ -7530,36 +7923,46 @@ TEST(DebugPromiseRejectedByCallback) { DebugLocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::Debug::SetDebugEventListener(&DebugEventCountException); + v8::Debug::SetDebugEventListener(isolate, &DebugEventCountException); + v8::Local<v8::Context> context = env.context(); ChangeBreakOnException(false, true); exception_event_counter = 0; - v8::Handle<v8::FunctionTemplate> fun = + v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate, ThrowCallback); - env->Global()->Set(v8_str("fun"), fun->GetFunction()); + CHECK(env->Global() + ->Set(context, v8_str("fun"), + fun->GetFunction(context).ToLocalChecked()) + .FromJust()); CompileRun("var p = new Promise(function(res, rej) { fun(); res(); });"); CompileRun( "var r;" "p.chain(function() { r = 'resolved'; }," " function(e) { r = 'rejected' + e; });"); - CHECK(CompileRun("r")->Equals(v8_str("rejectedrejection"))); + CHECK( + CompileRun("r")->Equals(context, v8_str("rejectedrejection")).FromJust()); CHECK_EQ(1, exception_event_counter); } TEST(DebugBreakOnExceptionInObserveCallback) { + i::FLAG_harmony_object_observe = true; DebugLocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::Debug::SetDebugEventListener(&DebugEventCountException); + v8::Debug::SetDebugEventListener(isolate, &DebugEventCountException); + v8::Local<v8::Context> context = env.context(); // Break on uncaught exception ChangeBreakOnException(false, true); exception_event_counter = 0; - v8::Handle<v8::FunctionTemplate> fun = + v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate, ThrowCallback); - env->Global()->Set(v8_str("fun"), fun->GetFunction()); + CHECK(env->Global() + ->Set(context, v8_str("fun"), + fun->GetFunction(context).ToLocalChecked()) + .FromJust()); CompileRun( "var obj = {};" @@ -7569,7 +7972,7 @@ TEST(DebugBreakOnExceptionInObserveCallback) { " throw Error('foo');" "});" "obj.prop = 1"); - CHECK(CompileRun("callbackRan")->BooleanValue()); + CHECK(CompileRun("callbackRan")->BooleanValue(context).FromJust()); CHECK_EQ(1, exception_event_counter); } @@ -7612,7 +8015,7 @@ TEST(DebugBreakInLexicalScopes) { DebugLocalContext env; v8::Isolate* isolate = env->GetIsolate(); v8::HandleScope scope(isolate); - v8::Debug::SetDebugEventListener(DebugHarmonyScopingListener); + v8::Debug::SetDebugEventListener(isolate, DebugHarmonyScopingListener); CompileRun( "'use strict'; \n" @@ -7650,6 +8053,6 @@ static void NoInterruptsOnDebugEvent( TEST(NoInterruptsInDebugListener) { DebugLocalContext env; - v8::Debug::SetDebugEventListener(NoInterruptsOnDebugEvent); + v8::Debug::SetDebugEventListener(env->GetIsolate(), NoInterruptsOnDebugEvent); CompileRun("void(0);"); } diff --git a/deps/v8/test/cctest/test-decls.cc b/deps/v8/test/cctest/test-decls.cc index 347ca9a6bc..4e9595258a 100644 --- a/deps/v8/test/cctest/test-decls.cc +++ b/deps/v8/test/cctest/test-decls.cc @@ -60,25 +60,24 @@ class DeclarationContext { } } - void Check(const char* source, - int get, int set, int has, + void Check(const char* source, int get, int set, int has, Expectations expectations, - v8::Handle<Value> value = Local<Value>()); + v8::Local<Value> value = Local<Value>()); int get_count() const { return get_count_; } int set_count() const { return set_count_; } int query_count() const { return query_count_; } protected: - virtual v8::Handle<Value> Get(Local<Name> key); - virtual v8::Handle<Value> Set(Local<Name> key, Local<Value> value); - virtual v8::Handle<Integer> Query(Local<Name> key); + virtual v8::Local<Value> Get(Local<Name> key); + virtual v8::Local<Value> Set(Local<Name> key, Local<Value> value); + virtual v8::Local<Integer> Query(Local<Name> key); void InitializeIfNeeded(); // Perform optional initialization steps on the context after it has // been created. Defaults to none but may be overwritten. - virtual void PostInitializeContext(Handle<Context> context) {} + virtual void PostInitializeContext(Local<Context> context) {} // Get the holder for the interceptor. Default to the instance template // but may be overwritten. @@ -138,10 +137,9 @@ void DeclarationContext::InitializeIfNeeded() { } -void DeclarationContext::Check(const char* source, - int get, int set, int query, +void DeclarationContext::Check(const char* source, int get, int set, int query, Expectations expectations, - v8::Handle<Value> value) { + v8::Local<Value> value) { InitializeIfNeeded(); // A retry after a GC may pollute the counts, so perform gc now // to avoid that. @@ -149,27 +147,30 @@ void DeclarationContext::Check(const char* source, HandleScope scope(CcTest::isolate()); TryCatch catcher(CcTest::isolate()); catcher.SetVerbose(true); - Local<Script> script = - Script::Compile(String::NewFromUtf8(CcTest::isolate(), source)); + Local<Context> context = CcTest::isolate()->GetCurrentContext(); + MaybeLocal<Script> script = Script::Compile( + context, + String::NewFromUtf8(CcTest::isolate(), source, v8::NewStringType::kNormal) + .ToLocalChecked()); if (expectations == EXPECT_ERROR) { CHECK(script.IsEmpty()); return; } CHECK(!script.IsEmpty()); - Local<Value> result = script->Run(); + MaybeLocal<Value> result = script.ToLocalChecked()->Run(context); CHECK_EQ(get, get_count()); CHECK_EQ(set, set_count()); CHECK_EQ(query, query_count()); if (expectations == EXPECT_RESULT) { CHECK(!catcher.HasCaught()); if (!value.IsEmpty()) { - CHECK(value->Equals(result)); + CHECK(value->Equals(context, result.ToLocalChecked()).FromJust()); } } else { CHECK(expectations == EXPECT_EXCEPTION); CHECK(catcher.HasCaught()); if (!value.IsEmpty()) { - CHECK(value->Equals(catcher.Exception())); + CHECK(value->Equals(context, catcher.Exception()).FromJust()); } } // Clean slate for the next test. @@ -208,24 +209,25 @@ DeclarationContext* DeclarationContext::GetInstance(Local<Value> data) { } -v8::Handle<Value> DeclarationContext::Get(Local<Name> key) { - return v8::Handle<Value>(); +v8::Local<Value> DeclarationContext::Get(Local<Name> key) { + return v8::Local<Value>(); } -v8::Handle<Value> DeclarationContext::Set(Local<Name> key, Local<Value> value) { - return v8::Handle<Value>(); +v8::Local<Value> DeclarationContext::Set(Local<Name> key, Local<Value> value) { + return v8::Local<Value>(); } -v8::Handle<Integer> DeclarationContext::Query(Local<Name> key) { - return v8::Handle<Integer>(); +v8::Local<Integer> DeclarationContext::Query(Local<Name> key) { + return v8::Local<Integer>(); } // Test global declaration of a property the interceptor doesn't know // about and doesn't handle. TEST(Unknown) { + i::FLAG_legacy_const = true; HandleScope scope(CcTest::isolate()); v8::V8::Initialize(); @@ -268,13 +270,14 @@ TEST(Unknown) { class AbsentPropertyContext: public DeclarationContext { protected: - virtual v8::Handle<Integer> Query(Local<Name> key) { - return v8::Handle<Integer>(); + virtual v8::Local<Integer> Query(Local<Name> key) { + return v8::Local<Integer>(); } }; TEST(Absent) { + i::FLAG_legacy_const = true; v8::Isolate* isolate = CcTest::isolate(); v8::V8::Initialize(); HandleScope scope(isolate); @@ -332,13 +335,13 @@ class AppearingPropertyContext: public DeclarationContext { AppearingPropertyContext() : state_(DECLARE) { } protected: - virtual v8::Handle<Integer> Query(Local<Name> key) { + virtual v8::Local<Integer> Query(Local<Name> key) { switch (state_) { case DECLARE: // Force declaration by returning that the // property is absent. state_ = INITIALIZE_IF_ASSIGN; - return Handle<Integer>(); + return Local<Integer>(); case INITIALIZE_IF_ASSIGN: // Return that the property is present so we only get the // setter called when initializing with a value. @@ -349,7 +352,7 @@ class AppearingPropertyContext: public DeclarationContext { break; } // Do the lookup in the object. - return v8::Handle<Integer>(); + return v8::Local<Integer>(); } private: @@ -358,6 +361,7 @@ class AppearingPropertyContext: public DeclarationContext { TEST(Appearing) { + i::FLAG_legacy_const = true; v8::V8::Initialize(); HandleScope scope(CcTest::isolate()); @@ -401,7 +405,7 @@ class ExistsInPrototypeContext: public DeclarationContext { public: ExistsInPrototypeContext() { InitializeIfNeeded(); } protected: - virtual v8::Handle<Integer> Query(Local<Name> key) { + virtual v8::Local<Integer> Query(Local<Name> key) { // Let it seem that the property exists in the prototype object. return Integer::New(isolate(), v8::None); } @@ -414,6 +418,7 @@ class ExistsInPrototypeContext: public DeclarationContext { TEST(ExistsInPrototype) { + i::FLAG_legacy_const = true; HandleScope scope(CcTest::isolate()); // Sanity check to make sure that the holder of the interceptor @@ -460,9 +465,9 @@ TEST(ExistsInPrototype) { class AbsentInPrototypeContext: public DeclarationContext { protected: - virtual v8::Handle<Integer> Query(Local<Name> key) { + virtual v8::Local<Integer> Query(Local<Name> key) { // Let it seem that the property is absent in the prototype object. - return Handle<Integer>(); + return Local<Integer>(); } // Use the prototype as the holder for the interceptors. @@ -495,18 +500,21 @@ class ExistsInHiddenPrototypeContext: public DeclarationContext { } protected: - virtual v8::Handle<Integer> Query(Local<Name> key) { + virtual v8::Local<Integer> Query(Local<Name> key) { // Let it seem that the property exists in the hidden prototype object. return Integer::New(isolate(), v8::None); } // Install the hidden prototype after the global object has been created. - virtual void PostInitializeContext(Handle<Context> context) { + virtual void PostInitializeContext(Local<Context> context) { Local<Object> global_object = context->Global(); - Local<Object> hidden_proto = hidden_proto_->GetFunction()->NewInstance(); + Local<Object> hidden_proto = hidden_proto_->GetFunction(context) + .ToLocalChecked() + ->NewInstance(context) + .ToLocalChecked(); Local<Object> inner_global = Local<Object>::Cast(global_object->GetPrototype()); - inner_global->SetPrototype(hidden_proto); + inner_global->SetPrototype(context, hidden_proto).FromJust(); } // Use the hidden prototype as the holder for the interceptors. @@ -520,6 +528,7 @@ class ExistsInHiddenPrototypeContext: public DeclarationContext { TEST(ExistsInHiddenPrototype) { + i::FLAG_legacy_const = true; HandleScope scope(CcTest::isolate()); { ExistsInHiddenPrototypeContext context; @@ -567,30 +576,31 @@ class SimpleContext { context_->Exit(); } - void Check(const char* source, - Expectations expectations, - v8::Handle<Value> value = Local<Value>()) { + void Check(const char* source, Expectations expectations, + v8::Local<Value> value = Local<Value>()) { HandleScope scope(context_->GetIsolate()); TryCatch catcher(context_->GetIsolate()); catcher.SetVerbose(true); - Local<Script> script = - Script::Compile(String::NewFromUtf8(context_->GetIsolate(), source)); + MaybeLocal<Script> script = Script::Compile( + context_, String::NewFromUtf8(context_->GetIsolate(), source, + v8::NewStringType::kNormal) + .ToLocalChecked()); if (expectations == EXPECT_ERROR) { CHECK(script.IsEmpty()); return; } CHECK(!script.IsEmpty()); - Local<Value> result = script->Run(); + MaybeLocal<Value> result = script.ToLocalChecked()->Run(context_); if (expectations == EXPECT_RESULT) { CHECK(!catcher.HasCaught()); if (!value.IsEmpty()) { - CHECK(value->Equals(result)); + CHECK(value->Equals(context_, result.ToLocalChecked()).FromJust()); } } else { CHECK(expectations == EXPECT_EXCEPTION); CHECK(catcher.HasCaught()); if (!value.IsEmpty()) { - CHECK(value->Equals(catcher.Exception())); + CHECK(value->Equals(context_, catcher.Exception()).FromJust()); } } } @@ -602,6 +612,7 @@ class SimpleContext { TEST(CrossScriptReferences) { + i::FLAG_legacy_const = true; v8::Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); @@ -901,10 +912,14 @@ TEST(CrossScriptDynamicLookup) { { SimpleContext context; - Local<String> undefined_string = String::NewFromUtf8( - CcTest::isolate(), "undefined", String::kInternalizedString); - Local<String> number_string = String::NewFromUtf8( - CcTest::isolate(), "number", String::kInternalizedString); + Local<String> undefined_string = + String::NewFromUtf8(CcTest::isolate(), "undefined", + v8::NewStringType::kInternalized) + .ToLocalChecked(); + Local<String> number_string = + String::NewFromUtf8(CcTest::isolate(), "number", + v8::NewStringType::kInternalized) + .ToLocalChecked(); context.Check( "function f(o) { with(o) { return x; } }" @@ -974,10 +989,14 @@ TEST(CrossScriptStaticLookupUndeclared) { { SimpleContext context; - Local<String> undefined_string = String::NewFromUtf8( - CcTest::isolate(), "undefined", String::kInternalizedString); - Local<String> number_string = String::NewFromUtf8( - CcTest::isolate(), "number", String::kInternalizedString); + Local<String> undefined_string = + String::NewFromUtf8(CcTest::isolate(), "undefined", + v8::NewStringType::kInternalized) + .ToLocalChecked(); + Local<String> number_string = + String::NewFromUtf8(CcTest::isolate(), "number", + v8::NewStringType::kInternalized) + .ToLocalChecked(); context.Check( "function f(o) { return x; }" diff --git a/deps/v8/test/cctest/test-deoptimization.cc b/deps/v8/test/cctest/test-deoptimization.cc index e6604a379e..7ba16b59f8 100644 --- a/deps/v8/test/cctest/test-deoptimization.cc +++ b/deps/v8/test/cctest/test-deoptimization.cc @@ -113,10 +113,10 @@ static void NonIncrementalGC(i::Isolate* isolate) { } -static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj, +static Handle<JSFunction> GetJSFunction(v8::Local<v8::Context> context, const char* property_name) { - v8::Local<v8::Function> fun = - v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name))); + v8::Local<v8::Function> fun = v8::Local<v8::Function>::Cast( + context->Global()->Get(context, v8_str(property_name)).ToLocalChecked()); return i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*fun)); } @@ -137,8 +137,12 @@ TEST(DeoptimizeSimple) { } NonIncrementalGC(CcTest::i_isolate()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK(!GetJSFunction(env.local(), "f")->IsOptimized()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); // Test lazy deoptimization of a simple function. Call the function after the @@ -153,8 +157,12 @@ TEST(DeoptimizeSimple) { } NonIncrementalGC(CcTest::i_isolate()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK(!GetJSFunction(env.local(), "f")->IsOptimized()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -175,8 +183,12 @@ TEST(DeoptimizeSimpleWithArguments) { } NonIncrementalGC(CcTest::i_isolate()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK(!GetJSFunction(env.local(), "f")->IsOptimized()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); // Test lazy deoptimization of a simple function with some arguments. Call the @@ -192,8 +204,12 @@ TEST(DeoptimizeSimpleWithArguments) { } NonIncrementalGC(CcTest::i_isolate()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK(!GetJSFunction(env.local(), "f")->IsOptimized()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -215,9 +231,17 @@ TEST(DeoptimizeSimpleNested) { "result = f(1, 2, 3);"); NonIncrementalGC(CcTest::i_isolate()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(6, env->Global()->Get(v8_str("result"))->Int32Value()); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(6, env->Global() + ->Get(env.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK(!GetJSFunction(env.local(), "f")->IsOptimized()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } } @@ -240,12 +264,22 @@ TEST(DeoptimizeRecursive) { } NonIncrementalGC(CcTest::i_isolate()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(11, env->Global()->Get(v8_str("calls"))->Int32Value()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(11, env->Global() + ->Get(env.local(), v8_str("calls")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); v8::Local<v8::Function> fun = v8::Local<v8::Function>::Cast( - env->Global()->Get(v8::String::NewFromUtf8(CcTest::isolate(), "f"))); + env->Global() + ->Get(env.local(), v8_str(CcTest::isolate(), "f")) + .ToLocalChecked()); CHECK(!fun.IsEmpty()); } @@ -272,8 +306,16 @@ TEST(DeoptimizeMultiple) { } NonIncrementalGC(CcTest::i_isolate()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(14, env->Global() + ->Get(env.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -293,8 +335,15 @@ TEST(DeoptimizeConstructor) { } NonIncrementalGC(CcTest::i_isolate()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK(env->Global()->Get(v8_str("result"))->IsTrue()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK(env->Global() + ->Get(env.local(), v8_str("result")) + .ToLocalChecked() + ->IsTrue()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); { @@ -310,8 +359,16 @@ TEST(DeoptimizeConstructor) { } NonIncrementalGC(CcTest::i_isolate()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(3, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(3, env->Global() + ->Get(env.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -339,8 +396,16 @@ TEST(DeoptimizeConstructorMultiple) { } NonIncrementalGC(CcTest::i_isolate()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(14, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(14, env->Global() + ->Get(env.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(CcTest::i_isolate())); } @@ -382,7 +447,7 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationADDString) { CompileRun(f_source); CompileRun("f('a+', new X());"); CHECK(!i_isolate->use_crankshaft() || - GetJSFunction(env->Global(), "f")->IsOptimized()); + GetJSFunction(env.local(), "f")->IsOptimized()); // Call f and force deoptimization while processing the binary operation. CompileRun( @@ -391,9 +456,14 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationADDString) { } NonIncrementalGC(i_isolate); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - v8::Handle<v8::Value> result = env->Global()->Get(v8_str("result")); + CHECK(!GetJSFunction(env.local(), "f")->IsOptimized()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + v8::Local<v8::Value> result = + env->Global()->Get(env.local(), v8_str("result")).ToLocalChecked(); CHECK(result->IsString()); v8::String::Utf8Value utf8(result); CHECK_EQ(0, strcmp("a+an X", *utf8)); @@ -439,13 +509,13 @@ static void TestDeoptimizeBinaryOpHelper(LocalContext* env, CompileRun(f_source); CompileRun("f(7, new X());"); CHECK(!i_isolate->use_crankshaft() || - GetJSFunction((*env)->Global(), "f")->IsOptimized()); + GetJSFunction((*env).local(), "f")->IsOptimized()); // Call f and force deoptimization while processing the binary operation. CompileRun("deopt = true;" "var result = f(7, new X());"); NonIncrementalGC(i_isolate); - CHECK(!GetJSFunction((*env)->Global(), "f")->IsOptimized()); + CHECK(!GetJSFunction((*env).local(), "f")->IsOptimized()); } @@ -462,8 +532,16 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationADD) { TestDeoptimizeBinaryOpHelper(&env, "+"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(15, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(15, env->Global() + ->Get(env.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); } isolate->Exit(); @@ -484,8 +562,16 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationSUB) { TestDeoptimizeBinaryOpHelper(&env, "-"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(-1, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(-1, env->Global() + ->Get(env.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); } isolate->Exit(); @@ -506,8 +592,16 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationMUL) { TestDeoptimizeBinaryOpHelper(&env, "*"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(56, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(56, env->Global() + ->Get(env.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); } isolate->Exit(); @@ -528,8 +622,16 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationDIV) { TestDeoptimizeBinaryOpHelper(&env, "/"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(0, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(0, env->Global() + ->Get(env.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); } isolate->Exit(); @@ -550,8 +652,16 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationMOD) { TestDeoptimizeBinaryOpHelper(&env, "%"); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(7, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(7, env->Global() + ->Get(env.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); } isolate->Exit(); @@ -596,7 +706,7 @@ UNINITIALIZED_TEST(DeoptimizeCompare) { CompileRun(f_source); CompileRun("f('a', new X());"); CHECK(!i_isolate->use_crankshaft() || - GetJSFunction(env->Global(), "f")->IsOptimized()); + GetJSFunction(env.local(), "f")->IsOptimized()); // Call f and force deoptimization while processing the comparison. CompileRun( @@ -605,9 +715,17 @@ UNINITIALIZED_TEST(DeoptimizeCompare) { } NonIncrementalGC(i_isolate); - CHECK(!GetJSFunction(env->Global(), "f")->IsOptimized()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(true, env->Global()->Get(v8_str("result"))->BooleanValue()); + CHECK(!GetJSFunction(env.local(), "f")->IsOptimized()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(true, env->Global() + ->Get(env.local(), v8_str("result")) + .ToLocalChecked() + ->BooleanValue(env.local()) + .FromJust()); CHECK_EQ(0, Deoptimizer::GetDeoptimizedCodeCount(i_isolate)); } isolate->Exit(); @@ -679,10 +797,10 @@ UNINITIALIZED_TEST(DeoptimizeLoadICStoreIC) { CompileRun("f2(new X(), 'z');"); CompileRun("g2(new X(), 'z');"); if (i_isolate->use_crankshaft()) { - CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); + CHECK(GetJSFunction(env.local(), "f1")->IsOptimized()); + CHECK(GetJSFunction(env.local(), "g1")->IsOptimized()); + CHECK(GetJSFunction(env.local(), "f2")->IsOptimized()); + CHECK(GetJSFunction(env.local(), "g2")->IsOptimized()); } // Call functions and force deoptimization while processing the ics. @@ -695,12 +813,20 @@ UNINITIALIZED_TEST(DeoptimizeLoadICStoreIC) { } NonIncrementalGC(i_isolate); - CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); - CHECK_EQ(4, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK(!GetJSFunction(env.local(), "f1")->IsOptimized()); + CHECK(!GetJSFunction(env.local(), "g1")->IsOptimized()); + CHECK(!GetJSFunction(env.local(), "f2")->IsOptimized()); + CHECK(!GetJSFunction(env.local(), "g2")->IsOptimized()); + CHECK_EQ(4, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(13, env->Global() + ->Get(env.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); } isolate->Exit(); isolate->Dispose(); @@ -775,10 +901,10 @@ UNINITIALIZED_TEST(DeoptimizeLoadICStoreICNested) { CompileRun("f2(new X(), 'z');"); CompileRun("g2(new X(), 'z');"); if (i_isolate->use_crankshaft()) { - CHECK(GetJSFunction(env->Global(), "f1")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "g1")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "f2")->IsOptimized()); - CHECK(GetJSFunction(env->Global(), "g2")->IsOptimized()); + CHECK(GetJSFunction(env.local(), "f1")->IsOptimized()); + CHECK(GetJSFunction(env.local(), "g1")->IsOptimized()); + CHECK(GetJSFunction(env.local(), "f2")->IsOptimized()); + CHECK(GetJSFunction(env.local(), "g2")->IsOptimized()); } // Call functions and force deoptimization while processing the ics. @@ -788,12 +914,20 @@ UNINITIALIZED_TEST(DeoptimizeLoadICStoreICNested) { } NonIncrementalGC(i_isolate); - CHECK(!GetJSFunction(env->Global(), "f1")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "g1")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "f2")->IsOptimized()); - CHECK(!GetJSFunction(env->Global(), "g2")->IsOptimized()); - CHECK_EQ(1, env->Global()->Get(v8_str("count"))->Int32Value()); - CHECK_EQ(13, env->Global()->Get(v8_str("result"))->Int32Value()); + CHECK(!GetJSFunction(env.local(), "f1")->IsOptimized()); + CHECK(!GetJSFunction(env.local(), "g1")->IsOptimized()); + CHECK(!GetJSFunction(env.local(), "f2")->IsOptimized()); + CHECK(!GetJSFunction(env.local(), "g2")->IsOptimized()); + CHECK_EQ(1, env->Global() + ->Get(env.local(), v8_str("count")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); + CHECK_EQ(13, env->Global() + ->Get(env.local(), v8_str("result")) + .ToLocalChecked() + ->Int32Value(env.local()) + .FromJust()); } isolate->Exit(); isolate->Dispose(); diff --git a/deps/v8/test/cctest/test-dictionary.cc b/deps/v8/test/cctest/test-dictionary.cc index 68c35f958e..0d4edf5dd4 100644 --- a/deps/v8/test/cctest/test-dictionary.cc +++ b/deps/v8/test/cctest/test-dictionary.cc @@ -35,6 +35,7 @@ #include "src/global-handles.h" #include "src/macro-assembler.h" #include "src/objects.h" +#include "test/cctest/heap/utils-inl.h" using namespace v8::internal; @@ -227,4 +228,18 @@ TEST(ObjectHashTableCausesGC) { } #endif +TEST(SetRequiresCopyOnCapacityChange) { + LocalContext context; + v8::HandleScope scope(context->GetIsolate()); + Isolate* isolate = CcTest::i_isolate(); + Handle<NameDictionary> dict = NameDictionary::New(isolate, 0, TENURED); + dict->SetRequiresCopyOnCapacityChange(); + Handle<Name> key = isolate->factory()->InternalizeString( + v8::Utils::OpenHandle(*v8_str("key"))); + Handle<Object> value = handle(Smi::FromInt(0), isolate); + Handle<NameDictionary> new_dict = + NameDictionary::Add(dict, key, value, PropertyDetails::Empty()); + CHECK_NE(*dict, *new_dict); +} + } // namespace diff --git a/deps/v8/test/cctest/test-disasm-arm64.cc b/deps/v8/test/cctest/test-disasm-arm64.cc index 357bfc5ad9..beca93ede2 100644 --- a/deps/v8/test/cctest/test-disasm-arm64.cc +++ b/deps/v8/test/cctest/test-disasm-arm64.cc @@ -45,20 +45,31 @@ using namespace v8::internal; #define EXP_SIZE (256) #define INSTR_SIZE (1024) -#define SET_UP_CLASS(ASMCLASS) \ +#define SET_UP_MASM() \ + InitializeVM(); \ + Isolate* isolate = CcTest::i_isolate(); \ + HandleScope scope(isolate); \ + byte* buf = static_cast<byte*>(malloc(INSTR_SIZE)); \ + uint32_t encoding = 0; \ + MacroAssembler* assm = new MacroAssembler( \ + isolate, buf, INSTR_SIZE, v8::internal::CodeObjectRequired::kYes); \ + Decoder<DispatchingDecoderVisitor>* decoder = \ + new Decoder<DispatchingDecoderVisitor>(); \ + DisassemblingDecoder* disasm = new DisassemblingDecoder(); \ + decoder->AppendVisitor(disasm) + +#define SET_UP_ASM() \ InitializeVM(); \ - Isolate* isolate = Isolate::Current(); \ + Isolate* isolate = CcTest::i_isolate(); \ HandleScope scope(isolate); \ byte* buf = static_cast<byte*>(malloc(INSTR_SIZE)); \ uint32_t encoding = 0; \ - ASMCLASS* assm = new ASMCLASS(isolate, buf, INSTR_SIZE); \ + Assembler* assm = new Assembler(isolate, buf, INSTR_SIZE); \ Decoder<DispatchingDecoderVisitor>* decoder = \ new Decoder<DispatchingDecoderVisitor>(); \ DisassemblingDecoder* disasm = new DisassemblingDecoder(); \ decoder->AppendVisitor(disasm) -#define SET_UP() SET_UP_CLASS(Assembler) - #define COMPARE(ASM, EXP) \ assm->Reset(); \ assm->ASM; \ @@ -102,7 +113,7 @@ static void InitializeVM() { TEST_(bootstrap) { - SET_UP(); + SET_UP_ASM(); // Instructions generated by C compiler, disassembled by objdump, and // reformatted to suit our disassembly style. @@ -132,7 +143,7 @@ TEST_(bootstrap) { TEST_(mov_mvn) { - SET_UP_CLASS(MacroAssembler); + SET_UP_MASM(); COMPARE(Mov(w0, Operand(0x1234)), "movz w0, #0x1234"); COMPARE(Mov(x1, Operand(0x1234)), "movz x1, #0x1234"); @@ -166,7 +177,7 @@ TEST_(mov_mvn) { TEST_(move_immediate) { - SET_UP(); + SET_UP_ASM(); COMPARE(movz(w0, 0x1234), "movz w0, #0x1234"); COMPARE(movz(x1, 0xabcd0000), "movz x1, #0xabcd0000"); @@ -203,7 +214,7 @@ TEST_(move_immediate) { TEST(move_immediate_2) { - SET_UP_CLASS(MacroAssembler); + SET_UP_MASM(); // Move instructions expected for certain immediates. This is really a macro // assembler test, to ensure it generates immediates efficiently. @@ -259,7 +270,7 @@ TEST(move_immediate_2) { TEST_(add_immediate) { - SET_UP(); + SET_UP_ASM(); COMPARE(add(w0, w1, Operand(0xff)), "add w0, w1, #0xff (255)"); COMPARE(add(x2, x3, Operand(0x3ff)), "add x2, x3, #0x3ff (1023)"); @@ -289,7 +300,7 @@ TEST_(add_immediate) { TEST_(sub_immediate) { - SET_UP(); + SET_UP_ASM(); COMPARE(sub(w0, w1, Operand(0xff)), "sub w0, w1, #0xff (255)"); COMPARE(sub(x2, x3, Operand(0x3ff)), "sub x2, x3, #0x3ff (1023)"); @@ -317,7 +328,7 @@ TEST_(sub_immediate) { TEST_(add_shifted) { - SET_UP(); + SET_UP_ASM(); COMPARE(add(w0, w1, Operand(w2)), "add w0, w1, w2"); COMPARE(add(x3, x4, Operand(x5)), "add x3, x4, x5"); @@ -343,7 +354,7 @@ TEST_(add_shifted) { TEST_(sub_shifted) { - SET_UP(); + SET_UP_ASM(); COMPARE(sub(w0, w1, Operand(w2)), "sub w0, w1, w2"); COMPARE(sub(x3, x4, Operand(x5)), "sub x3, x4, x5"); @@ -373,7 +384,7 @@ TEST_(sub_shifted) { TEST_(add_extended) { - SET_UP(); + SET_UP_ASM(); COMPARE(add(w0, w1, Operand(w2, UXTB)), "add w0, w1, w2, uxtb"); COMPARE(adds(x3, x4, Operand(w5, UXTB, 1)), "adds x3, x4, w5, uxtb #1"); @@ -399,7 +410,7 @@ TEST_(add_extended) { TEST_(sub_extended) { - SET_UP(); + SET_UP_ASM(); COMPARE(sub(w0, w1, Operand(w2, UXTB)), "sub w0, w1, w2, uxtb"); COMPARE(subs(x3, x4, Operand(w5, UXTB, 1)), "subs x3, x4, w5, uxtb #1"); @@ -425,7 +436,7 @@ TEST_(sub_extended) { TEST_(adc_subc_ngc) { - SET_UP(); + SET_UP_ASM(); COMPARE(adc(w0, w1, Operand(w2)), "adc w0, w1, w2"); COMPARE(adc(x3, x4, Operand(x5)), "adc x3, x4, x5"); @@ -445,7 +456,7 @@ TEST_(adc_subc_ngc) { TEST_(mul_and_div) { - SET_UP(); + SET_UP_ASM(); COMPARE(mul(w0, w1, w2), "mul w0, w1, w2"); COMPARE(mul(x3, x4, x5), "mul x3, x4, x5"); @@ -478,7 +489,7 @@ TEST_(mul_and_div) { TEST(maddl_msubl) { - SET_UP(); + SET_UP_ASM(); COMPARE(smaddl(x0, w1, w2, x3), "smaddl x0, w1, w2, x3"); COMPARE(smaddl(x25, w21, w22, x16), "smaddl x25, w21, w22, x16"); @@ -495,7 +506,7 @@ TEST(maddl_msubl) { TEST_(dp_1_source) { - SET_UP(); + SET_UP_ASM(); COMPARE(rbit(w0, w1), "rbit w0, w1"); COMPARE(rbit(x2, x3), "rbit x2, x3"); @@ -514,7 +525,7 @@ TEST_(dp_1_source) { TEST_(bitfield) { - SET_UP(); + SET_UP_ASM(); COMPARE(sxtb(w0, w1), "sxtb w0, w1"); COMPARE(sxtb(x2, x3), "sxtb x2, w3"); @@ -556,7 +567,7 @@ TEST_(bitfield) { TEST_(extract) { - SET_UP(); + SET_UP_ASM(); COMPARE(extr(w0, w1, w2, 0), "extr w0, w1, w2, #0"); COMPARE(extr(x3, x4, x5, 1), "extr x3, x4, x5, #1"); @@ -570,7 +581,7 @@ TEST_(extract) { TEST_(logical_immediate) { - SET_UP(); + SET_UP_ASM(); #define RESULT_SIZE (256) char result[RESULT_SIZE]; @@ -696,7 +707,7 @@ TEST_(logical_immediate) { TEST_(logical_shifted) { - SET_UP(); + SET_UP_ASM(); COMPARE(and_(w0, w1, Operand(w2)), "and w0, w1, w2"); COMPARE(and_(x3, x4, Operand(x5, LSL, 1)), "and x3, x4, x5, lsl #1"); @@ -766,7 +777,7 @@ TEST_(logical_shifted) { TEST_(dp_2_source) { - SET_UP(); + SET_UP_ASM(); COMPARE(lslv(w0, w1, w2), "lsl w0, w1, w2"); COMPARE(lslv(x3, x4, x5), "lsl x3, x4, x5"); @@ -782,7 +793,7 @@ TEST_(dp_2_source) { TEST_(adr) { - SET_UP(); + SET_UP_ASM(); COMPARE_PREFIX(adr(x0, 0), "adr x0, #+0x0"); COMPARE_PREFIX(adr(x1, 1), "adr x1, #+0x1"); @@ -798,7 +809,7 @@ TEST_(adr) { TEST_(branch) { - SET_UP(); + SET_UP_ASM(); #define INST_OFF(x) ((x) >> kInstructionSizeLog2) COMPARE_PREFIX(b(INST_OFF(0x4)), "b #+0x4"); @@ -835,7 +846,7 @@ TEST_(branch) { TEST_(load_store) { - SET_UP(); + SET_UP_ASM(); COMPARE(ldr(w0, MemOperand(x1)), "ldr w0, [x1]"); COMPARE(ldr(w2, MemOperand(x3, 4)), "ldr w2, [x3, #4]"); @@ -892,7 +903,7 @@ TEST_(load_store) { TEST_(load_store_regoffset) { - SET_UP(); + SET_UP_ASM(); COMPARE(ldr(w0, MemOperand(x1, w2, UXTW)), "ldr w0, [x1, w2, uxtw]"); COMPARE(ldr(w3, MemOperand(x4, w5, UXTW, 2)), "ldr w3, [x4, w5, uxtw #2]"); @@ -977,7 +988,7 @@ TEST_(load_store_regoffset) { TEST_(load_store_byte) { - SET_UP(); + SET_UP_ASM(); COMPARE(ldrb(w0, MemOperand(x1)), "ldrb w0, [x1]"); COMPARE(ldrb(x2, MemOperand(x3)), "ldrb w2, [x3]"); @@ -1009,7 +1020,7 @@ TEST_(load_store_byte) { TEST_(load_store_half) { - SET_UP(); + SET_UP_ASM(); COMPARE(ldrh(w0, MemOperand(x1)), "ldrh w0, [x1]"); COMPARE(ldrh(x2, MemOperand(x3)), "ldrh w2, [x3]"); @@ -1045,7 +1056,7 @@ TEST_(load_store_half) { TEST_(load_store_fp) { - SET_UP(); + SET_UP_ASM(); COMPARE(ldr(s0, MemOperand(x1)), "ldr s0, [x1]"); COMPARE(ldr(s2, MemOperand(x3, 4)), "ldr s2, [x3, #4]"); @@ -1097,7 +1108,7 @@ TEST_(load_store_fp) { TEST_(load_store_unscaled) { - SET_UP(); + SET_UP_ASM(); COMPARE(ldr(w0, MemOperand(x1, 1)), "ldur w0, [x1, #1]"); COMPARE(ldr(w2, MemOperand(x3, -1)), "ldur w2, [x3, #-1]"); @@ -1130,7 +1141,7 @@ TEST_(load_store_unscaled) { TEST_(load_store_pair) { - SET_UP(); + SET_UP_ASM(); COMPARE(ldp(w0, w1, MemOperand(x2)), "ldp w0, w1, [x2]"); COMPARE(ldp(x3, x4, MemOperand(x5)), "ldp x3, x4, [x5]"); @@ -1251,7 +1262,7 @@ TEST_(load_store_pair) { #if 0 // TODO(all): enable. TEST_(load_literal) { - SET_UP(); + SET_UP_ASM(); COMPARE_PREFIX(ldr(x10, 0x1234567890abcdefUL), "ldr x10, pc+8"); COMPARE_PREFIX(ldr(w20, 0xfedcba09), "ldr w20, pc+8"); @@ -1263,7 +1274,7 @@ TEST_(load_literal) { #endif TEST_(cond_select) { - SET_UP(); + SET_UP_ASM(); COMPARE(csel(w0, w1, w2, eq), "csel w0, w1, w2, eq"); COMPARE(csel(x3, x4, x5, ne), "csel x3, x4, x5, ne"); @@ -1298,7 +1309,7 @@ TEST_(cond_select) { TEST(cond_select_macro) { - SET_UP_CLASS(MacroAssembler); + SET_UP_MASM(); COMPARE(Csel(w0, w1, -1, eq), "csinv w0, w1, wzr, eq"); COMPARE(Csel(w2, w3, 0, ne), "csel w2, w3, wzr, ne"); @@ -1312,7 +1323,7 @@ TEST(cond_select_macro) { TEST_(cond_cmp) { - SET_UP(); + SET_UP_ASM(); COMPARE(ccmn(w0, w1, NZCVFlag, eq), "ccmn w0, w1, #NZCV, eq"); COMPARE(ccmn(x2, x3, NZCFlag, ne), "ccmn x2, x3, #NZCv, ne"); @@ -1330,7 +1341,7 @@ TEST_(cond_cmp) { TEST_(cond_cmp_macro) { - SET_UP_CLASS(MacroAssembler); + SET_UP_MASM(); COMPARE(Ccmp(w0, -1, VFlag, hi), "ccmn w0, #1, #nzcV, hi"); COMPARE(Ccmp(x1, -31, CFlag, ge), "ccmn x1, #31, #nzCv, ge"); @@ -1342,7 +1353,7 @@ TEST_(cond_cmp_macro) { TEST_(fmov_imm) { - SET_UP(); + SET_UP_ASM(); COMPARE(fmov(s0, 1.0f), "fmov s0, #0x70 (1.0000)"); COMPARE(fmov(s31, -13.0f), "fmov s31, #0xaa (-13.0000)"); @@ -1354,7 +1365,7 @@ TEST_(fmov_imm) { TEST_(fmov_reg) { - SET_UP(); + SET_UP_ASM(); COMPARE(fmov(w3, s13), "fmov w3, s13"); COMPARE(fmov(x6, d26), "fmov x6, d26"); @@ -1368,7 +1379,7 @@ TEST_(fmov_reg) { TEST_(fp_dp1) { - SET_UP(); + SET_UP_ASM(); COMPARE(fabs(s0, s1), "fabs s0, s1"); COMPARE(fabs(s31, s30), "fabs s31, s30"); @@ -1406,7 +1417,7 @@ TEST_(fp_dp1) { TEST_(fp_dp2) { - SET_UP(); + SET_UP_ASM(); COMPARE(fadd(s0, s1, s2), "fadd s0, s1, s2"); COMPARE(fadd(d3, d4, d5), "fadd d3, d4, d5"); @@ -1430,7 +1441,7 @@ TEST_(fp_dp2) { TEST(fp_dp3) { - SET_UP(); + SET_UP_ASM(); COMPARE(fmadd(s7, s8, s9, s10), "fmadd s7, s8, s9, s10"); COMPARE(fmadd(d10, d11, d12, d10), "fmadd d10, d11, d12, d10"); @@ -1447,7 +1458,7 @@ TEST(fp_dp3) { TEST_(fp_compare) { - SET_UP(); + SET_UP_ASM(); COMPARE(fcmp(s0, s1), "fcmp s0, s1"); COMPARE(fcmp(s31, s30), "fcmp s31, s30"); @@ -1461,7 +1472,7 @@ TEST_(fp_compare) { TEST_(fp_cond_compare) { - SET_UP(); + SET_UP_ASM(); COMPARE(fccmp(s0, s1, NoFlag, eq), "fccmp s0, s1, #nzcv, eq"); COMPARE(fccmp(s2, s3, ZVFlag, ne), "fccmp s2, s3, #nZcV, ne"); @@ -1479,7 +1490,7 @@ TEST_(fp_cond_compare) { TEST_(fp_select) { - SET_UP(); + SET_UP_ASM(); COMPARE(fcsel(s0, s1, s2, eq), "fcsel s0, s1, s2, eq") COMPARE(fcsel(s31, s31, s30, ne), "fcsel s31, s31, s30, ne"); @@ -1493,7 +1504,7 @@ TEST_(fp_select) { TEST_(fcvt_scvtf_ucvtf) { - SET_UP(); + SET_UP_ASM(); COMPARE(fcvtas(w0, s1), "fcvtas w0, s1"); COMPARE(fcvtas(x2, s3), "fcvtas x2, s3"); @@ -1555,7 +1566,7 @@ TEST_(fcvt_scvtf_ucvtf) { TEST_(system_mrs) { - SET_UP(); + SET_UP_ASM(); COMPARE(mrs(x0, NZCV), "mrs x0, nzcv"); COMPARE(mrs(lr, NZCV), "mrs lr, nzcv"); @@ -1566,7 +1577,7 @@ TEST_(system_mrs) { TEST_(system_msr) { - SET_UP(); + SET_UP_ASM(); COMPARE(msr(NZCV, x0), "msr nzcv, x0"); COMPARE(msr(NZCV, x30), "msr nzcv, lr"); @@ -1577,7 +1588,7 @@ TEST_(system_msr) { TEST_(system_nop) { - SET_UP(); + SET_UP_ASM(); COMPARE(nop(), "nop"); @@ -1586,9 +1597,9 @@ TEST_(system_nop) { TEST_(debug) { - SET_UP(); + SET_UP_ASM(); - DCHECK(kImmExceptionIsDebug == 0xdeb0); + CHECK(kImmExceptionIsDebug == 0xdeb0); // All debug codes should produce the same instruction, and the debug code // can be any uint32_t. @@ -1605,7 +1616,7 @@ TEST_(debug) { TEST_(hlt) { - SET_UP(); + SET_UP_ASM(); COMPARE(hlt(0), "hlt #0x0"); COMPARE(hlt(1), "hlt #0x1"); @@ -1616,7 +1627,7 @@ TEST_(hlt) { TEST_(brk) { - SET_UP(); + SET_UP_ASM(); COMPARE(brk(0), "brk #0x0"); COMPARE(brk(1), "brk #0x1"); @@ -1627,7 +1638,7 @@ TEST_(brk) { TEST_(add_sub_negative) { - SET_UP_CLASS(MacroAssembler); + SET_UP_MASM(); COMPARE(Add(x10, x0, -42), "sub x10, x0, #0x2a (42)"); COMPARE(Add(x11, x1, -687), "sub x11, x1, #0x2af (687)"); @@ -1658,7 +1669,7 @@ TEST_(add_sub_negative) { TEST_(logical_immediate_move) { - SET_UP_CLASS(MacroAssembler); + SET_UP_MASM(); COMPARE(And(w0, w1, 0), "movz w0, #0x0"); COMPARE(And(x0, x1, 0), "movz x0, #0x0"); @@ -1697,7 +1708,7 @@ TEST_(logical_immediate_move) { TEST_(barriers) { - SET_UP_CLASS(MacroAssembler); + SET_UP_MASM(); // DMB COMPARE(Dmb(FullSystem, BarrierAll), "dmb sy"); diff --git a/deps/v8/test/cctest/test-disasm-mips.cc b/deps/v8/test/cctest/test-disasm-mips.cc index 63b2b11aa9..9a7d8ae431 100644 --- a/deps/v8/test/cctest/test-disasm-mips.cc +++ b/deps/v8/test/cctest/test-disasm-mips.cc @@ -565,6 +565,11 @@ TEST(Type0) { COMPARE(lui(v0, 0xffff), "3c02ffff lui v0, 0xffff"); + if (IsMipsArchVariant(kMips32r6)) { + COMPARE(aui(a0, a1, 0x1), "3ca40001 aui a0, a1, 0x1"); + COMPARE(aui(v0, v1, 0xffff), "3c62ffff aui v0, v1, 0xffff"); + } + COMPARE(sll(a0, a1, 0), "00052000 sll a0, a1, 0"); COMPARE(sll(s0, s1, 8), @@ -890,27 +895,33 @@ TEST(Type1) { COMPARE(maxa_s(f3, f4, f5), "460520df maxa.s f3, f4, f5"); } + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { + COMPARE(trunc_l_d(f8, f6), "46203209 trunc.l.d f8, f6"); + COMPARE(trunc_l_s(f8, f6), "46003209 trunc.l.s f8, f6"); + + COMPARE(round_l_s(f8, f6), "46003208 round.l.s f8, f6"); + COMPARE(round_l_d(f8, f6), "46203208 round.l.d f8, f6"); + + COMPARE(floor_l_s(f8, f6), "4600320b floor.l.s f8, f6"); + COMPARE(floor_l_d(f8, f6), "4620320b floor.l.d f8, f6"); + + COMPARE(ceil_l_s(f8, f6), "4600320a ceil.l.s f8, f6"); + COMPARE(ceil_l_d(f8, f6), "4620320a ceil.l.d f8, f6"); + } + COMPARE(trunc_w_d(f8, f6), "4620320d trunc.w.d f8, f6"); COMPARE(trunc_w_s(f8, f6), "4600320d trunc.w.s f8, f6"); COMPARE(round_w_s(f8, f6), "4600320c round.w.s f8, f6"); COMPARE(round_w_d(f8, f6), "4620320c round.w.d f8, f6"); - COMPARE(round_l_s(f8, f6), "46003208 round.l.s f8, f6"); - COMPARE(round_l_d(f8, f6), "46203208 round.l.d f8, f6"); - COMPARE(floor_w_s(f8, f6), "4600320f floor.w.s f8, f6"); COMPARE(floor_w_d(f8, f6), "4620320f floor.w.d f8, f6"); - COMPARE(floor_l_s(f8, f6), "4600320b floor.l.s f8, f6"); - COMPARE(floor_l_d(f8, f6), "4620320b floor.l.d f8, f6"); - COMPARE(ceil_w_s(f8, f6), "4600320e ceil.w.s f8, f6"); COMPARE(ceil_w_d(f8, f6), "4620320e ceil.w.d f8, f6"); - COMPARE(ceil_l_s(f8, f6), "4600320a ceil.l.s f8, f6"); - COMPARE(ceil_l_d(f8, f6), "4620320a ceil.l.d f8, f6"); - COMPARE(sub_s(f10, f8, f6), "46064281 sub.s f10, f8, f6"); COMPARE(sub_d(f10, f8, f6), "46264281 sub.d f10, f8, f6"); @@ -935,9 +946,6 @@ TEST(Type1) { COMPARE(mov_d(f6, f4), "46202186 mov.d f6, f4"); if (IsMipsArchVariant(kMips32r2)) { - COMPARE(trunc_l_d(f8, f6), "46203209 trunc.l.d f8, f6"); - COMPARE(trunc_l_s(f8, f6), "46003209 trunc.l.s f8, f6"); - COMPARE(movz_s(f6, f4, t0), "46082192 movz.s f6, f4, t0"); COMPARE(movz_d(f6, f4, t0), "46282192 movz.d f6, f4, t0"); @@ -1045,23 +1053,28 @@ TEST(CVT_DISSASM) { SET_UP(); COMPARE(cvt_d_s(f22, f24), "4600c5a1 cvt.d.s f22, f24"); COMPARE(cvt_d_w(f22, f24), "4680c5a1 cvt.d.w f22, f24"); - if (IsMipsArchVariant(kMips32r6) || IsMipsArchVariant(kMips32r2)) { - COMPARE(cvt_d_l(f22, f24), "46a0c5a1 cvt.d.l f22, f24"); - } - - if (IsMipsArchVariant(kMips32r6) || IsMipsArchVariant(kMips32r2)) { - COMPARE(cvt_l_s(f22, f24), "4600c5a5 cvt.l.s f22, f24"); - COMPARE(cvt_l_d(f22, f24), "4620c5a5 cvt.l.d f22, f24"); - } COMPARE(cvt_s_d(f22, f24), "4620c5a0 cvt.s.d f22, f24"); COMPARE(cvt_s_w(f22, f24), "4680c5a0 cvt.s.w f22, f24"); - if (IsMipsArchVariant(kMips32r6) || IsMipsArchVariant(kMips32r2)) { + + if ((IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) && + IsFp64Mode()) { + COMPARE(cvt_d_l(f22, f24), "46a0c5a1 cvt.d.l f22, f24"); + COMPARE(cvt_l_d(f22, f24), "4620c5a5 cvt.l.d f22, f24"); + COMPARE(cvt_s_l(f22, f24), "46a0c5a0 cvt.s.l f22, f24"); + COMPARE(cvt_l_s(f22, f24), "4600c5a5 cvt.l.s f22, f24"); } - COMPARE(cvt_s_d(f22, f24), "4620c5a0 cvt.s.d f22, f24"); - COMPARE(cvt_s_w(f22, f24), "4680c5a0 cvt.s.w f22, f24"); + VERIFY_RUN(); +} + +TEST(ctc1_cfc1_disasm) { + SET_UP(); + COMPARE(abs_d(f10, f31), "4620fa85 abs.d f10, f31"); + COMPARE(ceil_w_s(f8, f31), "4600fa0e ceil.w.s f8, f31"); + COMPARE(ctc1(a0, FCSR), "44c4f800 ctc1 a0, FCSR"); + COMPARE(cfc1(a0, FCSR), "4444f800 cfc1 a0, FCSR"); VERIFY_RUN(); } diff --git a/deps/v8/test/cctest/test-disasm-mips64.cc b/deps/v8/test/cctest/test-disasm-mips64.cc index 7cf6397886..8a1e0e7db0 100644 --- a/deps/v8/test/cctest/test-disasm-mips64.cc +++ b/deps/v8/test/cctest/test-disasm-mips64.cc @@ -38,12 +38,18 @@ using namespace v8::internal; +bool prev_instr_compact_branch = false; bool DisassembleAndCompare(byte* pc, const char* compare_string) { disasm::NameConverter converter; disasm::Disassembler disasm(converter); EmbeddedVector<char, 128> disasm_buffer; + if (prev_instr_compact_branch) { + disasm.InstructionDecode(disasm_buffer, pc); + pc += 4; + } + disasm.InstructionDecode(disasm_buffer, pc); if (strcmp(compare_string, disasm_buffer.start()) != 0) { @@ -97,8 +103,14 @@ if (failure) { \ int pc_offset = assm.pc_offset(); \ 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 * 4)); \ + prev_instr_compact_branch = assm.IsPrevInstrCompactBranch(); \ + if (prev_instr_compact_branch) { \ + snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \ + compare_string, progcounter + 8 + (offset * 4)); \ + } else { \ + snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \ + compare_string, progcounter + 4 + (offset * 4)); \ + } \ assm.asm_; \ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \ } @@ -402,6 +414,20 @@ TEST(Type0) { COMPARE(lui(v0, 0xffff), "3c02ffff lui v0, 0xffff"); + if (kArchVariant == (kMips64r6)) { + COMPARE(aui(a0, a1, 0x1), "3ca40001 aui a0, a1, 0x1"); + COMPARE(aui(v0, v1, 0xffff), "3c62ffff aui v0, v1, 0xffff"); + + COMPARE(daui(a0, a1, 0x1), "74a40001 daui a0, a1, 0x1"); + COMPARE(daui(v0, v1, 0xffff), "7462ffff daui v0, v1, 0xffff"); + + COMPARE(dahi(a0, 0x1), "04860001 dahi a0, 0x1"); + COMPARE(dahi(v0, 0xffff), "0446ffff dahi v0, 0xffff"); + + COMPARE(dati(a0, 0x1), "049e0001 dati a0, 0x1"); + COMPARE(dati(v0, 0xffff), "045effff dati v0, 0xffff"); + } + COMPARE(sll(a0, a1, 0), "00052000 sll a0, a1, 0"); COMPARE(sll(s0, s1, 8), @@ -756,14 +782,6 @@ TEST(Type0) { } if (kArchVariant == kMips64r6) { - COMPARE_PC_REL_COMPACT(beqzc(a0, 16), "d8800010 beqzc a0, 0x10", - 16); - COMPARE_PC_REL_COMPACT(beqzc(a0, 4), "d8800004 beqzc a0, 0x4", 4); - COMPARE_PC_REL_COMPACT(beqzc(a0, -32), - "d89fffe0 beqzc a0, 0x1fffe0", -32); - } - - if (kArchVariant == kMips64r6) { COMPARE(ldpc(v0, 256), "ec580100 ldpc v0, 256"); COMPARE(ldpc(a0, -1), "ec9bffff ldpc a0, -1"); COMPARE(ldpc(a1, 0), "ecb80000 ldpc a1, 0"); @@ -778,11 +796,11 @@ TEST(Type0) { } if (kArchVariant == kMips64r6) { - COMPARE(jialc(a0, -32768), "f8048000 jialc a0, 0x8000"); - COMPARE(jialc(a0, -1), "f804ffff jialc a0, 0xffff"); - COMPARE(jialc(v0, 0), "f8020000 jialc v0, 0x0"); - COMPARE(jialc(s1, 1), "f8110001 jialc s1, 0x1"); - COMPARE(jialc(a0, 32767), "f8047fff jialc a0, 0x7fff"); + COMPARE(jialc(a0, -32768), "f8048000 jialc a0, -32768"); + COMPARE(jialc(a0, -1), "f804ffff jialc a0, -1"); + COMPARE(jialc(v0, 0), "f8020000 jialc v0, 0"); + COMPARE(jialc(s1, 1), "f8110001 jialc s1, 1"); + COMPARE(jialc(a0, 32767), "f8047fff jialc a0, 32767"); } VERIFY_RUN(); @@ -915,17 +933,17 @@ TEST(Type3) { COMPARE_PC_REL_COMPACT(bnvc(a1, a0, -32768), "60a48000 bnvc a1, a0, -32768", -32768); - COMPARE_PC_REL_COMPACT(beqzc(a0, 0), "d8800000 beqzc a0, 0x0", 0); - COMPARE_PC_REL_COMPACT(beqzc(a0, 0xfffff), // 0x0fffff == 1048575. - "d88fffff beqzc a0, 0xfffff", 1048575); - COMPARE_PC_REL_COMPACT(beqzc(a0, 0x100000), // 0x100000 == -1048576. - "d8900000 beqzc a0, 0x100000", -1048576); + COMPARE_PC_REL_COMPACT(beqzc(a0, 0), "d8800000 beqzc a0, 0", 0); + COMPARE_PC_REL_COMPACT(beqzc(a0, 1048575), // 0x0fffff == 1048575. + "d88fffff beqzc a0, 1048575", 1048575); + COMPARE_PC_REL_COMPACT(beqzc(a0, -1048576), // 0x100000 == -1048576. + "d8900000 beqzc a0, -1048576", -1048576); - COMPARE_PC_REL_COMPACT(bnezc(a0, 0), "f8800000 bnezc a0, 0x0", 0); - COMPARE_PC_REL_COMPACT(bnezc(a0, 0xfffff), // 0x0fffff == 1048575. - "f88fffff bnezc a0, 0xfffff", 1048575); - COMPARE_PC_REL_COMPACT(bnezc(a0, 0x100000), // 0x100000 == -1048576. - "f8900000 bnezc a0, 0x100000", -1048576); + COMPARE_PC_REL_COMPACT(bnezc(a0, 0), "f8800000 bnezc a0, 0", 0); + COMPARE_PC_REL_COMPACT(bnezc(a0, 1048575), // int21 maximal value. + "f88fffff bnezc a0, 1048575", 1048575); + COMPARE_PC_REL_COMPACT(bnezc(a0, -1048576), // int21 minimal value. + "f8900000 bnezc a0, -1048576", -1048576); COMPARE_PC_REL_COMPACT(bc(-33554432), "ca000000 bc -33554432", -33554432); @@ -944,29 +962,29 @@ TEST(Type3) { 33554431); COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -32768), - "18858000 bgeuc a0, a1, -32768", -32768); + "18858000 bgeuc a0, a1, -32768", -32768); COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -1), - "1885ffff bgeuc a0, a1, -1", -1); - COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 1), - "18850001 bgeuc a0, a1, 1", 1); + "1885ffff bgeuc a0, a1, -1", -1); + COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 1), "18850001 bgeuc a0, a1, 1", + 1); COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 32767), - "18857fff bgeuc a0, a1, 32767", 32767); + "18857fff bgeuc a0, a1, 32767", 32767); COMPARE_PC_REL_COMPACT(bgezalc(a0, -32768), - "18848000 bgezalc a0, -32768", -32768); - COMPARE_PC_REL_COMPACT(bgezalc(a0, -1), "1884ffff bgezalc a0, -1", + "18848000 bgezalc a0, -32768", -32768); + COMPARE_PC_REL_COMPACT(bgezalc(a0, -1), "1884ffff bgezalc a0, -1", -1); - COMPARE_PC_REL_COMPACT(bgezalc(a0, 1), "18840001 bgezalc a0, 1", 1); + COMPARE_PC_REL_COMPACT(bgezalc(a0, 1), "18840001 bgezalc a0, 1", 1); COMPARE_PC_REL_COMPACT(bgezalc(a0, 32767), - "18847fff bgezalc a0, 32767", 32767); + "18847fff bgezalc a0, 32767", 32767); COMPARE_PC_REL_COMPACT(blezalc(a0, -32768), - "18048000 blezalc a0, -32768", -32768); - COMPARE_PC_REL_COMPACT(blezalc(a0, -1), "1804ffff blezalc a0, -1", + "18048000 blezalc a0, -32768", -32768); + COMPARE_PC_REL_COMPACT(blezalc(a0, -1), "1804ffff blezalc a0, -1", -1); - COMPARE_PC_REL_COMPACT(blezalc(a0, 1), "18040001 blezalc a0, 1", 1); + COMPARE_PC_REL_COMPACT(blezalc(a0, 1), "18040001 blezalc a0, 1", 1); COMPARE_PC_REL_COMPACT(blezalc(a0, 32767), - "18047fff blezalc a0, 32767", 32767); + "18047fff blezalc a0, 32767", 32767); COMPARE_PC_REL_COMPACT(bltuc(a0, a1, -32768), "1c858000 bltuc a0, a1, -32768", -32768); @@ -1024,13 +1042,13 @@ TEST(Type3) { "5c847fff bltzc a0, 32767", 32767); COMPARE_PC_REL_COMPACT(bltc(a0, a1, -32768), - "5c858000 bltc a0, a1, -32768", -32768); + "5c858000 bltc a0, a1, -32768", -32768); COMPARE_PC_REL_COMPACT(bltc(a0, a1, -1), - "5c85ffff bltc a0, a1, -1", -1); - COMPARE_PC_REL_COMPACT(bltc(a0, a1, 1), "5c850001 bltc a0, a1, 1", + "5c85ffff bltc a0, a1, -1", -1); + COMPARE_PC_REL_COMPACT(bltc(a0, a1, 1), "5c850001 bltc a0, a1, 1", 1); COMPARE_PC_REL_COMPACT(bltc(a0, a1, 32767), - "5c857fff bltc a0, a1, 32767", 32767); + "5c857fff bltc a0, a1, 32767", 32767); COMPARE_PC_REL_COMPACT(bgtzc(a0, -32768), "5c048000 bgtzc a0, -32768", -32768); @@ -1061,13 +1079,13 @@ TEST(Type3) { 1); COMPARE_PC_REL_COMPACT(beqc(a0, a1, -32768), - "20858000 beqc a0, a1, -32768", -32768); - COMPARE_PC_REL_COMPACT(beqc(a0, a1, -1), "2085ffff beqc a0, a1, -1", - -1); - COMPARE_PC_REL_COMPACT(beqc(a0, a1, 1), "20850001 beqc a0, a1, 1", + "20858000 beqc a0, a1, -32768", -32768); + COMPARE_PC_REL_COMPACT(beqc(a0, a1, -1), + "2085ffff beqc a0, a1, -1", -1); + COMPARE_PC_REL_COMPACT(beqc(a0, a1, 1), "20850001 beqc a0, a1, 1", 1); COMPARE_PC_REL_COMPACT(beqc(a0, a1, 32767), - "20857fff beqc a0, a1, 32767", 32767); + "20857fff beqc a0, a1, 32767", 32767); COMPARE_PC_REL_COMPACT(bnec(a0, a1, -32768), "60858000 bnec a0, a1, -32768", -32768); @@ -1239,3 +1257,13 @@ TEST(CVT_DISSASM) { VERIFY_RUN(); } + + +TEST(ctc1_cfc1_disasm) { + SET_UP(); + COMPARE(abs_d(f10, f31), "4620fa85 abs.d f10, f31"); + COMPARE(ceil_w_s(f8, f31), "4600fa0e ceil.w.s f8, f31"); + COMPARE(ctc1(a0, FCSR), "44c4f800 ctc1 a0, FCSR"); + COMPARE(cfc1(a0, FCSR), "4444f800 cfc1 a0, FCSR"); + VERIFY_RUN(); +} diff --git a/deps/v8/test/cctest/test-disasm-ppc.cc b/deps/v8/test/cctest/test-disasm-ppc.cc index ec02a251dd..9290c46c78 100644 --- a/deps/v8/test/cctest/test-disasm-ppc.cc +++ b/deps/v8/test/cctest/test-disasm-ppc.cc @@ -64,7 +64,7 @@ bool DisassembleAndCompare(byte* pc, const char* compare_string) { // in the rest of the macros. #define SET_UP() \ CcTest::InitializeVM(); \ - Isolate* isolate = Isolate::Current(); \ + Isolate* isolate = CcTest::i_isolate(); \ HandleScope scope(isolate); \ byte* buffer = reinterpret_cast<byte*>(malloc(4 * 1024)); \ Assembler assm(isolate, buffer, 4 * 1024); \ diff --git a/deps/v8/test/cctest/test-elements-kind.cc b/deps/v8/test/cctest/test-elements-kind.cc index f5630ab54e..ee1f09d0a0 100644 --- a/deps/v8/test/cctest/test-elements-kind.cc +++ b/deps/v8/test/cctest/test-elements-kind.cc @@ -311,7 +311,7 @@ TEST(JSArrayAddingElementsGeneralizingiFastSmiElements) { // `delete array[0]` does not alter length, but changes the elments_kind name = MakeString("0"); - JSReceiver::DeletePropertyOrElement(array, name).Check(); + CHECK(JSReceiver::DeletePropertyOrElement(array, name).FromMaybe(false)); CHECK_NE(array->map(), *previous_map); CHECK_EQ(array->map()->elements_kind(), FAST_HOLEY_SMI_ELEMENTS); CHECK_EQ(1, Smi::cast(array->length())->value()); @@ -384,7 +384,7 @@ TEST(JSArrayAddingElementsGeneralizingFastElements) { // `delete array[0]` does not alter length, but changes the elments_kind name = MakeString("0"); - JSReceiver::DeletePropertyOrElement(array, name).Check(); + CHECK(JSReceiver::DeletePropertyOrElement(array, name).FromMaybe(false)); CHECK_NE(array->map(), *previous_map); CHECK_EQ(array->map()->elements_kind(), FAST_HOLEY_ELEMENTS); CHECK_EQ(1, Smi::cast(array->length())->value()); @@ -441,7 +441,7 @@ TEST(JSArrayAddingElementsGeneralizingiFastDoubleElements) { // `delete array[0]` does not alter length, but changes the elments_kind name = MakeString("0"); - JSReceiver::DeletePropertyOrElement(array, name).Check(); + CHECK(JSReceiver::DeletePropertyOrElement(array, name).FromMaybe(false)); CHECK_NE(array->map(), *previous_map); CHECK_EQ(array->map()->elements_kind(), FAST_HOLEY_DOUBLE_ELEMENTS); CHECK_EQ(2, Smi::cast(array->length())->value()); diff --git a/deps/v8/test/cctest/test-feedback-vector.cc b/deps/v8/test/cctest/test-feedback-vector.cc index 26a7191d9e..c06e5b9124 100644 --- a/deps/v8/test/cctest/test-feedback-vector.cc +++ b/deps/v8/test/cctest/test-feedback-vector.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(mvstanton): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "test/cctest/cctest.h" @@ -47,8 +44,6 @@ TEST(VectorStructure) { CHECK(Handle<FixedArray>::cast(vector) .is_identical_to(factory->empty_fixed_array())); // Which can nonetheless be queried. - CHECK_EQ(0, vector->ic_with_type_info_count()); - CHECK_EQ(0, vector->ic_generic_count()); CHECK(vector->is_empty()); { @@ -135,8 +130,6 @@ TEST(VectorICMetadata) { // Meanwhile set some feedback values and type feedback values to // verify the data structure remains intact. - vector->change_ic_with_type_info_count(100); - vector->change_ic_generic_count(3333); vector->Set(FeedbackVectorSlot(0), *vector); // Verify the metadata is correctly set up from the spec. @@ -200,60 +193,6 @@ TEST(VectorSlotClearing) { } -TEST(VectorICProfilerStatistics) { - if (i::FLAG_always_opt) return; - CcTest::InitializeVM(); - LocalContext context; - v8::HandleScope scope(context->GetIsolate()); - Isolate* isolate = CcTest::i_isolate(); - Heap* heap = isolate->heap(); - - // Make sure function f has a call that uses a type feedback slot. - CompileRun( - "function fun() {};" - "function f(a) { a(); } f(fun);"); - Handle<JSFunction> f = GetFunction("f"); - // There should be one IC. - Handle<Code> code = handle(f->shared()->code(), isolate); - TypeFeedbackInfo* feedback_info = - TypeFeedbackInfo::cast(code->type_feedback_info()); - CHECK_EQ(1, feedback_info->ic_total_count()); - CHECK_EQ(0, feedback_info->ic_with_type_info_count()); - CHECK_EQ(0, feedback_info->ic_generic_count()); - Handle<TypeFeedbackVector> feedback_vector = - handle(f->shared()->feedback_vector(), isolate); - FeedbackVectorHelper helper(feedback_vector); - CallICNexus nexus(feedback_vector, helper.slot(0)); - CHECK_EQ(1, feedback_vector->ic_with_type_info_count()); - CHECK_EQ(0, feedback_vector->ic_generic_count()); - - // Now send the information generic. - CompileRun("f(Object);"); - CHECK_EQ(0, feedback_vector->ic_with_type_info_count()); - CHECK_EQ(1, feedback_vector->ic_generic_count()); - - // A collection will not affect the site. - heap->CollectAllGarbage(); - CHECK_EQ(0, feedback_vector->ic_with_type_info_count()); - CHECK_EQ(1, feedback_vector->ic_generic_count()); - - // The Array function is special. A call to array remains monomorphic - // and isn't cleared by gc because an AllocationSite is being held. - // Clear the IC manually in order to test this case. - nexus.Clear(*code); - CompileRun("f(Array);"); - CHECK_EQ(1, feedback_vector->ic_with_type_info_count()); - CHECK_EQ(0, feedback_vector->ic_generic_count()); - - - CHECK(nexus.GetFeedback()->IsAllocationSite()); - heap->CollectAllGarbage(); - CHECK_EQ(1, feedback_vector->ic_with_type_info_count()); - CHECK_EQ(0, feedback_vector->ic_generic_count()); - CHECK(nexus.GetFeedback()->IsAllocationSite()); -} - - TEST(VectorCallICStates) { if (i::FLAG_always_opt) return; CcTest::InitializeVM(); @@ -460,17 +399,11 @@ TEST(ReferenceContextAllocatesNoSlots) { Handle<TypeFeedbackVector> feedback_vector = handle(f->shared()->feedback_vector(), isolate); FeedbackVectorHelper helper(feedback_vector); - if (FLAG_vector_stores) { - CHECK_EQ(4, helper.slot_count()); - CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::STORE_IC); - CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); - CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); - CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::LOAD_IC); - } else { - CHECK_EQ(2, helper.slot_count()); - CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); - CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); - } + CHECK_EQ(4, helper.slot_count()); + CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::STORE_IC); + CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); + CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); + CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::LOAD_IC); } { @@ -485,11 +418,7 @@ TEST(ReferenceContextAllocatesNoSlots) { // There should be one LOAD_IC, for the load of a. Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); FeedbackVectorHelper helper(feedback_vector); - if (FLAG_vector_stores) { - CHECK_EQ(2, helper.slot_count()); - } else { - CHECK_EQ(1, helper.slot_count()); - } + CHECK_EQ(2, helper.slot_count()); } { @@ -506,20 +435,12 @@ TEST(ReferenceContextAllocatesNoSlots) { // There should be 2 LOAD_ICs and 2 CALL_ICs. Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); FeedbackVectorHelper helper(feedback_vector); - if (FLAG_vector_stores) { - CHECK_EQ(5, helper.slot_count()); - CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::CALL_IC); - CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); - CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); - CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::CALL_IC); - CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); - } else { - CHECK_EQ(4, helper.slot_count()); - CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::CALL_IC); - CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); - CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::CALL_IC); - CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::LOAD_IC); - } + CHECK_EQ(5, helper.slot_count()); + CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::CALL_IC); + CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); + CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); + CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::CALL_IC); + CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); } { @@ -536,16 +457,10 @@ TEST(ReferenceContextAllocatesNoSlots) { // the load of x[0] in the return statement. Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); FeedbackVectorHelper helper(feedback_vector); - if (FLAG_vector_stores) { - CHECK_EQ(3, helper.slot_count()); - CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); - CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::KEYED_STORE_IC); - CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::KEYED_LOAD_IC); - } else { - CHECK_EQ(2, helper.slot_count()); - CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); - CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::KEYED_LOAD_IC); - } + CHECK_EQ(3, helper.slot_count()); + CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); + CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::KEYED_STORE_IC); + CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::KEYED_LOAD_IC); } { @@ -561,27 +476,19 @@ TEST(ReferenceContextAllocatesNoSlots) { // There should be 3 LOAD_ICs, for load of a and load of x.old and x.young. Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); FeedbackVectorHelper helper(feedback_vector); - if (FLAG_vector_stores) { - CHECK_EQ(6, helper.slot_count()); - CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); - CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::STORE_IC); - CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); - CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::STORE_IC); - CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); - CHECK_SLOT_KIND(helper, 5, FeedbackVectorSlotKind::LOAD_IC); - } else { - CHECK_EQ(3, helper.slot_count()); - CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); - CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::LOAD_IC); - CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::LOAD_IC); - } + CHECK_EQ(6, helper.slot_count()); + CHECK_SLOT_KIND(helper, 0, FeedbackVectorSlotKind::LOAD_IC); + CHECK_SLOT_KIND(helper, 1, FeedbackVectorSlotKind::STORE_IC); + CHECK_SLOT_KIND(helper, 2, FeedbackVectorSlotKind::STORE_IC); + CHECK_SLOT_KIND(helper, 3, FeedbackVectorSlotKind::STORE_IC); + CHECK_SLOT_KIND(helper, 4, FeedbackVectorSlotKind::LOAD_IC); + CHECK_SLOT_KIND(helper, 5, FeedbackVectorSlotKind::LOAD_IC); } } TEST(VectorStoreICBasic) { if (i::FLAG_always_opt) return; - if (!i::FLAG_vector_stores) return; CcTest::InitializeVM(); LocalContext context; diff --git a/deps/v8/test/cctest/test-field-type-tracking.cc b/deps/v8/test/cctest/test-field-type-tracking.cc index fe1170d9b6..89456bd6ba 100644 --- a/deps/v8/test/cctest/test-field-type-tracking.cc +++ b/deps/v8/test/cctest/test-field-type-tracking.cc @@ -101,7 +101,7 @@ class Expectations { void Init(int index, PropertyType type, PropertyAttributes attributes, Representation representation, Handle<Object> value) { - DCHECK(index < MAX_PROPERTIES); + CHECK(index < MAX_PROPERTIES); types_[index] = type; attributes_[index] = attributes; representations_[index] = representation; @@ -621,6 +621,17 @@ static void TestGeneralizeRepresentation( CHECK_EQ(expected_field_type_dependency, info.dependencies()->HasAborted()); } + { + // Check that all previous maps are not stable. + Map* tmp = *new_map; + while (true) { + Object* back = tmp->GetBackPointer(); + if (back->IsUndefined()) break; + tmp = Map::cast(back); + CHECK(!tmp->is_stable()); + } + } + info.dependencies()->Rollback(); // Properly cleanup compilation info. // Update all deprecated maps and check that they are now the same. @@ -1380,9 +1391,10 @@ TEST(ReconfigureDataFieldAttribute_DataConstantToDataFieldAfterTargetMap) { void UpdateExpectations(int property_index, Expectations& expectations) { Isolate* isolate = CcTest::i_isolate(); - Handle<HeapType> any_type = HeapType::Any(isolate); + Handle<HeapType> function_type = + HeapType::Class(isolate->sloppy_function_map(), isolate); expectations.SetDataField(property_index, Representation::HeapObject(), - any_type); + function_type); } }; @@ -2136,7 +2148,8 @@ TEST(TransitionDataConstantToAnotherDataConstant) { v8::HandleScope scope(CcTest::isolate()); Isolate* isolate = CcTest::i_isolate(); Factory* factory = isolate->factory(); - Handle<HeapType> any_type = HeapType::Any(isolate); + Handle<HeapType> function_type = + HeapType::Class(isolate->sloppy_function_map(), isolate); Handle<JSFunction> js_func1 = factory->NewFunction(factory->empty_string()); TransitionToDataConstantOperator transition_op1(js_func1); @@ -2144,8 +2157,8 @@ TEST(TransitionDataConstantToAnotherDataConstant) { Handle<JSFunction> js_func2 = factory->NewFunction(factory->empty_string()); TransitionToDataConstantOperator transition_op2(js_func2); - FieldGeneralizationChecker checker(kPropCount - 1, - Representation::HeapObject(), any_type); + FieldGeneralizationChecker checker( + kPropCount - 1, Representation::HeapObject(), function_type); TestTransitionTo(transition_op1, transition_op2, checker); } diff --git a/deps/v8/test/cctest/test-func-name-inference.cc b/deps/v8/test/cctest/test-func-name-inference.cc index 6c7aa030bc..77ba2f2243 100644 --- a/deps/v8/test/cctest/test-func-name-inference.cc +++ b/deps/v8/test/cctest/test-func-name-inference.cc @@ -49,7 +49,7 @@ using ::v8::internal::String; using ::v8::internal::Vector; -static void CheckFunctionName(v8::Handle<v8::Script> script, +static void CheckFunctionName(v8::Local<v8::Script> script, const char* func_pos_src, const char* ref_inferred_name) { Isolate* isolate = CcTest::i_isolate(); @@ -93,8 +93,12 @@ static void CheckFunctionName(v8::Handle<v8::Script> script, } -static v8::Handle<v8::Script> Compile(v8::Isolate* isolate, const char* src) { - return v8::Script::Compile(v8::String::NewFromUtf8(isolate, src)); +static v8::Local<v8::Script> Compile(v8::Isolate* isolate, const char* src) { + return v8::Script::Compile( + isolate->GetCurrentContext(), + v8::String::NewFromUtf8(isolate, src, v8::NewStringType::kNormal) + .ToLocalChecked()) + .ToLocalChecked(); } @@ -102,10 +106,9 @@ TEST(GlobalProperty) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "fun1 = function() { return 1; }\n" - "fun2 = function() { return 2; }\n"); + v8::Local<v8::Script> script = Compile(CcTest::isolate(), + "fun1 = function() { return 1; }\n" + "fun2 = function() { return 2; }\n"); CheckFunctionName(script, "return 1", "fun1"); CheckFunctionName(script, "return 2", "fun2"); } @@ -115,10 +118,10 @@ TEST(GlobalVar) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "var fun1 = function() { return 1; }\n" - "var fun2 = function() { return 2; }\n"); + v8::Local<v8::Script> script = + Compile(CcTest::isolate(), + "var fun1 = function() { return 1; }\n" + "var fun2 = function() { return 2; }\n"); CheckFunctionName(script, "return 1", "fun1"); CheckFunctionName(script, "return 2", "fun2"); } @@ -128,12 +131,12 @@ TEST(LocalVar) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "function outer() {\n" - " var fun1 = function() { return 1; }\n" - " var fun2 = function() { return 2; }\n" - "}"); + v8::Local<v8::Script> script = + Compile(CcTest::isolate(), + "function outer() {\n" + " var fun1 = function() { return 1; }\n" + " var fun2 = function() { return 2; }\n" + "}"); CheckFunctionName(script, "return 1", "fun1"); CheckFunctionName(script, "return 2", "fun2"); } @@ -143,12 +146,12 @@ TEST(InConstructor) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "function MyClass() {\n" - " this.method1 = function() { return 1; }\n" - " this.method2 = function() { return 2; }\n" - "}"); + v8::Local<v8::Script> script = + Compile(CcTest::isolate(), + "function MyClass() {\n" + " this.method1 = function() { return 1; }\n" + " this.method2 = function() { return 2; }\n" + "}"); CheckFunctionName(script, "return 1", "MyClass.method1"); CheckFunctionName(script, "return 2", "MyClass.method2"); } @@ -158,14 +161,14 @@ TEST(Factory) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "function createMyObj() {\n" - " var obj = {};\n" - " obj.method1 = function() { return 1; }\n" - " obj.method2 = function() { return 2; }\n" - " return obj;\n" - "}"); + v8::Local<v8::Script> script = + Compile(CcTest::isolate(), + "function createMyObj() {\n" + " var obj = {};\n" + " obj.method1 = function() { return 1; }\n" + " obj.method2 = function() { return 2; }\n" + " return obj;\n" + "}"); CheckFunctionName(script, "return 1", "obj.method1"); CheckFunctionName(script, "return 2", "obj.method2"); } @@ -175,14 +178,14 @@ TEST(Static) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "function MyClass() {}\n" - "MyClass.static1 = function() { return 1; }\n" - "MyClass.static2 = function() { return 2; }\n" - "MyClass.MyInnerClass = {}\n" - "MyClass.MyInnerClass.static3 = function() { return 3; }\n" - "MyClass.MyInnerClass.static4 = function() { return 4; }"); + v8::Local<v8::Script> script = + Compile(CcTest::isolate(), + "function MyClass() {}\n" + "MyClass.static1 = function() { return 1; }\n" + "MyClass.static2 = function() { return 2; }\n" + "MyClass.MyInnerClass = {}\n" + "MyClass.MyInnerClass.static3 = function() { return 3; }\n" + "MyClass.MyInnerClass.static4 = function() { return 4; }"); CheckFunctionName(script, "return 1", "MyClass.static1"); CheckFunctionName(script, "return 2", "MyClass.static2"); CheckFunctionName(script, "return 3", "MyClass.MyInnerClass.static3"); @@ -194,7 +197,7 @@ TEST(Prototype) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( + v8::Local<v8::Script> script = Compile( CcTest::isolate(), "function MyClass() {}\n" "MyClass.prototype.method1 = function() { return 1; }\n" @@ -213,12 +216,12 @@ TEST(ObjectLiteral) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "function MyClass() {}\n" - "MyClass.prototype = {\n" - " method1: function() { return 1; },\n" - " method2: function() { return 2; } }"); + v8::Local<v8::Script> script = + Compile(CcTest::isolate(), + "function MyClass() {}\n" + "MyClass.prototype = {\n" + " method1: function() { return 1; },\n" + " method2: function() { return 2; } }"); CheckFunctionName(script, "return 1", "MyClass.method1"); CheckFunctionName(script, "return 2", "MyClass.method2"); } @@ -228,16 +231,16 @@ 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" - "}"); + v8::Local<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"); } @@ -247,16 +250,16 @@ 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" - "}"); + v8::Local<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"); } @@ -266,7 +269,7 @@ TEST(AsParameter) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( + v8::Local<v8::Script> script = Compile( CcTest::isolate(), "function f1(a) { return a(); }\n" "function f2(a, b) { return a() + b(); }\n" @@ -283,11 +286,10 @@ TEST(MultipleFuncsConditional) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "fun1 = 0 ?\n" - " function() { return 1; } :\n" - " function() { return 2; }"); + v8::Local<v8::Script> script = Compile(CcTest::isolate(), + "fun1 = 0 ?\n" + " function() { return 1; } :\n" + " function() { return 2; }"); CheckFunctionName(script, "return 1", "fun1"); CheckFunctionName(script, "return 2", "fun1"); } @@ -297,12 +299,12 @@ TEST(MultipleFuncsInLiteral) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "function MyClass() {}\n" - "MyClass.prototype = {\n" - " method1: 0 ? function() { return 1; } :\n" - " function() { return 2; } }"); + v8::Local<v8::Script> script = + Compile(CcTest::isolate(), + "function MyClass() {}\n" + "MyClass.prototype = {\n" + " method1: 0 ? function() { return 1; } :\n" + " function() { return 2; } }"); CheckFunctionName(script, "return 1", "MyClass.method1"); CheckFunctionName(script, "return 2", "MyClass.method1"); } @@ -312,18 +314,17 @@ TEST(AnonymousInAnonymousClosure1) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "(function() {\n" - " (function() {\n" - " var a = 1;\n" - " return;\n" - " })();\n" - " var b = function() {\n" - " var c = 1;\n" - " return;\n" - " };\n" - "})();"); + v8::Local<v8::Script> script = Compile(CcTest::isolate(), + "(function() {\n" + " (function() {\n" + " var a = 1;\n" + " return;\n" + " })();\n" + " var b = function() {\n" + " var c = 1;\n" + " return;\n" + " };\n" + "})();"); CheckFunctionName(script, "return", ""); } @@ -332,15 +333,14 @@ TEST(AnonymousInAnonymousClosure2) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "(function() {\n" - " (function() {\n" - " var a = 1;\n" - " return;\n" - " })();\n" - " var c = 1;\n" - "})();"); + v8::Local<v8::Script> script = Compile(CcTest::isolate(), + "(function() {\n" + " (function() {\n" + " var a = 1;\n" + " return;\n" + " })();\n" + " var c = 1;\n" + "})();"); CheckFunctionName(script, "return", ""); } @@ -349,15 +349,14 @@ TEST(NamedInAnonymousClosure) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "var foo = function() {\n" - " (function named() {\n" - " var a = 1;\n" - " })();\n" - " var c = 1;\n" - " return;\n" - "};"); + v8::Local<v8::Script> script = Compile(CcTest::isolate(), + "var foo = function() {\n" + " (function named() {\n" + " var a = 1;\n" + " })();\n" + " var c = 1;\n" + " return;\n" + "};"); CheckFunctionName(script, "return", "foo"); } @@ -367,12 +366,12 @@ TEST(Issue380) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "function a() {\n" - "var result = function(p,a,c,k,e,d)" - "{return p}(\"if blah blah\",62,1976,\'a|b\'.split(\'|\'),0,{})\n" - "}"); + v8::Local<v8::Script> script = + Compile(CcTest::isolate(), + "function a() {\n" + "var result = function(p,a,c,k,e,d)" + "{return p}(\"if blah blah\",62,1976,\'a|b\'.split(\'|\'),0,{})\n" + "}"); CheckFunctionName(script, "return p", ""); } @@ -381,12 +380,12 @@ TEST(MultipleAssignments) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "var fun1 = fun2 = function () { return 1; }\n" - "var bar1 = bar2 = bar3 = function () { return 2; }\n" - "foo1 = foo2 = function () { return 3; }\n" - "baz1 = baz2 = baz3 = function () { return 4; }"); + v8::Local<v8::Script> script = + Compile(CcTest::isolate(), + "var fun1 = fun2 = function () { return 1; }\n" + "var bar1 = bar2 = bar3 = function () { return 2; }\n" + "foo1 = foo2 = function () { return 3; }\n" + "baz1 = baz2 = baz3 = function () { return 4; }"); CheckFunctionName(script, "return 1", "fun2"); CheckFunctionName(script, "return 2", "bar3"); CheckFunctionName(script, "return 3", "foo2"); @@ -398,7 +397,7 @@ TEST(AsConstructorParameter) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( + v8::Local<v8::Script> script = Compile( CcTest::isolate(), "function Foo() {}\n" "var foo = new Foo(function() { return 1; })\n" @@ -413,14 +412,14 @@ TEST(FactoryHashmap) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "function createMyObj() {\n" - " var obj = {};\n" - " obj[\"method1\"] = function() { return 1; }\n" - " obj[\"method2\"] = function() { return 2; }\n" - " return obj;\n" - "}"); + v8::Local<v8::Script> script = + Compile(CcTest::isolate(), + "function createMyObj() {\n" + " var obj = {};\n" + " obj[\"method1\"] = function() { return 1; }\n" + " obj[\"method2\"] = function() { return 2; }\n" + " return obj;\n" + "}"); CheckFunctionName(script, "return 1", "obj.method1"); CheckFunctionName(script, "return 2", "obj.method2"); } @@ -430,16 +429,16 @@ TEST(FactoryHashmapVariable) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "function createMyObj() {\n" - " var obj = {};\n" - " var methodName = \"method1\";\n" - " obj[methodName] = function() { return 1; }\n" - " methodName = \"method2\";\n" - " obj[methodName] = function() { return 2; }\n" - " return obj;\n" - "}"); + v8::Local<v8::Script> script = + Compile(CcTest::isolate(), + "function createMyObj() {\n" + " var obj = {};\n" + " var methodName = \"method1\";\n" + " obj[methodName] = function() { return 1; }\n" + " methodName = \"method2\";\n" + " obj[methodName] = function() { return 2; }\n" + " return obj;\n" + "}"); // Can't infer function names statically. CheckFunctionName(script, "return 1", "obj.(anonymous function)"); CheckFunctionName(script, "return 2", "obj.(anonymous function)"); @@ -450,7 +449,7 @@ TEST(FactoryHashmapConditional) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( + v8::Local<v8::Script> script = Compile( CcTest::isolate(), "function createMyObj() {\n" " var obj = {};\n" @@ -466,14 +465,13 @@ TEST(GlobalAssignmentAndCall) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "var Foo = function() {\n" - " return 1;\n" - "}();\n" - "var Baz = Bar = function() {\n" - " return 2;\n" - "}"); + v8::Local<v8::Script> script = Compile(CcTest::isolate(), + "var Foo = function() {\n" + " return 1;\n" + "}();\n" + "var Baz = Bar = function() {\n" + " return 2;\n" + "}"); // The inferred name is empty, because this is an assignment of a result. CheckFunctionName(script, "return 1", ""); // See MultipleAssignments test. @@ -485,17 +483,16 @@ TEST(AssignmentAndCall) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "(function Enclosing() {\n" - " var Foo;\n" - " Foo = function() {\n" - " return 1;\n" - " }();\n" - " var Baz = Bar = function() {\n" - " return 2;\n" - " }\n" - "})();"); + v8::Local<v8::Script> script = Compile(CcTest::isolate(), + "(function Enclosing() {\n" + " var Foo;\n" + " Foo = function() {\n" + " return 1;\n" + " }();\n" + " var Baz = Bar = function() {\n" + " return 2;\n" + " }\n" + "})();"); // The inferred name is empty, because this is an assignment of a result. CheckFunctionName(script, "return 1", ""); // See MultipleAssignments test. @@ -509,15 +506,15 @@ TEST(MethodAssignmentInAnonymousFunctionCall) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "(function () {\n" - " var EventSource = function () { };\n" - " EventSource.prototype.addListener = function () {\n" - " return 2012;\n" - " };\n" - " this.PublicEventSource = EventSource;\n" - "})();"); + v8::Local<v8::Script> script = + Compile(CcTest::isolate(), + "(function () {\n" + " var EventSource = function () { };\n" + " EventSource.prototype.addListener = function () {\n" + " return 2012;\n" + " };\n" + " this.PublicEventSource = EventSource;\n" + "})();"); CheckFunctionName(script, "return 2012", "EventSource.addListener"); } @@ -526,20 +523,19 @@ TEST(ReturnAnonymousFunction) { CcTest::InitializeVM(); v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Script> script = Compile( - CcTest::isolate(), - "(function() {\n" - " function wrapCode() {\n" - " return function () {\n" - " return 2012;\n" - " };\n" - " };\n" - " var foo = 10;\n" - " function f() {\n" - " return wrapCode();\n" - " }\n" - " this.ref = f;\n" - "})()"); - script->Run(); + v8::Local<v8::Script> script = Compile(CcTest::isolate(), + "(function() {\n" + " function wrapCode() {\n" + " return function () {\n" + " return 2012;\n" + " };\n" + " };\n" + " var foo = 10;\n" + " function f() {\n" + " return wrapCode();\n" + " }\n" + " this.ref = f;\n" + "})()"); + script->Run(CcTest::isolate()->GetCurrentContext()).ToLocalChecked(); CheckFunctionName(script, "return 2012", ""); } diff --git a/deps/v8/test/cctest/test-global-handles.cc b/deps/v8/test/cctest/test-global-handles.cc index cc95df21cf..22fd785566 100644 --- a/deps/v8/test/cctest/test-global-handles.cc +++ b/deps/v8/test/cctest/test-global-handles.cc @@ -56,7 +56,7 @@ class TestRetainedObjectInfo : public v8::RetainedObjectInfo { bool has_been_disposed() { return has_been_disposed_; } virtual void Dispose() { - DCHECK(!has_been_disposed_); + CHECK(!has_been_disposed_); has_been_disposed_ = true; } @@ -121,16 +121,16 @@ TEST(IterateObjectGroupsOldApi) { global_handles->IterateObjectGroups(&visitor, &CanSkipCallback); // CanSkipCallback was called for all objects. - DCHECK(can_skip_called_objects.length() == 4); - DCHECK(can_skip_called_objects.Contains(*g1s1.location())); - DCHECK(can_skip_called_objects.Contains(*g1s2.location())); - DCHECK(can_skip_called_objects.Contains(*g2s1.location())); - DCHECK(can_skip_called_objects.Contains(*g2s2.location())); + CHECK(can_skip_called_objects.length() == 4); + CHECK(can_skip_called_objects.Contains(*g1s1.location())); + CHECK(can_skip_called_objects.Contains(*g1s2.location())); + CHECK(can_skip_called_objects.Contains(*g2s1.location())); + CHECK(can_skip_called_objects.Contains(*g2s2.location())); // Nothing was visited. - DCHECK(visitor.visited.length() == 0); - DCHECK(!info1.has_been_disposed()); - DCHECK(!info2.has_been_disposed()); + CHECK(visitor.visited.length() == 0); + CHECK(!info1.has_been_disposed()); + CHECK(!info2.has_been_disposed()); } // Iterate again, now only skip the second object group. @@ -145,18 +145,18 @@ TEST(IterateObjectGroupsOldApi) { global_handles->IterateObjectGroups(&visitor, &CanSkipCallback); // CanSkipCallback was called for all objects. - DCHECK(can_skip_called_objects.length() == 3 || - can_skip_called_objects.length() == 4); - DCHECK(can_skip_called_objects.Contains(*g1s2.location())); - DCHECK(can_skip_called_objects.Contains(*g2s1.location())); - DCHECK(can_skip_called_objects.Contains(*g2s2.location())); + CHECK(can_skip_called_objects.length() == 3 || + can_skip_called_objects.length() == 4); + CHECK(can_skip_called_objects.Contains(*g1s2.location())); + CHECK(can_skip_called_objects.Contains(*g2s1.location())); + CHECK(can_skip_called_objects.Contains(*g2s2.location())); // The first group was visited. - DCHECK(visitor.visited.length() == 2); - DCHECK(visitor.visited.Contains(*g1s1.location())); - DCHECK(visitor.visited.Contains(*g1s2.location())); - DCHECK(info1.has_been_disposed()); - DCHECK(!info2.has_been_disposed()); + CHECK(visitor.visited.length() == 2); + CHECK(visitor.visited.Contains(*g1s1.location())); + CHECK(visitor.visited.Contains(*g1s2.location())); + CHECK(info1.has_been_disposed()); + CHECK(!info2.has_been_disposed()); } // Iterate again, don't skip anything. @@ -166,15 +166,15 @@ TEST(IterateObjectGroupsOldApi) { global_handles->IterateObjectGroups(&visitor, &CanSkipCallback); // CanSkipCallback was called for all objects. - DCHECK(can_skip_called_objects.length() == 1); - DCHECK(can_skip_called_objects.Contains(*g2s1.location()) || - can_skip_called_objects.Contains(*g2s2.location())); + CHECK(can_skip_called_objects.length() == 1); + CHECK(can_skip_called_objects.Contains(*g2s1.location()) || + can_skip_called_objects.Contains(*g2s2.location())); // The second group was visited. - DCHECK(visitor.visited.length() == 2); - DCHECK(visitor.visited.Contains(*g2s1.location())); - DCHECK(visitor.visited.Contains(*g2s2.location())); - DCHECK(info2.has_been_disposed()); + CHECK(visitor.visited.length() == 2); + CHECK(visitor.visited.Contains(*g2s1.location())); + CHECK(visitor.visited.Contains(*g2s2.location())); + CHECK(info2.has_been_disposed()); } } @@ -216,16 +216,16 @@ TEST(IterateObjectGroups) { global_handles->IterateObjectGroups(&visitor, &CanSkipCallback); // CanSkipCallback was called for all objects. - DCHECK(can_skip_called_objects.length() == 4); - DCHECK(can_skip_called_objects.Contains(*g1s1.location())); - DCHECK(can_skip_called_objects.Contains(*g1s2.location())); - DCHECK(can_skip_called_objects.Contains(*g2s1.location())); - DCHECK(can_skip_called_objects.Contains(*g2s2.location())); + CHECK(can_skip_called_objects.length() == 4); + CHECK(can_skip_called_objects.Contains(*g1s1.location())); + CHECK(can_skip_called_objects.Contains(*g1s2.location())); + CHECK(can_skip_called_objects.Contains(*g2s1.location())); + CHECK(can_skip_called_objects.Contains(*g2s2.location())); // Nothing was visited. - DCHECK(visitor.visited.length() == 0); - DCHECK(!info1.has_been_disposed()); - DCHECK(!info2.has_been_disposed()); + CHECK(visitor.visited.length() == 0); + CHECK(!info1.has_been_disposed()); + CHECK(!info2.has_been_disposed()); } // Iterate again, now only skip the second object group. @@ -240,18 +240,18 @@ TEST(IterateObjectGroups) { global_handles->IterateObjectGroups(&visitor, &CanSkipCallback); // CanSkipCallback was called for all objects. - DCHECK(can_skip_called_objects.length() == 3 || - can_skip_called_objects.length() == 4); - DCHECK(can_skip_called_objects.Contains(*g1s2.location())); - DCHECK(can_skip_called_objects.Contains(*g2s1.location())); - DCHECK(can_skip_called_objects.Contains(*g2s2.location())); + CHECK(can_skip_called_objects.length() == 3 || + can_skip_called_objects.length() == 4); + CHECK(can_skip_called_objects.Contains(*g1s2.location())); + CHECK(can_skip_called_objects.Contains(*g2s1.location())); + CHECK(can_skip_called_objects.Contains(*g2s2.location())); // The first group was visited. - DCHECK(visitor.visited.length() == 2); - DCHECK(visitor.visited.Contains(*g1s1.location())); - DCHECK(visitor.visited.Contains(*g1s2.location())); - DCHECK(info1.has_been_disposed()); - DCHECK(!info2.has_been_disposed()); + CHECK(visitor.visited.length() == 2); + CHECK(visitor.visited.Contains(*g1s1.location())); + CHECK(visitor.visited.Contains(*g1s2.location())); + CHECK(info1.has_been_disposed()); + CHECK(!info2.has_been_disposed()); } // Iterate again, don't skip anything. @@ -261,15 +261,15 @@ TEST(IterateObjectGroups) { global_handles->IterateObjectGroups(&visitor, &CanSkipCallback); // CanSkipCallback was called for all objects. - DCHECK(can_skip_called_objects.length() == 1); - DCHECK(can_skip_called_objects.Contains(*g2s1.location()) || - can_skip_called_objects.Contains(*g2s2.location())); + CHECK(can_skip_called_objects.length() == 1); + CHECK(can_skip_called_objects.Contains(*g2s1.location()) || + can_skip_called_objects.Contains(*g2s2.location())); // The second group was visited. - DCHECK(visitor.visited.length() == 2); - DCHECK(visitor.visited.Contains(*g2s1.location())); - DCHECK(visitor.visited.Contains(*g2s2.location())); - DCHECK(info2.has_been_disposed()); + CHECK(visitor.visited.length() == 2); + CHECK(visitor.visited.Contains(*g2s1.location())); + CHECK(visitor.visited.Contains(*g2s2.location())); + CHECK(info2.has_been_disposed()); } } @@ -306,16 +306,16 @@ TEST(ImplicitReferences) { List<ImplicitRefGroup*>* implicit_refs = global_handles->implicit_ref_groups(); USE(implicit_refs); - DCHECK(implicit_refs->length() == 2); - DCHECK(implicit_refs->at(0)->parent == - reinterpret_cast<HeapObject**>(g1s1.location())); - DCHECK(implicit_refs->at(0)->length == 2); - DCHECK(implicit_refs->at(0)->children[0] == g1c1.location()); - DCHECK(implicit_refs->at(0)->children[1] == g1c2.location()); - DCHECK(implicit_refs->at(1)->parent == - reinterpret_cast<HeapObject**>(g2s1.location())); - DCHECK(implicit_refs->at(1)->length == 1); - DCHECK(implicit_refs->at(1)->children[0] == g2c1.location()); + CHECK(implicit_refs->length() == 2); + CHECK(implicit_refs->at(0)->parent == + reinterpret_cast<HeapObject**>(g1s1.location())); + CHECK(implicit_refs->at(0)->length == 2); + CHECK(implicit_refs->at(0)->children[0] == g1c1.location()); + CHECK(implicit_refs->at(0)->children[1] == g1c2.location()); + CHECK(implicit_refs->at(1)->parent == + reinterpret_cast<HeapObject**>(g2s1.location())); + CHECK(implicit_refs->at(1)->length == 1); + CHECK(implicit_refs->at(1)->children[0] == g2c1.location()); global_handles->RemoveObjectGroups(); global_handles->RemoveImplicitRefGroups(); } @@ -337,7 +337,9 @@ TEST(EternalHandles) { indices[i] = -1; HandleScope scope(isolate); v8::Local<v8::Object> object = v8::Object::New(v8_isolate); - object->Set(i, v8::Integer::New(v8_isolate, i)); + object->Set(v8_isolate->GetCurrentContext(), i, + v8::Integer::New(v8_isolate, i)) + .FromJust(); // Create with internal api eternal_handles->Create( isolate, *v8::Utils::OpenHandle(*object), &indices[i]); @@ -360,10 +362,12 @@ TEST(EternalHandles) { // Test external api local = eternals[i].Get(v8_isolate); } - v8::Local<v8::Object> object = v8::Handle<v8::Object>::Cast(local); - v8::Local<v8::Value> value = object->Get(i); + v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(local); + v8::Local<v8::Value> value = + object->Get(v8_isolate->GetCurrentContext(), i).ToLocalChecked(); CHECK(value->IsInt32()); - CHECK_EQ(i, value->Int32Value()); + CHECK_EQ(i, + value->Int32Value(v8_isolate->GetCurrentContext()).FromJust()); } } @@ -397,3 +401,19 @@ TEST(PersistentBaseGetLocal) { CHECK(o == g.Get(isolate)); CHECK(v8::Local<v8::Object>::New(isolate, g) == g.Get(isolate)); } + + +void WeakCallback(const v8::WeakCallbackInfo<void>& data) {} + + +TEST(WeakPersistentSmi) { + CcTest::InitializeVM(); + v8::Isolate* isolate = CcTest::isolate(); + + v8::HandleScope scope(isolate); + v8::Local<v8::Number> n = v8::Number::New(isolate, 0); + v8::Global<v8::Number> g(isolate, n); + + // Should not crash. + g.SetWeak<void>(nullptr, &WeakCallback, v8::WeakCallbackType::kParameter); +} diff --git a/deps/v8/test/cctest/test-global-object.cc b/deps/v8/test/cctest/test-global-object.cc index c696086061..d6713208bf 100644 --- a/deps/v8/test/cctest/test-global-object.cc +++ b/deps/v8/test/cctest/test-global-object.cc @@ -42,12 +42,12 @@ TEST(StrictUndeclaredGlobalVariable) { LocalContext context; v8::TryCatch try_catch(CcTest::isolate()); v8::Local<v8::Script> script = v8_compile("\"use strict\"; x = 42;"); - v8::Handle<v8::Object> proto = v8::Object::New(CcTest::isolate()); - v8::Handle<v8::Object> global = + v8::Local<v8::Object> proto = v8::Object::New(CcTest::isolate()); + v8::Local<v8::Object> global = context->Global()->GetPrototype().As<v8::Object>(); - proto->Set(var_name, v8_num(100)); - global->SetPrototype(proto); - script->Run(); + proto->Set(context.local(), var_name, v8_num(100)).FromJust(); + global->SetPrototype(context.local(), proto).FromJust(); + CHECK(script->Run(context.local()).IsEmpty()); CHECK(try_catch.HasCaught()); v8::String::Utf8Value exception(try_catch.Exception()); CHECK_EQ(0, strcmp("ReferenceError: x is not defined", *exception)); @@ -59,7 +59,7 @@ TEST(KeysGlobalObject_Regress2764) { v8::HandleScope scope(env1->GetIsolate()); // Create second environment. - v8::Handle<Context> env2 = Context::New(env1->GetIsolate()); + v8::Local<Context> env2 = Context::New(env1->GetIsolate()); Local<Value> token = v8_str("foo"); @@ -68,17 +68,25 @@ TEST(KeysGlobalObject_Regress2764) { env2->SetSecurityToken(token); // Create a reference to env2 global from env1 global. - env1->Global()->Set(v8_str("global2"), env2->Global()); + env1->Global() + ->Set(env1.local(), v8_str("global2"), env2->Global()) + .FromJust(); // Set some global variables in global2 - env2->Global()->Set(v8_str("a"), v8_str("a")); - env2->Global()->Set(v8_str("42"), v8_str("42")); + env2->Global()->Set(env2, v8_str("a"), v8_str("a")).FromJust(); + env2->Global()->Set(env2, v8_str("42"), v8_str("42")).FromJust(); // List all entries from global2. Local<Array> result; result = Local<Array>::Cast(CompileRun("Object.keys(global2)")); CHECK_EQ(2u, result->Length()); - CHECK(v8_str("42")->Equals(result->Get(0))); - CHECK(v8_str("a")->Equals(result->Get(1))); + CHECK( + v8_str("42") + ->Equals(env1.local(), result->Get(env1.local(), 0).ToLocalChecked()) + .FromJust()); + CHECK( + v8_str("a") + ->Equals(env1.local(), result->Get(env1.local(), 1).ToLocalChecked()) + .FromJust()); result = Local<Array>::Cast(CompileRun("Object.getOwnPropertyNames(global2)")); diff --git a/deps/v8/test/cctest/test-hashing.cc b/deps/v8/test/cctest/test-hashing.cc index 9e5de2e05a..25a8e5c527 100644 --- a/deps/v8/test/cctest/test-hashing.cc +++ b/deps/v8/test/cctest/test-hashing.cc @@ -110,7 +110,8 @@ void check(uint32_t key) { HandleScope scope(isolate); v8::internal::byte buffer[2048]; - MacroAssembler masm(CcTest::i_isolate(), buffer, sizeof buffer); + MacroAssembler masm(CcTest::i_isolate(), buffer, sizeof(buffer), + v8::internal::CodeObjectRequired::kYes); generate(&masm, key); @@ -124,8 +125,8 @@ void check(uint32_t key) { HASH_FUNCTION hash = FUNCTION_CAST<HASH_FUNCTION>(code->entry()); #ifdef USE_SIMULATOR - uint32_t codegen_hash = static_cast<uint32_t>( - reinterpret_cast<uintptr_t>(CALL_GENERATED_CODE(hash, 0, 0, 0, 0, 0))); + uint32_t codegen_hash = static_cast<uint32_t>(reinterpret_cast<uintptr_t>( + CALL_GENERATED_CODE(isolate, hash, 0, 0, 0, 0, 0))); #else uint32_t codegen_hash = hash(); #endif diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc index 9bdd3b81e6..a2fd09e9f5 100644 --- a/deps/v8/test/cctest/test-heap-profiler.cc +++ b/deps/v8/test/cctest/test-heap-profiler.cc @@ -96,11 +96,10 @@ class NamedEntriesDetector { static const v8::HeapGraphNode* GetGlobalObject( const v8::HeapSnapshot* snapshot) { - CHECK_EQ(3, snapshot->GetRoot()->GetChildrenCount()); - // The 0th-child is (GC Roots), 1st is code stubs context, 2nd is the user - // root. + CHECK_EQ(2, snapshot->GetRoot()->GetChildrenCount()); + // The 0th-child is (GC Roots), 1st is the user root. const v8::HeapGraphNode* global_obj = - snapshot->GetRoot()->GetChild(2)->GetToNode(); + snapshot->GetRoot()->GetChild(1)->GetToNode(); CHECK_EQ(0, strncmp("Object", const_cast<i::HeapEntry*>( reinterpret_cast<const i::HeapEntry*>(global_obj))->name(), 6)); return global_obj; @@ -247,13 +246,12 @@ TEST(BoundFunctionInSnapshot) { const v8::HeapGraphNode* f = GetProperty(global, v8::HeapGraphEdge::kProperty, "boundFunction"); CHECK(f); - CHECK(v8::String::NewFromUtf8(env->GetIsolate(), "native_bind") - ->Equals(f->GetName())); + CHECK(v8_str("native_bind")->Equals(env.local(), f->GetName()).FromJust()); const v8::HeapGraphNode* bindings = GetProperty(f, v8::HeapGraphEdge::kInternal, "bindings"); CHECK(bindings); CHECK_EQ(v8::HeapGraphNode::kArray, bindings->GetType()); - CHECK_EQ(3, bindings->GetChildrenCount()); + CHECK_EQ(1, bindings->GetChildrenCount()); const v8::HeapGraphNode* bound_this = GetProperty( f, v8::HeapGraphEdge::kShortcut, "bound_this"); @@ -428,8 +426,8 @@ TEST(HeapSnapshotConsString) { v8::ObjectTemplate::New(isolate); global_template->SetInternalFieldCount(1); LocalContext env(NULL, global_template); - v8::Handle<v8::Object> global_proxy = env->Global(); - v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); + v8::Local<v8::Object> global_proxy = env->Global(); + v8::Local<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); CHECK_EQ(1, global->InternalFieldCount()); i::Factory* factory = CcTest::i_isolate()->factory(); @@ -475,11 +473,11 @@ TEST(HeapSnapshotSymbol) { GetProperty(global, v8::HeapGraphEdge::kProperty, "a"); CHECK(a); CHECK_EQ(a->GetType(), v8::HeapGraphNode::kSymbol); - CHECK(v8_str("symbol")->Equals(a->GetName())); + CHECK(v8_str("symbol")->Equals(env.local(), a->GetName()).FromJust()); const v8::HeapGraphNode* name = GetProperty(a, v8::HeapGraphEdge::kInternal, "name"); CHECK(name); - CHECK(v8_str("mySymbol")->Equals(name->GetName())); + CHECK(v8_str("mySymbol")->Equals(env.local(), name->GetName()).FromJust()); } @@ -540,7 +538,7 @@ TEST(HeapSnapshotWeakCollection) { GetProperty(global, v8::HeapGraphEdge::kProperty, "ws"); CHECK(ws); CHECK_EQ(v8::HeapGraphNode::kObject, ws->GetType()); - CHECK(v8_str("WeakSet")->Equals(ws->GetName())); + CHECK(v8_str("WeakSet")->Equals(env.local(), ws->GetName()).FromJust()); const v8::HeapGraphNode* ws_table = GetProperty(ws, v8::HeapGraphEdge::kInternal, "table"); @@ -564,7 +562,7 @@ TEST(HeapSnapshotWeakCollection) { GetProperty(global, v8::HeapGraphEdge::kProperty, "wm"); CHECK(wm); CHECK_EQ(v8::HeapGraphNode::kObject, wm->GetType()); - CHECK(v8_str("WeakMap")->Equals(wm->GetName())); + CHECK(v8_str("WeakMap")->Equals(env.local(), wm->GetName()).FromJust()); const v8::HeapGraphNode* wm_table = GetProperty(wm, v8::HeapGraphEdge::kInternal, "table"); @@ -613,7 +611,7 @@ TEST(HeapSnapshotCollection) { GetProperty(global, v8::HeapGraphEdge::kProperty, "set"); CHECK(set); CHECK_EQ(v8::HeapGraphNode::kObject, set->GetType()); - CHECK(v8_str("Set")->Equals(set->GetName())); + CHECK(v8_str("Set")->Equals(env.local(), set->GetName()).FromJust()); const v8::HeapGraphNode* set_table = GetProperty(set, v8::HeapGraphEdge::kInternal, "table"); @@ -637,7 +635,7 @@ TEST(HeapSnapshotCollection) { GetProperty(global, v8::HeapGraphEdge::kProperty, "map"); CHECK(map); CHECK_EQ(v8::HeapGraphNode::kObject, map->GetType()); - CHECK(v8_str("Map")->Equals(map->GetName())); + CHECK(v8_str("Map")->Equals(env.local(), map->GetName()).FromJust()); const v8::HeapGraphNode* map_table = GetProperty(map, v8::HeapGraphEdge::kInternal, "table"); @@ -666,8 +664,8 @@ TEST(HeapSnapshotInternalReferences) { v8::ObjectTemplate::New(isolate); global_template->SetInternalFieldCount(2); LocalContext env(NULL, global_template); - v8::Handle<v8::Object> global_proxy = env->Global(); - v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); + v8::Local<v8::Object> global_proxy = env->Global(); + v8::Local<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); CHECK_EQ(2, global->InternalFieldCount()); v8::Local<v8::Object> obj = v8::Object::New(isolate); global->SetInternalField(0, v8_num(17)); @@ -863,7 +861,7 @@ class TestJSONStream : public v8::OutputStream { return kContinue; } virtual WriteResult WriteUint32Chunk(uint32_t* buffer, int chars_written) { - DCHECK(false); + CHECK(false); return kAbort; } void WriteTo(i::Vector<char> dest) { buffer_.WriteTo(dest); } @@ -916,19 +914,26 @@ TEST(HeapSnapshotJSONSerialization) { // Verify that snapshot string is valid JSON. OneByteResource* json_res = new OneByteResource(json); v8::Local<v8::String> json_string = - v8::String::NewExternal(env->GetIsolate(), json_res); - env->Global()->Set(v8_str("json_snapshot"), json_string); + v8::String::NewExternalOneByte(env->GetIsolate(), json_res) + .ToLocalChecked(); + env->Global() + ->Set(env.local(), v8_str("json_snapshot"), json_string) + .FromJust(); v8::Local<v8::Value> snapshot_parse_result = CompileRun( "var parsed = JSON.parse(json_snapshot); true;"); CHECK(!snapshot_parse_result.IsEmpty()); // Verify that snapshot object has required fields. v8::Local<v8::Object> parsed_snapshot = - env->Global()->Get(v8_str("parsed"))->ToObject(isolate); - CHECK(parsed_snapshot->Has(v8_str("snapshot"))); - CHECK(parsed_snapshot->Has(v8_str("nodes"))); - CHECK(parsed_snapshot->Has(v8_str("edges"))); - CHECK(parsed_snapshot->Has(v8_str("strings"))); + env->Global() + ->Get(env.local(), v8_str("parsed")) + .ToLocalChecked() + ->ToObject(env.local()) + .ToLocalChecked(); + CHECK(parsed_snapshot->Has(env.local(), v8_str("snapshot")).FromJust()); + CHECK(parsed_snapshot->Has(env.local(), v8_str("nodes")).FromJust()); + CHECK(parsed_snapshot->Has(env.local(), v8_str("edges")).FromJust()); + CHECK(parsed_snapshot->Has(env.local(), v8_str("strings")).FromJust()); // Get node and edge "member" offsets. v8::Local<v8::Value> meta_analysis_result = CompileRun( @@ -979,21 +984,34 @@ TEST(HeapSnapshotJSONSerialization) { " \"x\", property_type)," " \"s\", property_type)"); CHECK(!string_obj_pos_val.IsEmpty()); - int string_obj_pos = - static_cast<int>(string_obj_pos_val->ToNumber(isolate)->Value()); + int string_obj_pos = static_cast<int>( + string_obj_pos_val->ToNumber(env.local()).ToLocalChecked()->Value()); v8::Local<v8::Object> nodes_array = - parsed_snapshot->Get(v8_str("nodes"))->ToObject(isolate); - int string_index = static_cast<int>( - nodes_array->Get(string_obj_pos + 1)->ToNumber(isolate)->Value()); + parsed_snapshot->Get(env.local(), v8_str("nodes")) + .ToLocalChecked() + ->ToObject(env.local()) + .ToLocalChecked(); + int string_index = + static_cast<int>(nodes_array->Get(env.local(), string_obj_pos + 1) + .ToLocalChecked() + ->ToNumber(env.local()) + .ToLocalChecked() + ->Value()); CHECK_GT(string_index, 0); v8::Local<v8::Object> strings_array = - parsed_snapshot->Get(v8_str("strings"))->ToObject(isolate); - v8::Local<v8::String> string = - strings_array->Get(string_index)->ToString(isolate); - v8::Local<v8::String> ref_string = - CompileRun(STRING_LITERAL_FOR_TEST)->ToString(isolate); + parsed_snapshot->Get(env.local(), v8_str("strings")) + .ToLocalChecked() + ->ToObject(env.local()) + .ToLocalChecked(); + v8::Local<v8::String> string = strings_array->Get(env.local(), string_index) + .ToLocalChecked() + ->ToString(env.local()) + .ToLocalChecked(); + v8::Local<v8::String> ref_string = CompileRun(STRING_LITERAL_FOR_TEST) + ->ToString(env.local()) + .ToLocalChecked(); #undef STRING_LITERAL_FOR_TEST - CHECK_LT(0, strcmp(*v8::String::Utf8Value(ref_string), + CHECK_EQ(0, strcmp(*v8::String::Utf8Value(ref_string), *v8::String::Utf8Value(string))); } @@ -1032,13 +1050,13 @@ class TestStatsStream : public v8::OutputStream { virtual ~TestStatsStream() {} virtual void EndOfStream() { ++eos_signaled_; } virtual WriteResult WriteAsciiChunk(char* buffer, int chars_written) { - DCHECK(false); + CHECK(false); return kAbort; } virtual WriteResult WriteHeapStatsChunk(v8::HeapStatsUpdate* buffer, int updates_written) { ++intervals_count_; - DCHECK(updates_written); + CHECK(updates_written); updates_written_ += updates_written; entries_count_ = 0; if (first_interval_index_ == -1 && updates_written != 0) @@ -1190,7 +1208,7 @@ TEST(HeapSnapshotObjectsStats) { v8::Local<v8::Array> array = v8::Array::New(env->GetIsolate()); CHECK_EQ(0u, array->Length()); // Force array's buffer allocation. - array->Set(2, v8_num(7)); + array->Set(env.local(), 2, v8_num(7)).FromJust(); uint32_t entries_size; { @@ -1205,7 +1223,7 @@ TEST(HeapSnapshotObjectsStats) { } for (int i = 0; i < 100; ++i) - array->Set(i, v8_num(i)); + array->Set(env.local(), i, v8_num(i)).FromJust(); { // Single chunk of data with 1 entry expected in update. @@ -1230,7 +1248,7 @@ TEST(HeapObjectIds) { v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); const int kLength = 10; - v8::Handle<v8::Object> objects[kLength]; + v8::Local<v8::Object> objects[kLength]; v8::SnapshotObjectId ids[kLength]; heap_profiler->StartTrackingHeapObjects(false); @@ -1252,15 +1270,15 @@ TEST(HeapObjectIds) { for (int i = 0; i < kLength; i++) { v8::SnapshotObjectId id = heap_profiler->GetObjectId(objects[i]); CHECK_EQ(ids[i], id); - v8::Handle<v8::Value> obj = heap_profiler->FindObjectById(ids[i]); - CHECK(objects[i]->Equals(obj)); + v8::Local<v8::Value> obj = heap_profiler->FindObjectById(ids[i]); + CHECK(objects[i]->Equals(env.local(), obj).FromJust()); } heap_profiler->ClearObjectIds(); for (int i = 0; i < kLength; i++) { v8::SnapshotObjectId id = heap_profiler->GetObjectId(objects[i]); CHECK_EQ(v8::HeapProfiler::kUnknownObjectId, id); - v8::Handle<v8::Value> obj = heap_profiler->FindObjectById(ids[i]); + v8::Local<v8::Value> obj = heap_profiler->FindObjectById(ids[i]); CHECK(obj.IsEmpty()); } } @@ -1308,8 +1326,8 @@ TEST(HeapSnapshotGetSnapshotObjectId) { GetProperty(global, v8::HeapGraphEdge::kProperty, "globalObject"); CHECK(global_object); - v8::Local<v8::Value> globalObjectHandle = env->Global()->Get( - v8::String::NewFromUtf8(env->GetIsolate(), "globalObject")); + v8::Local<v8::Value> globalObjectHandle = + env->Global()->Get(env.local(), v8_str("globalObject")).ToLocalChecked(); CHECK(!globalObjectHandle.IsEmpty()); CHECK(globalObjectHandle->IsObject()); @@ -1412,7 +1430,7 @@ class TestRetainedObjectInfo : public v8::RetainedObjectInfo { bool disposed() { return disposed_; } static v8::RetainedObjectInfo* WrapperInfoCallback( - uint16_t class_id, v8::Handle<v8::Value> wrapper) { + uint16_t class_id, v8::Local<v8::Value> wrapper) { if (class_id == 1) { if (wrapper->IsString()) { v8::String::Utf8Value utf8(wrapper); @@ -1532,14 +1550,18 @@ class GraphWithImplicitRefs { for (int i = 0; i < kObjectsCount; i++) { objects_[i].Reset(isolate_, v8::Object::New(isolate_)); } - (*env)->Global()->Set(v8_str("root_object"), - v8::Local<v8::Value>::New(isolate_, objects_[0])); + (*env) + ->Global() + ->Set(isolate_->GetCurrentContext(), v8_str("root_object"), + v8::Local<v8::Value>::New(isolate_, objects_[0])) + .FromJust(); } ~GraphWithImplicitRefs() { instance_ = NULL; } - static void gcPrologue(v8::GCType type, v8::GCCallbackFlags flags) { + static void gcPrologue(v8::Isolate* isolate, v8::GCType type, + v8::GCCallbackFlags flags) { instance_->AddImplicitReferences(); } @@ -1571,7 +1593,7 @@ TEST(HeapSnapshotImplicitReferences) { v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); GraphWithImplicitRefs graph(&env); - v8::V8::AddGCPrologueCallback(&GraphWithImplicitRefs::gcPrologue); + env->GetIsolate()->AddGCPrologueCallback(&GraphWithImplicitRefs::gcPrologue); const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot(); CHECK(ValidateSnapshot(snapshot)); @@ -1594,7 +1616,8 @@ TEST(HeapSnapshotImplicitReferences) { } } CHECK_EQ(2, implicit_targets_count); - v8::V8::RemoveGCPrologueCallback(&GraphWithImplicitRefs::gcPrologue); + env->GetIsolate()->RemoveGCPrologueCallback( + &GraphWithImplicitRefs::gcPrologue); } @@ -1664,7 +1687,7 @@ TEST(DeleteHeapSnapshot) { class NameResolver : public v8::HeapProfiler::ObjectNameResolver { public: - virtual const char* GetName(v8::Handle<v8::Object> object) { + virtual const char* GetName(v8::Local<v8::Object> object) { return "Global object name"; } }; @@ -1757,17 +1780,21 @@ TEST(GetHeapValueForNode) { const v8::HeapGraphNode* obj = GetProperty( global, v8::HeapGraphEdge::kProperty, "a"); CHECK(heap_profiler->FindObjectById(obj->GetId())->IsObject()); - v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>(); + v8::Local<v8::Object> js_obj = js_global->Get(env.local(), v8_str("a")) + .ToLocalChecked() + .As<v8::Object>(); CHECK(js_obj == heap_profiler->FindObjectById(obj->GetId())); const v8::HeapGraphNode* s_prop = GetProperty(obj, v8::HeapGraphEdge::kProperty, "s_prop"); - v8::Local<v8::String> js_s_prop = - js_obj->Get(v8_str("s_prop")).As<v8::String>(); + v8::Local<v8::String> js_s_prop = js_obj->Get(env.local(), v8_str("s_prop")) + .ToLocalChecked() + .As<v8::String>(); CHECK(js_s_prop == heap_profiler->FindObjectById(s_prop->GetId())); const v8::HeapGraphNode* n_prop = GetProperty(obj, v8::HeapGraphEdge::kProperty, "n_prop"); - v8::Local<v8::String> js_n_prop = - js_obj->Get(v8_str("n_prop")).As<v8::String>(); + v8::Local<v8::String> js_n_prop = js_obj->Get(env.local(), v8_str("n_prop")) + .ToLocalChecked() + .As<v8::String>(); CHECK(js_n_prop == heap_profiler->FindObjectById(n_prop->GetId())); } @@ -1818,42 +1845,56 @@ TEST(GetConstructorName) { "var Constructor2 = function() {};\n" "var obj2 = new Constructor2();\n" "var obj3 = {};\n" - "obj3.constructor = function Constructor3() {};\n" + "obj3.__proto__ = { constructor: function Constructor3() {} };\n" "var obj4 = {};\n" "// Slow properties\n" "for (var i=0; i<2000; ++i) obj4[\"p\" + i] = i;\n" - "obj4.constructor = function Constructor4() {};\n" + "obj4.__proto__ = { constructor: function Constructor4() {} };\n" "var obj5 = {};\n" "var obj6 = {};\n" "obj6.constructor = 6;"); v8::Local<v8::Object> js_global = env->Global()->GetPrototype().As<v8::Object>(); - v8::Local<v8::Object> obj1 = js_global->Get(v8_str("obj1")).As<v8::Object>(); - i::Handle<i::JSObject> js_obj1 = v8::Utils::OpenHandle(*obj1); + v8::Local<v8::Object> obj1 = js_global->Get(env.local(), v8_str("obj1")) + .ToLocalChecked() + .As<v8::Object>(); + i::Handle<i::JSObject> js_obj1 = + i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj1)); CHECK_EQ(0, StringCmp( "Constructor1", i::V8HeapExplorer::GetConstructorName(*js_obj1))); - v8::Local<v8::Object> obj2 = js_global->Get(v8_str("obj2")).As<v8::Object>(); - i::Handle<i::JSObject> js_obj2 = v8::Utils::OpenHandle(*obj2); + v8::Local<v8::Object> obj2 = js_global->Get(env.local(), v8_str("obj2")) + .ToLocalChecked() + .As<v8::Object>(); + i::Handle<i::JSObject> js_obj2 = + i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj2)); CHECK_EQ(0, StringCmp( "Constructor2", i::V8HeapExplorer::GetConstructorName(*js_obj2))); - v8::Local<v8::Object> obj3 = js_global->Get(v8_str("obj3")).As<v8::Object>(); - i::Handle<i::JSObject> js_obj3 = v8::Utils::OpenHandle(*obj3); - // TODO(verwaest): Restore to Constructor3 once supported by the - // heap-snapshot-generator. - CHECK_EQ( - 0, StringCmp("Object", i::V8HeapExplorer::GetConstructorName(*js_obj3))); - v8::Local<v8::Object> obj4 = js_global->Get(v8_str("obj4")).As<v8::Object>(); - i::Handle<i::JSObject> js_obj4 = v8::Utils::OpenHandle(*obj4); - // TODO(verwaest): Restore to Constructor4 once supported by the - // heap-snapshot-generator. - CHECK_EQ( - 0, StringCmp("Object", i::V8HeapExplorer::GetConstructorName(*js_obj4))); - v8::Local<v8::Object> obj5 = js_global->Get(v8_str("obj5")).As<v8::Object>(); - i::Handle<i::JSObject> js_obj5 = v8::Utils::OpenHandle(*obj5); + v8::Local<v8::Object> obj3 = js_global->Get(env.local(), v8_str("obj3")) + .ToLocalChecked() + .As<v8::Object>(); + i::Handle<i::JSObject> js_obj3 = + i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj3)); + CHECK_EQ(0, StringCmp("Constructor3", + i::V8HeapExplorer::GetConstructorName(*js_obj3))); + v8::Local<v8::Object> obj4 = js_global->Get(env.local(), v8_str("obj4")) + .ToLocalChecked() + .As<v8::Object>(); + i::Handle<i::JSObject> js_obj4 = + i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj4)); + CHECK_EQ(0, StringCmp("Constructor4", + i::V8HeapExplorer::GetConstructorName(*js_obj4))); + v8::Local<v8::Object> obj5 = js_global->Get(env.local(), v8_str("obj5")) + .ToLocalChecked() + .As<v8::Object>(); + i::Handle<i::JSObject> js_obj5 = + i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj5)); CHECK_EQ(0, StringCmp( "Object", i::V8HeapExplorer::GetConstructorName(*js_obj5))); - v8::Local<v8::Object> obj6 = js_global->Get(v8_str("obj6")).As<v8::Object>(); - i::Handle<i::JSObject> js_obj6 = v8::Utils::OpenHandle(*obj6); + v8::Local<v8::Object> obj6 = js_global->Get(env.local(), v8_str("obj6")) + .ToLocalChecked() + .As<v8::Object>(); + i::Handle<i::JSObject> js_obj6 = + i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj6)); CHECK_EQ(0, StringCmp( "Object", i::V8HeapExplorer::GetConstructorName(*js_obj6))); } @@ -1912,8 +1953,10 @@ TEST(FastCaseRedefinedAccessors) { "});\n"); v8::Local<v8::Object> js_global = env->Global()->GetPrototype().As<v8::Object>(); - i::Handle<i::JSObject> js_obj1 = - v8::Utils::OpenHandle(*js_global->Get(v8_str("obj1")).As<v8::Object>()); + i::Handle<i::JSReceiver> js_obj1 = + v8::Utils::OpenHandle(*js_global->Get(env.local(), v8_str("obj1")) + .ToLocalChecked() + .As<v8::Object>()); USE(js_obj1); const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot(); @@ -1983,10 +2026,11 @@ TEST(HiddenPropertiesFastCase) { GetProperty(c, v8::HeapGraphEdge::kProperty, "<symbol>"); CHECK(!hidden_props); - v8::Handle<v8::Value> cHandle = - env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "c")); + v8::Local<v8::Value> cHandle = + env->Global()->Get(env.local(), v8_str("c")).ToLocalChecked(); CHECK(!cHandle.IsEmpty() && cHandle->IsObject()); - cHandle->ToObject(isolate) + cHandle->ToObject(env.local()) + .ToLocalChecked() ->SetPrivate(env.local(), v8::Private::ForApi(env->GetIsolate(), v8_str("key")), v8_str("val")) @@ -2117,7 +2161,6 @@ 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) { @@ -2125,13 +2168,10 @@ TEST(NoDebugObjectInSnapshot) { const v8::HeapGraphNode* global = edge->GetToNode(); const v8::HeapGraphNode* foo = GetProperty(global, v8::HeapGraphEdge::kProperty, "foo"); - if (foo != nullptr) { - found = true; - } + CHECK(foo); } } - CHECK_EQ(2, globals_count); - CHECK(found); + CHECK_EQ(1, globals_count); } @@ -2288,18 +2328,27 @@ TEST(AllocationSitesAreVisible) { CHECK_EQ(v8::internal::FixedArray::SizeFor(3), static_cast<int>(elements->GetShallowSize())); - v8::Handle<v8::Value> array_val = + v8::Local<v8::Value> array_val = heap_profiler->FindObjectById(transition_info->GetId()); CHECK(array_val->IsArray()); - v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(array_val); + v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(array_val); // Verify the array is "a" in the code above. CHECK_EQ(3u, array->Length()); CHECK(v8::Integer::New(isolate, 3) - ->Equals(array->Get(v8::Integer::New(isolate, 0)))); + ->Equals(env.local(), + array->Get(env.local(), v8::Integer::New(isolate, 0)) + .ToLocalChecked()) + .FromJust()); CHECK(v8::Integer::New(isolate, 2) - ->Equals(array->Get(v8::Integer::New(isolate, 1)))); + ->Equals(env.local(), + array->Get(env.local(), v8::Integer::New(isolate, 1)) + .ToLocalChecked()) + .FromJust()); CHECK(v8::Integer::New(isolate, 1) - ->Equals(array->Get(v8::Integer::New(isolate, 2)))); + ->Equals(env.local(), + array->Get(env.local(), v8::Integer::New(isolate, 2)) + .ToLocalChecked()) + .FromJust()); } @@ -2583,7 +2632,7 @@ TEST(TrackV8ApiAllocation) { const char* names[] = { "(V8 API)" }; heap_profiler->StartTrackingHeapObjects(true); - v8::Handle<v8::Object> o1 = v8::Object::New(env->GetIsolate()); + v8::Local<v8::Object> o1 = v8::Object::New(env->GetIsolate()); o1->Clone(); AllocationTracker* tracker = @@ -2653,15 +2702,15 @@ TEST(ArrayBufferSharedBackingStore) { CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); void* data = ab_contents.Data(); - DCHECK(data != NULL); + CHECK(data != NULL); v8::Local<v8::ArrayBuffer> ab2 = v8::ArrayBuffer::New(isolate, data, ab_contents.ByteLength()); CHECK(ab2->IsExternal()); - env->Global()->Set(v8_str("ab1"), ab); - env->Global()->Set(v8_str("ab2"), ab2); + env->Global()->Set(env.local(), v8_str("ab1"), ab).FromJust(); + env->Global()->Set(env.local(), v8_str("ab2"), ab2).FromJust(); - v8::Handle<v8::Value> result = CompileRun("ab2.byteLength"); - CHECK_EQ(1024, result->Int32Value()); + v8::Local<v8::Value> result = CompileRun("ab2.byteLength"); + CHECK_EQ(1024, result->Int32Value(env.local()).FromJust()); const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot(); CHECK(ValidateSnapshot(snapshot)); @@ -2688,13 +2737,13 @@ TEST(BoxObject) { v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); LocalContext env; - v8::Handle<v8::Object> global_proxy = env->Global(); - v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); + v8::Local<v8::Object> global_proxy = env->Global(); + v8::Local<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); i::Factory* factory = CcTest::i_isolate()->factory(); i::Handle<i::String> string = factory->NewStringFromStaticChars("string"); i::Handle<i::Object> box = factory->NewBox(string); - global->Set(0, v8::ToApiHandle<v8::Object>(box)); + global->Set(env.local(), 0, v8::ToApiHandle<v8::Object>(box)).FromJust(); v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot(); diff --git a/deps/v8/test/cctest/test-inobject-slack-tracking.cc b/deps/v8/test/cctest/test-inobject-slack-tracking.cc new file mode 100644 index 0000000000..6ce77c9416 --- /dev/null +++ b/deps/v8/test/cctest/test-inobject-slack-tracking.cc @@ -0,0 +1,1111 @@ +// 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 <stdlib.h> +#include <sstream> +#include <utility> + +#include "src/api.h" +#include "src/objects.h" +#include "src/v8.h" + +#include "test/cctest/cctest.h" + +using namespace v8::base; +using namespace v8::internal; + + +static const int kMaxInobjectProperties = + (JSObject::kMaxInstanceSize - JSObject::kHeaderSize) >> kPointerSizeLog2; + + +template <typename T> +static Handle<T> OpenHandle(v8::Local<v8::Value> value) { + Handle<Object> obj = v8::Utils::OpenHandle(*value); + return Handle<T>::cast(obj); +} + + +static inline v8::Local<v8::Value> Run(v8::Local<v8::Script> script) { + v8::Local<v8::Value> result; + if (script->Run(v8::Isolate::GetCurrent()->GetCurrentContext()) + .ToLocal(&result)) { + return result; + } + return v8::Local<v8::Value>(); +} + + +template <typename T = Object> +Handle<T> GetGlobal(const char* name) { + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + Handle<String> str_name = factory->InternalizeUtf8String(name); + + Handle<Object> value = + Object::GetProperty(isolate->global_object(), str_name).ToHandleChecked(); + return Handle<T>::cast(value); +} + + +template <typename T = Object> +Handle<T> GetLexical(const char* name) { + Isolate* isolate = CcTest::i_isolate(); + Factory* factory = isolate->factory(); + + Handle<String> str_name = factory->InternalizeUtf8String(name); + Handle<ScriptContextTable> script_contexts( + isolate->native_context()->script_context_table()); + + ScriptContextTable::LookupResult lookup_result; + if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) { + Handle<Object> result = + FixedArray::get(ScriptContextTable::GetContext( + script_contexts, lookup_result.context_index), + lookup_result.slot_index); + return Handle<T>::cast(result); + } + return Handle<T>(); +} + + +template <typename T = Object> +Handle<T> GetLexical(const std::string& name) { + return GetLexical<T>(name.c_str()); +} + + +template <typename T> +static inline Handle<T> Run(v8::Local<v8::Script> script) { + return OpenHandle<T>(Run(script)); +} + + +template <typename T> +static inline Handle<T> CompileRun(const char* script) { + return OpenHandle<T>(CompileRun(script)); +} + + +static Object* GetFieldValue(JSObject* obj, int property_index) { + FieldIndex index = FieldIndex::ForPropertyIndex(obj->map(), property_index); + return obj->RawFastPropertyAt(index); +} + + +static double GetDoubleFieldValue(JSObject* obj, FieldIndex field_index) { + if (obj->IsUnboxedDoubleField(field_index)) { + return obj->RawFastDoublePropertyAt(field_index); + } else { + Object* value = obj->RawFastPropertyAt(field_index); + CHECK(value->IsMutableHeapNumber()); + return HeapNumber::cast(value)->value(); + } +} + + +static double GetDoubleFieldValue(JSObject* obj, int property_index) { + FieldIndex index = FieldIndex::ForPropertyIndex(obj->map(), property_index); + return GetDoubleFieldValue(obj, index); +} + + +bool IsObjectShrinkable(JSObject* obj) { + Handle<Map> filler_map = + CcTest::i_isolate()->factory()->one_pointer_filler_map(); + + int inobject_properties = obj->map()->GetInObjectProperties(); + int unused = obj->map()->unused_property_fields(); + if (unused == 0) return false; + + for (int i = inobject_properties - unused; i < inobject_properties; i++) { + if (*filler_map != GetFieldValue(obj, i)) { + return false; + } + } + return true; +} + + +TEST(JSObjectBasic) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + const char* source = + "function A() {" + " this.a = 42;" + " this.d = 4.2;" + " this.o = this;" + "}"; + CompileRun(source); + + Handle<JSFunction> func = GetGlobal<JSFunction>("A"); + + // Zero instances were created so far. + CHECK(!func->has_initial_map()); + + v8::Local<v8::Script> new_A_script = v8_compile("new A();"); + + Handle<JSObject> obj = Run<JSObject>(new_A_script); + + CHECK(func->has_initial_map()); + Handle<Map> initial_map(func->initial_map()); + + // One instance created. + CHECK_EQ(Map::kSlackTrackingCounterStart - 1, + initial_map->construction_counter()); + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + + // There must be at least some slack. + CHECK_LT(5, obj->map()->GetInObjectProperties()); + CHECK_EQ(Smi::FromInt(42), GetFieldValue(*obj, 0)); + CHECK_EQ(4.2, GetDoubleFieldValue(*obj, 1)); + CHECK_EQ(*obj, GetFieldValue(*obj, 2)); + CHECK(IsObjectShrinkable(*obj)); + + // Create several objects to complete the tracking. + for (int i = 1; i < Map::kGenerousAllocationCount; i++) { + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + Handle<JSObject> tmp = Run<JSObject>(new_A_script); + CHECK_EQ(initial_map->IsInobjectSlackTrackingInProgress(), + IsObjectShrinkable(*tmp)); + } + CHECK(!initial_map->IsInobjectSlackTrackingInProgress()); + CHECK(!IsObjectShrinkable(*obj)); + + // No slack left. + CHECK_EQ(3, obj->map()->GetInObjectProperties()); +} + + +TEST(JSObjectBasicNoInlineNew) { + FLAG_inline_new = false; + TestJSObjectBasic(); +} + + +TEST(JSObjectComplex) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + const char* source = + "function A(n) {" + " if (n > 0) this.a = 42;" + " if (n > 1) this.d = 4.2;" + " if (n > 2) this.o1 = this;" + " if (n > 3) this.o2 = this;" + " if (n > 4) this.o3 = this;" + " if (n > 5) this.o4 = this;" + "}"; + CompileRun(source); + + Handle<JSFunction> func = GetGlobal<JSFunction>("A"); + + // Zero instances were created so far. + CHECK(!func->has_initial_map()); + + Handle<JSObject> obj1 = CompileRun<JSObject>("new A(1);"); + Handle<JSObject> obj3 = CompileRun<JSObject>("new A(3);"); + Handle<JSObject> obj5 = CompileRun<JSObject>("new A(5);"); + + CHECK(func->has_initial_map()); + Handle<Map> initial_map(func->initial_map()); + + // Three instances created. + CHECK_EQ(Map::kSlackTrackingCounterStart - 3, + initial_map->construction_counter()); + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + + // There must be at least some slack. + CHECK_LT(5, obj3->map()->GetInObjectProperties()); + CHECK_EQ(Smi::FromInt(42), GetFieldValue(*obj3, 0)); + CHECK_EQ(4.2, GetDoubleFieldValue(*obj3, 1)); + CHECK_EQ(*obj3, GetFieldValue(*obj3, 2)); + CHECK(IsObjectShrinkable(*obj1)); + CHECK(IsObjectShrinkable(*obj3)); + CHECK(IsObjectShrinkable(*obj5)); + + // Create several objects to complete the tracking. + for (int i = 3; i < Map::kGenerousAllocationCount; i++) { + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + CompileRun("new A(3);"); + } + CHECK(!initial_map->IsInobjectSlackTrackingInProgress()); + + // obj1 and obj2 stays shrinkable because we don't clear unused fields. + CHECK(IsObjectShrinkable(*obj1)); + CHECK(IsObjectShrinkable(*obj3)); + CHECK(!IsObjectShrinkable(*obj5)); + + CHECK_EQ(5, obj1->map()->GetInObjectProperties()); + CHECK_EQ(4, obj1->map()->unused_property_fields()); + + CHECK_EQ(5, obj3->map()->GetInObjectProperties()); + CHECK_EQ(2, obj3->map()->unused_property_fields()); + + CHECK_EQ(5, obj5->map()->GetInObjectProperties()); + CHECK_EQ(0, obj5->map()->unused_property_fields()); + + // Since slack tracking is complete, the new objects should not be shrinkable. + obj1 = CompileRun<JSObject>("new A(1);"); + obj3 = CompileRun<JSObject>("new A(3);"); + obj5 = CompileRun<JSObject>("new A(5);"); + + CHECK(!IsObjectShrinkable(*obj1)); + CHECK(!IsObjectShrinkable(*obj3)); + CHECK(!IsObjectShrinkable(*obj5)); +} + + +TEST(JSObjectComplexNoInlineNew) { + FLAG_inline_new = false; + TestJSObjectComplex(); +} + + +TEST(JSGeneratorObjectBasic) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + const char* source = + "function* A() {" + " var i = 0;" + " while(true) {" + " yield i++;" + " }" + "};" + "function CreateGenerator() {" + " var o = A();" + " o.a = 42;" + " o.d = 4.2;" + " o.o = o;" + " return o;" + "}"; + CompileRun(source); + + Handle<JSFunction> func = GetGlobal<JSFunction>("A"); + + // Zero instances were created so far. + CHECK(!func->has_initial_map()); + + v8::Local<v8::Script> new_A_script = v8_compile("CreateGenerator();"); + + Handle<JSObject> obj = Run<JSObject>(new_A_script); + + CHECK(func->has_initial_map()); + Handle<Map> initial_map(func->initial_map()); + + // One instance created. + CHECK_EQ(Map::kSlackTrackingCounterStart - 1, + initial_map->construction_counter()); + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + + // There must be at least some slack. + CHECK_LT(5, obj->map()->GetInObjectProperties()); + CHECK_EQ(Smi::FromInt(42), GetFieldValue(*obj, 0)); + CHECK_EQ(4.2, GetDoubleFieldValue(*obj, 1)); + CHECK_EQ(*obj, GetFieldValue(*obj, 2)); + CHECK(IsObjectShrinkable(*obj)); + + // Create several objects to complete the tracking. + for (int i = 1; i < Map::kGenerousAllocationCount; i++) { + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + Handle<JSObject> tmp = Run<JSObject>(new_A_script); + CHECK_EQ(initial_map->IsInobjectSlackTrackingInProgress(), + IsObjectShrinkable(*tmp)); + } + CHECK(!initial_map->IsInobjectSlackTrackingInProgress()); + CHECK(!IsObjectShrinkable(*obj)); + + // No slack left. + CHECK_EQ(3, obj->map()->GetInObjectProperties()); +} + + +TEST(JSGeneratorObjectBasicNoInlineNew) { + FLAG_inline_new = false; + TestJSGeneratorObjectBasic(); +} + + +TEST(SubclassBasicNoBaseClassInstances) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + // Check that base class' and subclass' slack tracking do not interfere with + // each other. + // In this test we never create base class instances. + + const char* source = + "'use strict';" + "class A {" + " constructor(...args) {" + " this.aa = 42;" + " this.ad = 4.2;" + " this.ao = this;" + " }" + "};" + "class B extends A {" + " constructor(...args) {" + " super(...args);" + " this.ba = 142;" + " this.bd = 14.2;" + " this.bo = this;" + " }" + "};"; + CompileRun(source); + + Handle<JSFunction> a_func = GetLexical<JSFunction>("A"); + Handle<JSFunction> b_func = GetLexical<JSFunction>("B"); + + // Zero instances were created so far. + CHECK(!a_func->has_initial_map()); + CHECK(!b_func->has_initial_map()); + + v8::Local<v8::Script> new_B_script = v8_compile("new B();"); + + Handle<JSObject> obj = Run<JSObject>(new_B_script); + + CHECK(a_func->has_initial_map()); + Handle<Map> a_initial_map(a_func->initial_map()); + + CHECK(b_func->has_initial_map()); + Handle<Map> b_initial_map(b_func->initial_map()); + + // Zero instances of A created. + CHECK_EQ(Map::kSlackTrackingCounterStart, + a_initial_map->construction_counter()); + CHECK(a_initial_map->IsInobjectSlackTrackingInProgress()); + + // One instance of B created. + CHECK_EQ(Map::kSlackTrackingCounterStart - 1, + b_initial_map->construction_counter()); + CHECK(b_initial_map->IsInobjectSlackTrackingInProgress()); + + // There must be at least some slack. + CHECK_LT(10, obj->map()->GetInObjectProperties()); + CHECK_EQ(Smi::FromInt(42), GetFieldValue(*obj, 0)); + CHECK_EQ(4.2, GetDoubleFieldValue(*obj, 1)); + CHECK_EQ(*obj, GetFieldValue(*obj, 2)); + CHECK_EQ(Smi::FromInt(142), GetFieldValue(*obj, 3)); + CHECK_EQ(14.2, GetDoubleFieldValue(*obj, 4)); + CHECK_EQ(*obj, GetFieldValue(*obj, 5)); + CHECK(IsObjectShrinkable(*obj)); + + // Create several subclass instances to complete the tracking. + for (int i = 1; i < Map::kGenerousAllocationCount; i++) { + CHECK(b_initial_map->IsInobjectSlackTrackingInProgress()); + Handle<JSObject> tmp = Run<JSObject>(new_B_script); + CHECK_EQ(b_initial_map->IsInobjectSlackTrackingInProgress(), + IsObjectShrinkable(*tmp)); + } + CHECK(!b_initial_map->IsInobjectSlackTrackingInProgress()); + CHECK(!IsObjectShrinkable(*obj)); + + // Zero instances of A created. + CHECK_EQ(Map::kSlackTrackingCounterStart, + a_initial_map->construction_counter()); + CHECK(a_initial_map->IsInobjectSlackTrackingInProgress()); + + // No slack left. + CHECK_EQ(6, obj->map()->GetInObjectProperties()); +} + + +TEST(SubclassBasicNoBaseClassInstancesNoInlineNew) { + FLAG_inline_new = false; + TestSubclassBasicNoBaseClassInstances(); +} + + +TEST(SubclassBasic) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + // Check that base class' and subclass' slack tracking do not interfere with + // each other. + // In this test we first create enough base class instances to complete + // the slack tracking and then proceed creating subclass instances. + + const char* source = + "'use strict';" + "class A {" + " constructor(...args) {" + " this.aa = 42;" + " this.ad = 4.2;" + " this.ao = this;" + " }" + "};" + "class B extends A {" + " constructor(...args) {" + " super(...args);" + " this.ba = 142;" + " this.bd = 14.2;" + " this.bo = this;" + " }" + "};"; + CompileRun(source); + + Handle<JSFunction> a_func = GetLexical<JSFunction>("A"); + Handle<JSFunction> b_func = GetLexical<JSFunction>("B"); + + // Zero instances were created so far. + CHECK(!a_func->has_initial_map()); + CHECK(!b_func->has_initial_map()); + + v8::Local<v8::Script> new_A_script = v8_compile("new A();"); + v8::Local<v8::Script> new_B_script = v8_compile("new B();"); + + Handle<JSObject> a_obj = Run<JSObject>(new_A_script); + Handle<JSObject> b_obj = Run<JSObject>(new_B_script); + + CHECK(a_func->has_initial_map()); + Handle<Map> a_initial_map(a_func->initial_map()); + + CHECK(b_func->has_initial_map()); + Handle<Map> b_initial_map(b_func->initial_map()); + + // One instance of a base class created. + CHECK_EQ(Map::kSlackTrackingCounterStart - 1, + a_initial_map->construction_counter()); + CHECK(a_initial_map->IsInobjectSlackTrackingInProgress()); + + // One instance of a subclass created. + CHECK_EQ(Map::kSlackTrackingCounterStart - 1, + b_initial_map->construction_counter()); + CHECK(b_initial_map->IsInobjectSlackTrackingInProgress()); + + // Create several base class instances to complete the tracking. + for (int i = 1; i < Map::kGenerousAllocationCount; i++) { + CHECK(a_initial_map->IsInobjectSlackTrackingInProgress()); + Handle<JSObject> tmp = Run<JSObject>(new_A_script); + CHECK_EQ(a_initial_map->IsInobjectSlackTrackingInProgress(), + IsObjectShrinkable(*tmp)); + } + CHECK(!a_initial_map->IsInobjectSlackTrackingInProgress()); + CHECK(!IsObjectShrinkable(*a_obj)); + + // No slack left. + CHECK_EQ(3, a_obj->map()->GetInObjectProperties()); + + // There must be at least some slack. + CHECK_LT(10, b_obj->map()->GetInObjectProperties()); + CHECK_EQ(Smi::FromInt(42), GetFieldValue(*b_obj, 0)); + CHECK_EQ(4.2, GetDoubleFieldValue(*b_obj, 1)); + CHECK_EQ(*b_obj, GetFieldValue(*b_obj, 2)); + CHECK_EQ(Smi::FromInt(142), GetFieldValue(*b_obj, 3)); + CHECK_EQ(14.2, GetDoubleFieldValue(*b_obj, 4)); + CHECK_EQ(*b_obj, GetFieldValue(*b_obj, 5)); + CHECK(IsObjectShrinkable(*b_obj)); + + // Create several subclass instances to complete the tracking. + for (int i = 1; i < Map::kGenerousAllocationCount; i++) { + CHECK(b_initial_map->IsInobjectSlackTrackingInProgress()); + Handle<JSObject> tmp = Run<JSObject>(new_B_script); + CHECK_EQ(b_initial_map->IsInobjectSlackTrackingInProgress(), + IsObjectShrinkable(*tmp)); + } + CHECK(!b_initial_map->IsInobjectSlackTrackingInProgress()); + CHECK(!IsObjectShrinkable(*b_obj)); + + // No slack left. + CHECK_EQ(6, b_obj->map()->GetInObjectProperties()); +} + + +TEST(SubclassBasicNoInlineNew) { + FLAG_inline_new = false; + TestSubclassBasic(); +} + + +// Creates class hierachy of length matching the |hierarchy_desc| length and +// with the number of fields at i'th level equal to |hierarchy_desc[i]|. +static void CreateClassHierarchy(const std::vector<int>& hierarchy_desc) { + std::ostringstream os; + os << "'use strict';\n\n"; + + int n = static_cast<int>(hierarchy_desc.size()); + for (int cur_class = 0; cur_class < n; cur_class++) { + os << "class A" << cur_class; + if (cur_class > 0) { + os << " extends A" << (cur_class - 1); + } + os << " {\n" + " constructor(...args) {\n"; + if (cur_class > 0) { + os << " super(...args);\n"; + } + int fields_count = hierarchy_desc[cur_class]; + for (int k = 0; k < fields_count; k++) { + os << " this.f" << cur_class << "_" << k << " = " << k << ";\n"; + } + os << " }\n" + "};\n\n"; + } + CompileRun(os.str().c_str()); +} + + +static std::string GetClassName(int class_index) { + std::ostringstream os; + os << "A" << class_index; + return os.str(); +} + + +static v8::Local<v8::Script> GetNewObjectScript(const std::string& class_name) { + std::ostringstream os; + os << "new " << class_name << "();"; + return v8_compile(os.str().c_str()); +} + + +// Test that in-object slack tracking works as expected for first |n| classes +// in the hierarchy. +// This test works only for if the total property count is less than maximum +// in-object properties count. +static void TestClassHierarchy(const std::vector<int>& hierarchy_desc, int n) { + int fields_count = 0; + for (int cur_class = 0; cur_class < n; cur_class++) { + std::string class_name = GetClassName(cur_class); + int fields_count_at_current_level = hierarchy_desc[cur_class]; + fields_count += fields_count_at_current_level; + + // This test is not suitable for in-object properties count overflow case. + CHECK_LT(fields_count, kMaxInobjectProperties); + + // Create |class_name| objects and check slack tracking. + v8::Local<v8::Script> new_script = GetNewObjectScript(class_name); + + Handle<JSFunction> func = GetLexical<JSFunction>(class_name); + + Handle<JSObject> obj = Run<JSObject>(new_script); + + CHECK(func->has_initial_map()); + Handle<Map> initial_map(func->initial_map()); + + // There must be at least some slack. + CHECK_LT(fields_count, obj->map()->GetInObjectProperties()); + + // One instance was created. + CHECK_EQ(Map::kSlackTrackingCounterStart - 1, + initial_map->construction_counter()); + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + + // Create several instances to complete the tracking. + for (int i = 1; i < Map::kGenerousAllocationCount; i++) { + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + Handle<JSObject> tmp = Run<JSObject>(new_script); + CHECK_EQ(initial_map->IsInobjectSlackTrackingInProgress(), + IsObjectShrinkable(*tmp)); + } + CHECK(!initial_map->IsInobjectSlackTrackingInProgress()); + CHECK(!IsObjectShrinkable(*obj)); + + // No slack left. + CHECK_EQ(fields_count, obj->map()->GetInObjectProperties()); + } +} + + +static void TestSubclassChain(const std::vector<int>& hierarchy_desc) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + CreateClassHierarchy(hierarchy_desc); + TestClassHierarchy(hierarchy_desc, static_cast<int>(hierarchy_desc.size())); +} + + +TEST(LongSubclassChain1) { + std::vector<int> hierarchy_desc; + for (int i = 0; i < 7; i++) { + hierarchy_desc.push_back(i * 10); + } + TestSubclassChain(hierarchy_desc); +} + + +TEST(LongSubclassChain2) { + std::vector<int> hierarchy_desc; + hierarchy_desc.push_back(10); + for (int i = 0; i < 42; i++) { + hierarchy_desc.push_back(0); + } + hierarchy_desc.push_back(230); + TestSubclassChain(hierarchy_desc); +} + + +TEST(LongSubclassChain3) { + std::vector<int> hierarchy_desc; + for (int i = 0; i < 42; i++) { + hierarchy_desc.push_back(5); + } + TestSubclassChain(hierarchy_desc); +} + + +TEST(InobjectPropetiesCountOverflowInSubclass) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + std::vector<int> hierarchy_desc; + const int kNoOverflowCount = 5; + for (int i = 0; i < kNoOverflowCount; i++) { + hierarchy_desc.push_back(50); + } + // In this class we are going to have properties in the backing store. + hierarchy_desc.push_back(100); + + CreateClassHierarchy(hierarchy_desc); + + // For the last class in the hierarchy we need different checks. + { + int cur_class = kNoOverflowCount; + std::string class_name = GetClassName(cur_class); + + // Create |class_name| objects and check slack tracking. + v8::Local<v8::Script> new_script = GetNewObjectScript(class_name); + + Handle<JSFunction> func = GetLexical<JSFunction>(class_name); + + Handle<JSObject> obj = Run<JSObject>(new_script); + + CHECK(func->has_initial_map()); + Handle<Map> initial_map(func->initial_map()); + + // There must be no slack left. + CHECK_EQ(JSObject::kMaxInstanceSize, obj->map()->instance_size()); + CHECK_EQ(kMaxInobjectProperties, obj->map()->GetInObjectProperties()); + + // One instance was created. + CHECK_EQ(Map::kSlackTrackingCounterStart - 1, + initial_map->construction_counter()); + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + + // Create several instances to complete the tracking. + for (int i = 1; i < Map::kGenerousAllocationCount; i++) { + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + Handle<JSObject> tmp = Run<JSObject>(new_script); + CHECK(!IsObjectShrinkable(*tmp)); + } + CHECK(!initial_map->IsInobjectSlackTrackingInProgress()); + CHECK(!IsObjectShrinkable(*obj)); + + // No slack left. + CHECK_EQ(kMaxInobjectProperties, obj->map()->GetInObjectProperties()); + } + + // The other classes in the hierarchy are not affected. + TestClassHierarchy(hierarchy_desc, kNoOverflowCount); +} + + +TEST(SlowModeSubclass) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + std::vector<int> hierarchy_desc; + const int kNoOverflowCount = 5; + for (int i = 0; i < kNoOverflowCount; i++) { + hierarchy_desc.push_back(50); + } + // This class should go dictionary mode. + hierarchy_desc.push_back(1000); + + CreateClassHierarchy(hierarchy_desc); + + // For the last class in the hierarchy we need different checks. + { + int cur_class = kNoOverflowCount; + std::string class_name = GetClassName(cur_class); + + // Create |class_name| objects and check slack tracking. + v8::Local<v8::Script> new_script = GetNewObjectScript(class_name); + + Handle<JSFunction> func = GetLexical<JSFunction>(class_name); + + Handle<JSObject> obj = Run<JSObject>(new_script); + + CHECK(func->has_initial_map()); + Handle<Map> initial_map(func->initial_map()); + + // Object should go dictionary mode. + CHECK_EQ(JSObject::kHeaderSize, obj->map()->instance_size()); + CHECK(obj->map()->is_dictionary_map()); + + // One instance was created. + CHECK_EQ(Map::kSlackTrackingCounterStart - 1, + initial_map->construction_counter()); + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + + // Create several instances to complete the tracking. + for (int i = 1; i < Map::kGenerousAllocationCount; i++) { + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + Handle<JSObject> tmp = Run<JSObject>(new_script); + CHECK(!IsObjectShrinkable(*tmp)); + } + CHECK(!initial_map->IsInobjectSlackTrackingInProgress()); + CHECK(!IsObjectShrinkable(*obj)); + + // Object should stay in dictionary mode. + CHECK_EQ(JSObject::kHeaderSize, obj->map()->instance_size()); + CHECK(obj->map()->is_dictionary_map()); + } + + // The other classes in the hierarchy are not affected. + TestClassHierarchy(hierarchy_desc, kNoOverflowCount); +} + + +static void TestSubclassBuiltin(const char* subclass_name, + InstanceType instance_type, + const char* builtin_name, + const char* ctor_arguments = "", + int builtin_properties_count = 0) { + { + std::ostringstream os; + os << "'use strict';\n" + "class " + << subclass_name << " extends " << builtin_name + << " {\n" + " constructor(...args) {\n" + " super(...args);\n" + " this.a = 42;\n" + " this.d = 4.2;\n" + " this.o = this;\n" + " }\n" + "};\n"; + CompileRun(os.str().c_str()); + } + + Handle<JSFunction> func = GetLexical<JSFunction>(subclass_name); + + // Zero instances were created so far. + CHECK(!func->has_initial_map()); + + v8::Local<v8::Script> new_script; + { + std::ostringstream os; + os << "new " << subclass_name << "(" << ctor_arguments << ");"; + new_script = v8_compile(os.str().c_str()); + } + + Run<JSObject>(new_script); + + CHECK(func->has_initial_map()); + Handle<Map> initial_map(func->initial_map()); + + CHECK_EQ(instance_type, initial_map->instance_type()); + + // One instance of a subclass created. + CHECK_EQ(Map::kSlackTrackingCounterStart - 1, + initial_map->construction_counter()); + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + + // Create two instances in order to ensure that |obj|.o is a data field + // in case of Function subclassing. + Handle<JSObject> obj = Run<JSObject>(new_script); + + // Two instances of a subclass created. + CHECK_EQ(Map::kSlackTrackingCounterStart - 2, + initial_map->construction_counter()); + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + + // There must be at least some slack. + CHECK_LT(builtin_properties_count + 5, obj->map()->GetInObjectProperties()); + CHECK_EQ(Smi::FromInt(42), GetFieldValue(*obj, builtin_properties_count + 0)); + CHECK_EQ(4.2, GetDoubleFieldValue(*obj, builtin_properties_count + 1)); + CHECK_EQ(*obj, GetFieldValue(*obj, builtin_properties_count + 2)); + CHECK(IsObjectShrinkable(*obj)); + + // Create several subclass instances to complete the tracking. + for (int i = 2; i < Map::kGenerousAllocationCount; i++) { + CHECK(initial_map->IsInobjectSlackTrackingInProgress()); + Handle<JSObject> tmp = Run<JSObject>(new_script); + CHECK_EQ(initial_map->IsInobjectSlackTrackingInProgress(), + IsObjectShrinkable(*tmp)); + } + CHECK(!initial_map->IsInobjectSlackTrackingInProgress()); + CHECK(!IsObjectShrinkable(*obj)); + + // No slack left. + CHECK_EQ(builtin_properties_count + 3, obj->map()->GetInObjectProperties()); + + CHECK_EQ(instance_type, obj->map()->instance_type()); +} + + +TEST(SubclassObjectBuiltin) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + TestSubclassBuiltin("A1", JS_OBJECT_TYPE, "Object", "true"); + TestSubclassBuiltin("A2", JS_OBJECT_TYPE, "Object", "42"); + TestSubclassBuiltin("A3", JS_OBJECT_TYPE, "Object", "'some string'"); +} + + +TEST(SubclassObjectBuiltinNoInlineNew) { + FLAG_inline_new = false; + TestSubclassObjectBuiltin(); +} + + +TEST(SubclassFunctionBuiltin) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + TestSubclassBuiltin("A1", JS_FUNCTION_TYPE, "Function", "'return 153;'"); + TestSubclassBuiltin("A2", JS_FUNCTION_TYPE, "Function", "'this.a = 44;'"); +} + + +TEST(SubclassFunctionBuiltinNoInlineNew) { + FLAG_inline_new = false; + TestSubclassFunctionBuiltin(); +} + + +TEST(SubclassBooleanBuiltin) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + TestSubclassBuiltin("A1", JS_VALUE_TYPE, "Boolean", "true"); + TestSubclassBuiltin("A2", JS_VALUE_TYPE, "Boolean", "false"); +} + + +TEST(SubclassBooleanBuiltinNoInlineNew) { + FLAG_inline_new = false; + TestSubclassBooleanBuiltin(); +} + + +TEST(SubclassErrorBuiltin) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + const int first_field = 2; + TestSubclassBuiltin("A1", JS_OBJECT_TYPE, "Error", "'err'", first_field); + TestSubclassBuiltin("A2", JS_OBJECT_TYPE, "EvalError", "'err'", first_field); + TestSubclassBuiltin("A3", JS_OBJECT_TYPE, "RangeError", "'err'", first_field); + TestSubclassBuiltin("A4", JS_OBJECT_TYPE, "ReferenceError", "'err'", + first_field); + TestSubclassBuiltin("A5", JS_OBJECT_TYPE, "SyntaxError", "'err'", + first_field); + TestSubclassBuiltin("A6", JS_OBJECT_TYPE, "TypeError", "'err'", first_field); + TestSubclassBuiltin("A7", JS_OBJECT_TYPE, "URIError", "'err'", first_field); +} + + +TEST(SubclassErrorBuiltinNoInlineNew) { + FLAG_inline_new = false; + TestSubclassErrorBuiltin(); +} + + +TEST(SubclassNumberBuiltin) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + TestSubclassBuiltin("A1", JS_VALUE_TYPE, "Number", "42"); + TestSubclassBuiltin("A2", JS_VALUE_TYPE, "Number", "4.2"); +} + + +TEST(SubclassNumberBuiltinNoInlineNew) { + FLAG_inline_new = false; + TestSubclassNumberBuiltin(); +} + + +TEST(SubclassDateBuiltin) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + TestSubclassBuiltin("A1", JS_DATE_TYPE, "Date", "123456789"); +} + + +TEST(SubclassDateBuiltinNoInlineNew) { + FLAG_inline_new = false; + TestSubclassDateBuiltin(); +} + + +TEST(SubclassStringBuiltin) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + TestSubclassBuiltin("A1", JS_VALUE_TYPE, "String", "'some string'"); + TestSubclassBuiltin("A2", JS_VALUE_TYPE, "String", ""); +} + + +TEST(SubclassStringBuiltinNoInlineNew) { + FLAG_inline_new = false; + TestSubclassStringBuiltin(); +} + + +TEST(SubclassRegExpBuiltin) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + const int first_field = 1; + TestSubclassBuiltin("A1", JS_REGEXP_TYPE, "RegExp", "'o(..)h', 'g'", + first_field); +} + + +TEST(SubclassRegExpBuiltinNoInlineNew) { + FLAG_inline_new = false; + TestSubclassRegExpBuiltin(); +} + + +TEST(SubclassArrayBuiltin) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + TestSubclassBuiltin("A1", JS_ARRAY_TYPE, "Array", "42"); +} + + +TEST(SubclassArrayBuiltinNoInlineNew) { + FLAG_inline_new = false; + TestSubclassArrayBuiltin(); +} + + +TEST(SubclassTypedArrayBuiltin) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + +#define TYPED_ARRAY_TEST(Type, type, TYPE, elementType, size) \ + TestSubclassBuiltin("A" #Type, JS_TYPED_ARRAY_TYPE, #Type "Array", "42"); + + TYPED_ARRAYS(TYPED_ARRAY_TEST) + +#undef TYPED_ARRAY_TEST +} + + +TEST(SubclassTypedArrayBuiltinNoInlineNew) { + FLAG_inline_new = false; + TestSubclassTypedArrayBuiltin(); +} + + +TEST(SubclassCollectionBuiltin) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + TestSubclassBuiltin("A1", JS_SET_TYPE, "Set", ""); + TestSubclassBuiltin("A2", JS_MAP_TYPE, "Map", ""); + TestSubclassBuiltin("A3", JS_WEAK_SET_TYPE, "WeakSet", ""); + TestSubclassBuiltin("A4", JS_WEAK_MAP_TYPE, "WeakMap", ""); +} + + +TEST(SubclassCollectionBuiltinNoInlineNew) { + FLAG_inline_new = false; + TestSubclassCollectionBuiltin(); +} + + +TEST(SubclassArrayBufferBuiltin) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + TestSubclassBuiltin("A1", JS_ARRAY_BUFFER_TYPE, "ArrayBuffer", "42"); + TestSubclassBuiltin("A2", JS_DATA_VIEW_TYPE, "DataView", + "new ArrayBuffer(42)"); +} + + +TEST(SubclassArrayBufferBuiltinNoInlineNew) { + FLAG_inline_new = false; + TestSubclassArrayBufferBuiltin(); +} + + +TEST(SubclassPromiseBuiltin) { + // Avoid eventual completion of in-object slack tracking. + FLAG_inline_construct = false; + FLAG_always_opt = false; + CcTest::InitializeVM(); + v8::HandleScope scope(CcTest::isolate()); + + const int first_field = 4; + TestSubclassBuiltin("A1", JS_PROMISE_TYPE, "Promise", + "function(resolve, reject) { resolve('ok'); }", + first_field); +} + + +TEST(SubclassPromiseBuiltinNoInlineNew) { + FLAG_inline_new = false; + TestSubclassPromiseBuiltin(); +} diff --git a/deps/v8/test/cctest/test-javascript-arm64.cc b/deps/v8/test/cctest/test-javascript-arm64.cc index cbbbf3c22a..3f7d9d17c3 100644 --- a/deps/v8/test/cctest/test-javascript-arm64.cc +++ b/deps/v8/test/cctest/test-javascript-arm64.cc @@ -34,7 +34,7 @@ #include "src/compilation-cache.h" #include "src/execution.h" #include "src/isolate.h" -#include "src/parser.h" +#include "src/parsing/parser.h" #include "src/unicode-inl.h" #include "src/utils.h" #include "test/cctest/cctest.h" @@ -43,7 +43,6 @@ using ::v8::Context; using ::v8::Extension; using ::v8::Function; using ::v8::FunctionTemplate; -using ::v8::Handle; using ::v8::HandleScope; using ::v8::Local; using ::v8::Message; @@ -59,21 +58,24 @@ using ::v8::Undefined; using ::v8::V8; using ::v8::Value; -static void ExpectBoolean(bool expected, Local<Value> result) { +static void ExpectBoolean(Local<Context> context, bool expected, + Local<Value> result) { CHECK(result->IsBoolean()); - CHECK_EQ(expected, result->BooleanValue()); + CHECK_EQ(expected, result->BooleanValue(context).FromJust()); } -static void ExpectInt32(int32_t expected, Local<Value> result) { +static void ExpectInt32(Local<Context> context, int32_t expected, + Local<Value> result) { CHECK(result->IsInt32()); - CHECK_EQ(expected, result->Int32Value()); + CHECK_EQ(expected, result->Int32Value(context).FromJust()); } -static void ExpectNumber(double expected, Local<Value> result) { +static void ExpectNumber(Local<Context> context, double expected, + Local<Value> result) { CHECK(result->IsNumber()); - CHECK_EQ(expected, result->NumberValue()); + CHECK_EQ(expected, result->NumberValue(context).FromJust()); } @@ -88,7 +90,7 @@ TEST(simple_value) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); Local<Value> result = CompileRun("0x271828;"); - ExpectInt32(0x271828, result); + ExpectInt32(env.local(), 0x271828, result); } @@ -96,7 +98,7 @@ TEST(global_variable) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); Local<Value> result = CompileRun("var my_global_var = 0x123; my_global_var;"); - ExpectInt32(0x123, result); + ExpectInt32(env.local(), 0x123, result); } @@ -106,7 +108,7 @@ TEST(simple_function_call) { Local<Value> result = CompileRun( "function foo() { return 0x314; }" "foo();"); - ExpectInt32(0x314, result); + ExpectInt32(env.local(), 0x314, result); } @@ -120,14 +122,12 @@ TEST(binary_op) { " return 2 * (a + b - 1);" "}" "foo();"); - ExpectInt32(0x2468, result); + ExpectInt32(env.local(), 0x2468, result); } -static void if_comparison_testcontext_helper( - char const * op, - char const * lhs, - char const * rhs, - int expect) { +static void if_comparison_testcontext_helper(Local<Context> context, + char const* op, char const* lhs, + char const* rhs, int expect) { char buffer[256]; snprintf(buffer, sizeof(buffer), "var lhs = %s;" @@ -136,14 +136,12 @@ static void if_comparison_testcontext_helper( "else { 0; }", lhs, rhs, op); Local<Value> result = CompileRun(buffer); - ExpectInt32(expect, result); + ExpectInt32(context, expect, result); } -static void if_comparison_effectcontext_helper( - char const * op, - char const * lhs, - char const * rhs, - int expect) { +static void if_comparison_effectcontext_helper(Local<Context> context, + char const* op, char const* lhs, + char const* rhs, int expect) { char buffer[256]; snprintf(buffer, sizeof(buffer), "var lhs = %s;" @@ -153,23 +151,21 @@ static void if_comparison_effectcontext_helper( "else { 0; }", lhs, rhs, op); Local<Value> result = CompileRun(buffer); - ExpectInt32(expect, result); + ExpectInt32(context, expect, result); } -static void if_comparison_helper( - char const * op, - int expect_when_lt, - int expect_when_eq, - int expect_when_gt) { +static void if_comparison_helper(Local<Context> context, char const* op, + int expect_when_lt, int expect_when_eq, + int expect_when_gt) { // TODO(all): Non-SMI tests. - if_comparison_testcontext_helper(op, "1", "3", expect_when_lt); - if_comparison_testcontext_helper(op, "5", "5", expect_when_eq); - if_comparison_testcontext_helper(op, "9", "7", expect_when_gt); + if_comparison_testcontext_helper(context, op, "1", "3", expect_when_lt); + if_comparison_testcontext_helper(context, op, "5", "5", expect_when_eq); + if_comparison_testcontext_helper(context, op, "9", "7", expect_when_gt); - if_comparison_effectcontext_helper(op, "1", "3", expect_when_lt); - if_comparison_effectcontext_helper(op, "5", "5", expect_when_eq); - if_comparison_effectcontext_helper(op, "9", "7", expect_when_gt); + if_comparison_effectcontext_helper(context, op, "1", "3", expect_when_lt); + if_comparison_effectcontext_helper(context, op, "5", "5", expect_when_eq); + if_comparison_effectcontext_helper(context, op, "9", "7", expect_when_gt); } @@ -177,14 +173,14 @@ TEST(if_comparison) { LocalContext env; v8::HandleScope scope(env->GetIsolate()); - if_comparison_helper("<", 1, 0, 0); - if_comparison_helper("<=", 1, 1, 0); - if_comparison_helper("==", 0, 1, 0); - if_comparison_helper("===", 0, 1, 0); - if_comparison_helper(">=", 0, 1, 1); - if_comparison_helper(">", 0, 0, 1); - if_comparison_helper("!=", 1, 0, 1); - if_comparison_helper("!==", 1, 0, 1); + if_comparison_helper(env.local(), "<", 1, 0, 0); + if_comparison_helper(env.local(), "<=", 1, 1, 0); + if_comparison_helper(env.local(), "==", 0, 1, 0); + if_comparison_helper(env.local(), "===", 0, 1, 0); + if_comparison_helper(env.local(), ">=", 0, 1, 1); + if_comparison_helper(env.local(), ">", 0, 0, 1); + if_comparison_helper(env.local(), "!=", 1, 0, 1); + if_comparison_helper(env.local(), "!==", 1, 0, 1); } @@ -194,19 +190,19 @@ TEST(unary_plus) { Local<Value> result; // SMI result = CompileRun("var a = 1234; +a"); - ExpectInt32(1234, result); + ExpectInt32(env.local(), 1234, result); // Number result = CompileRun("var a = 1234.5; +a"); - ExpectNumber(1234.5, result); + ExpectNumber(env.local(), 1234.5, result); // String (SMI) result = CompileRun("var a = '1234'; +a"); - ExpectInt32(1234, result); + ExpectInt32(env.local(), 1234, result); // String (Number) result = CompileRun("var a = '1234.5'; +a"); - ExpectNumber(1234.5, result); + ExpectNumber(env.local(), 1234.5, result); // Check side effects. result = CompileRun("var a = 1234; +(a = 4321); a"); - ExpectInt32(4321, result); + ExpectInt32(env.local(), 4321, result); } @@ -215,15 +211,15 @@ TEST(unary_minus) { v8::HandleScope scope(env->GetIsolate()); Local<Value> result; result = CompileRun("var a = 1234; -a"); - ExpectInt32(-1234, result); + ExpectInt32(env.local(), -1234, result); result = CompileRun("var a = 1234.5; -a"); - ExpectNumber(-1234.5, result); + ExpectNumber(env.local(), -1234.5, result); result = CompileRun("var a = 1234; -(a = 4321); a"); - ExpectInt32(4321, result); + ExpectInt32(env.local(), 4321, result); result = CompileRun("var a = '1234'; -a"); - ExpectInt32(-1234, result); + ExpectInt32(env.local(), -1234, result); result = CompileRun("var a = '1234.5'; -a"); - ExpectNumber(-1234.5, result); + ExpectNumber(env.local(), -1234.5, result); } @@ -234,7 +230,7 @@ TEST(unary_void) { result = CompileRun("var a = 1234; void (a);"); ExpectUndefined(result); result = CompileRun("var a = 0; void (a = 42); a"); - ExpectInt32(42, result); + ExpectInt32(env.local(), 42, result); result = CompileRun("var a = 0; void (a = 42);"); ExpectUndefined(result); } @@ -245,21 +241,21 @@ TEST(unary_not) { v8::HandleScope scope(env->GetIsolate()); Local<Value> result; result = CompileRun("var a = 1234; !a"); - ExpectBoolean(false, result); + ExpectBoolean(env.local(), false, result); result = CompileRun("var a = 0; !a"); - ExpectBoolean(true, result); + ExpectBoolean(env.local(), true, result); result = CompileRun("var a = 0; !(a = 1234); a"); - ExpectInt32(1234, result); + ExpectInt32(env.local(), 1234, result); result = CompileRun("var a = '1234'; !a"); - ExpectBoolean(false, result); + ExpectBoolean(env.local(), false, result); result = CompileRun("var a = ''; !a"); - ExpectBoolean(true, result); + ExpectBoolean(env.local(), true, result); result = CompileRun("var a = 1234; !!a"); - ExpectBoolean(true, result); + ExpectBoolean(env.local(), true, result); result = CompileRun("var a = 0; !!a"); - ExpectBoolean(false, result); + ExpectBoolean(env.local(), false, result); result = CompileRun("var a = 0; if ( !a ) { 1; } else { 0; }"); - ExpectInt32(1, result); + ExpectInt32(env.local(), 1, result); result = CompileRun("var a = 1; if ( !a ) { 1; } else { 0; }"); - ExpectInt32(0, result); + ExpectInt32(env.local(), 0, result); } diff --git a/deps/v8/test/cctest/test-js-arm64-variables.cc b/deps/v8/test/cctest/test-js-arm64-variables.cc index 98d3365b87..38b22f9b1b 100644 --- a/deps/v8/test/cctest/test-js-arm64-variables.cc +++ b/deps/v8/test/cctest/test-js-arm64-variables.cc @@ -36,7 +36,7 @@ #include "src/compilation-cache.h" #include "src/execution.h" #include "src/isolate.h" -#include "src/parser.h" +#include "src/parsing/parser.h" #include "src/unicode-inl.h" #include "src/utils.h" #include "test/cctest/cctest.h" @@ -45,7 +45,6 @@ using ::v8::Context; using ::v8::Extension; using ::v8::Function; using ::v8::FunctionTemplate; -using ::v8::Handle; using ::v8::HandleScope; using ::v8::Local; using ::v8::Message; @@ -61,9 +60,10 @@ using ::v8::Undefined; using ::v8::V8; using ::v8::Value; -static void ExpectInt32(int32_t expected, Local<Value> result) { +static void ExpectInt32(Local<Context> context, int32_t expected, + Local<Value> result) { CHECK(result->IsInt32()); - CHECK_EQ(expected, result->Int32Value()); + CHECK_EQ(expected, result->Int32Value(context).FromJust()); } @@ -75,7 +75,7 @@ TEST(global_variables) { "var x = 0;" "function f0() { return x; }" "f0();"); - ExpectInt32(0, result); + ExpectInt32(env.local(), 0, result); } @@ -86,7 +86,7 @@ TEST(parameters) { Local<Value> result = CompileRun( "function f1(x) { return x; }" "f1(1);"); - ExpectInt32(1, result); + ExpectInt32(env.local(), 1, result); } @@ -97,7 +97,7 @@ TEST(stack_allocated_locals) { Local<Value> result = CompileRun( "function f2() { var x = 2; return x; }" "f2();"); - ExpectInt32(2, result); + ExpectInt32(env.local(), 2, result); } @@ -111,7 +111,7 @@ TEST(context_allocated_locals) { " return x;" "}" "f3(3);"); - ExpectInt32(3, result); + ExpectInt32(env.local(), 3, result); } @@ -125,7 +125,7 @@ TEST(read_from_outer_context) { " return g();" "}" "f4(4);"); - ExpectInt32(4, result); + ExpectInt32(env.local(), 4, result); } @@ -138,5 +138,5 @@ TEST(lookup_slots) { " with ({}) return x;" "}" "f5(5);"); - ExpectInt32(5, result); + ExpectInt32(env.local(), 5, result); } diff --git a/deps/v8/test/cctest/test-liveedit.cc b/deps/v8/test/cctest/test-liveedit.cc index fdda3f53c6..b8cf406130 100644 --- a/deps/v8/test/cctest/test-liveedit.cc +++ b/deps/v8/test/cctest/test-liveedit.cc @@ -117,12 +117,12 @@ void CompareStringsOneWay(const char* s1, const char* s2, int similar_part_length = diff_pos1 - pos1; int diff_pos2 = pos2 + similar_part_length; - DCHECK_EQ(diff_pos2, chunk->pos2); + CHECK_EQ(diff_pos2, chunk->pos2); for (int j = 0; j < similar_part_length; j++) { - DCHECK(pos1 + j < len1); - DCHECK(pos2 + j < len2); - DCHECK_EQ(s1[pos1 + j], s2[pos2 + j]); + CHECK(pos1 + j < len1); + CHECK(pos2 + j < len2); + CHECK_EQ(s1[pos1 + j], s2[pos2 + j]); } diff_parameter += chunk->len1 + chunk->len2; pos1 = diff_pos1 + chunk->len1; @@ -131,17 +131,17 @@ void CompareStringsOneWay(const char* s1, const char* s2, { // After last chunk. int similar_part_length = len1 - pos1; - DCHECK_EQ(similar_part_length, len2 - pos2); + CHECK_EQ(similar_part_length, len2 - pos2); USE(len2); for (int j = 0; j < similar_part_length; j++) { - DCHECK(pos1 + j < len1); - DCHECK(pos2 + j < len2); - DCHECK_EQ(s1[pos1 + j], s2[pos2 + j]); + CHECK(pos1 + j < len1); + CHECK(pos2 + j < len2); + CHECK_EQ(s1[pos1 + j], s2[pos2 + j]); } } if (expected_diff_parameter != -1) { - DCHECK_EQ(expected_diff_parameter, diff_parameter); + CHECK_EQ(expected_diff_parameter, diff_parameter); } } diff --git a/deps/v8/test/cctest/test-lockers.cc b/deps/v8/test/cctest/test-lockers.cc index f1dc5a28b4..385366aa24 100644 --- a/deps/v8/test/cctest/test-lockers.cc +++ b/deps/v8/test/cctest/test-lockers.cc @@ -35,7 +35,7 @@ #include "src/compilation-cache.h" #include "src/execution.h" #include "src/isolate.h" -#include "src/parser.h" +#include "src/parsing/parser.h" #include "src/unicode-inl.h" #include "src/utils.h" #include "test/cctest/cctest.h" @@ -57,7 +57,7 @@ using ::v8::V8; // Migrating an isolate class KangarooThread : public v8::base::Thread { public: - KangarooThread(v8::Isolate* isolate, v8::Handle<v8::Context> context) + KangarooThread(v8::Isolate* isolate, v8::Local<v8::Context> context) : Thread(Options("KangarooThread")), isolate_(isolate), context_(isolate, context) {} @@ -66,15 +66,14 @@ class KangarooThread : public v8::base::Thread { { v8::Locker locker(isolate_); v8::Isolate::Scope isolate_scope(isolate_); - CHECK_EQ(reinterpret_cast<v8::internal::Isolate*>(isolate_), - v8::internal::Isolate::Current()); + CHECK_EQ(isolate_, v8::Isolate::GetCurrent()); v8::HandleScope scope(isolate_); v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); Local<Value> v = CompileRun("getValue()"); CHECK(v->IsNumber()); - CHECK_EQ(30, static_cast<int>(v->NumberValue())); + CHECK_EQ(30, static_cast<int>(v->NumberValue(context).FromJust())); } { v8::Locker locker(isolate_); @@ -85,7 +84,7 @@ class KangarooThread : public v8::base::Thread { v8::Context::Scope context_scope(context); Local<Value> v = CompileRun("getValue()"); CHECK(v->IsNumber()); - CHECK_EQ(30, static_cast<int>(v->NumberValue())); + CHECK_EQ(30, static_cast<int>(v->NumberValue(context).FromJust())); } isolate_->Dispose(); } @@ -108,8 +107,7 @@ TEST(KangarooIsolates) { v8::HandleScope handle_scope(isolate); v8::Local<v8::Context> context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); - CHECK_EQ(reinterpret_cast<v8::internal::Isolate*>(isolate), - v8::internal::Isolate::Current()); + CHECK_EQ(isolate, v8::Isolate::GetCurrent()); CompileRun("function getValue() { return 30; }"); thread1.Reset(new KangarooThread(isolate, context)); } @@ -118,14 +116,14 @@ TEST(KangarooIsolates) { } -static void CalcFibAndCheck() { +static void CalcFibAndCheck(v8::Local<v8::Context> context) { Local<Value> v = CompileRun("function fib(n) {" " if (n <= 2) return 1;" " return fib(n-1) + fib(n-2);" "}" "fib(10)"); CHECK(v->IsNumber()); - CHECK_EQ(55, static_cast<int>(v->NumberValue())); + CHECK_EQ(55, static_cast<int>(v->NumberValue(context).FromJust())); } class JoinableThread { @@ -187,9 +185,8 @@ class IsolateLockingThreadWithLocalContext : public JoinableThread { v8::Isolate::Scope isolate_scope(isolate_); v8::HandleScope handle_scope(isolate_); LocalContext local_context(isolate_); - CHECK_EQ(reinterpret_cast<v8::internal::Isolate*>(isolate_), - v8::internal::Isolate::Current()); - CalcFibAndCheck(); + CHECK_EQ(isolate_, v8::Isolate::GetCurrent()); + CalcFibAndCheck(local_context.local()); } private: v8::Isolate* isolate_; @@ -241,11 +238,11 @@ class IsolateNestedLockingThread : public JoinableThread { LocalContext local_context(isolate_); { v8::Locker another_lock(isolate_); - CalcFibAndCheck(); + CalcFibAndCheck(local_context.local()); } { v8::Locker another_lock(isolate_); - CalcFibAndCheck(); + CalcFibAndCheck(local_context.local()); } } private: @@ -289,7 +286,7 @@ class SeparateIsolatesLocksNonexclusiveThread : public JoinableThread { IsolateLockingThreadWithLocalContext threadB(isolate2_); threadB.Start(); - CalcFibAndCheck(); + CalcFibAndCheck(local_context.local()); threadB.Join(); } private: @@ -323,11 +320,10 @@ TEST(SeparateIsolatesLocksNonexclusive) { class LockIsolateAndCalculateFibSharedContextThread : public JoinableThread { public: explicit LockIsolateAndCalculateFibSharedContextThread( - v8::Isolate* isolate, v8::Handle<v8::Context> context) - : JoinableThread("LockIsolateAndCalculateFibThread"), - isolate_(isolate), - context_(isolate, context) { - } + v8::Isolate* isolate, v8::Local<v8::Context> context) + : JoinableThread("LockIsolateAndCalculateFibThread"), + isolate_(isolate), + context_(isolate, context) {} virtual void Run() { v8::Locker lock(isolate_); @@ -336,7 +332,7 @@ class LockIsolateAndCalculateFibSharedContextThread : public JoinableThread { v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); - CalcFibAndCheck(); + CalcFibAndCheck(context); } private: v8::Isolate* isolate_; @@ -351,26 +347,31 @@ class LockerUnlockerThread : public JoinableThread { } virtual void Run() { - v8::Locker lock(isolate_); - v8::Isolate::Scope isolate_scope(isolate_); - v8::HandleScope handle_scope(isolate_); - v8::Local<v8::Context> context = v8::Context::New(isolate_); + isolate_->DiscardThreadSpecificMetadata(); // No-op { - v8::Context::Scope context_scope(context); - CalcFibAndCheck(); - } - { - LockIsolateAndCalculateFibSharedContextThread thread(isolate_, context); - isolate_->Exit(); - v8::Unlocker unlocker(isolate_); - thread.Start(); - thread.Join(); - } - isolate_->Enter(); - { - v8::Context::Scope context_scope(context); - CalcFibAndCheck(); + v8::Locker lock(isolate_); + v8::Isolate::Scope isolate_scope(isolate_); + v8::HandleScope handle_scope(isolate_); + v8::Local<v8::Context> context = v8::Context::New(isolate_); + { + v8::Context::Scope context_scope(context); + CalcFibAndCheck(context); + } + { + LockIsolateAndCalculateFibSharedContextThread thread(isolate_, context); + isolate_->Exit(); + v8::Unlocker unlocker(isolate_); + thread.Start(); + thread.Join(); + } + isolate_->Enter(); + { + v8::Context::Scope context_scope(context); + CalcFibAndCheck(context); + } } + isolate_->DiscardThreadSpecificMetadata(); + isolate_->DiscardThreadSpecificMetadata(); // No-op } private: @@ -411,7 +412,7 @@ class LockTwiceAndUnlockThread : public JoinableThread { v8::Local<v8::Context> context = v8::Context::New(isolate_); { v8::Context::Scope context_scope(context); - CalcFibAndCheck(); + CalcFibAndCheck(context); } { v8::Locker second_lock(isolate_); @@ -426,7 +427,7 @@ class LockTwiceAndUnlockThread : public JoinableThread { isolate_->Enter(); { v8::Context::Scope context_scope(context); - CalcFibAndCheck(); + CalcFibAndCheck(context); } } @@ -472,10 +473,10 @@ class LockAndUnlockDifferentIsolatesThread : public JoinableThread { { v8::Isolate::Scope isolate_scope(isolate1_); v8::HandleScope handle_scope(isolate1_); - v8::Handle<v8::Context> context1 = v8::Context::New(isolate1_); + v8::Local<v8::Context> context1 = v8::Context::New(isolate1_); { v8::Context::Scope context_scope(context1); - CalcFibAndCheck(); + CalcFibAndCheck(context1); } thread.Reset(new LockIsolateAndCalculateFibSharedContextThread( isolate1_, context1)); @@ -486,17 +487,17 @@ class LockAndUnlockDifferentIsolatesThread : public JoinableThread { { v8::Isolate::Scope isolate_scope(isolate2_); v8::HandleScope handle_scope(isolate2_); - v8::Handle<v8::Context> context2 = v8::Context::New(isolate2_); + v8::Local<v8::Context> context2 = v8::Context::New(isolate2_); { v8::Context::Scope context_scope(context2); - CalcFibAndCheck(); + CalcFibAndCheck(context2); } v8::Unlocker unlock1(isolate1_); CHECK(!v8::Locker::IsLocked(isolate1_)); CHECK(v8::Locker::IsLocked(isolate2_)); v8::Context::Scope context_scope(context2); thread->Start(); - CalcFibAndCheck(); + CalcFibAndCheck(context2); thread->Join(); } } @@ -522,11 +523,10 @@ TEST(LockAndUnlockDifferentIsolates) { class LockUnlockLockThread : public JoinableThread { public: - LockUnlockLockThread(v8::Isolate* isolate, v8::Handle<v8::Context> context) - : JoinableThread("LockUnlockLockThread"), - isolate_(isolate), - context_(isolate, context) { - } + LockUnlockLockThread(v8::Isolate* isolate, v8::Local<v8::Context> context) + : JoinableThread("LockUnlockLockThread"), + isolate_(isolate), + context_(isolate, context) {} virtual void Run() { v8::Locker lock1(isolate_); @@ -538,7 +538,7 @@ class LockUnlockLockThread : public JoinableThread { v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); - CalcFibAndCheck(); + CalcFibAndCheck(context); } { v8::Unlocker unlock1(isolate_); @@ -553,7 +553,7 @@ class LockUnlockLockThread : public JoinableThread { v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); - CalcFibAndCheck(); + CalcFibAndCheck(context); } } } @@ -579,7 +579,7 @@ TEST(LockUnlockLockMultithreaded) { v8::Locker locker_(isolate); v8::Isolate::Scope isolate_scope(isolate); v8::HandleScope handle_scope(isolate); - v8::Handle<v8::Context> context = v8::Context::New(isolate); + v8::Local<v8::Context> context = v8::Context::New(isolate); for (int i = 0; i < kNThreads; i++) { threads.Add(new LockUnlockLockThread( isolate, context)); @@ -591,7 +591,7 @@ TEST(LockUnlockLockMultithreaded) { class LockUnlockLockDefaultIsolateThread : public JoinableThread { public: - explicit LockUnlockLockDefaultIsolateThread(v8::Handle<v8::Context> context) + explicit LockUnlockLockDefaultIsolateThread(v8::Local<v8::Context> context) : JoinableThread("LockUnlockLockDefaultIsolateThread"), context_(CcTest::isolate(), context) {} @@ -603,7 +603,7 @@ class LockUnlockLockDefaultIsolateThread : public JoinableThread { v8::Local<v8::Context> context = v8::Local<v8::Context>::New(CcTest::isolate(), context_); v8::Context::Scope context_scope(context); - CalcFibAndCheck(); + CalcFibAndCheck(context); } { v8::Unlocker unlock1(CcTest::isolate()); @@ -614,7 +614,7 @@ class LockUnlockLockDefaultIsolateThread : public JoinableThread { v8::Local<v8::Context> context = v8::Local<v8::Context>::New(CcTest::isolate(), context_); v8::Context::Scope context_scope(context); - CalcFibAndCheck(); + CalcFibAndCheck(context); } } } @@ -655,11 +655,12 @@ TEST(Regress1433) { v8::Locker lock(isolate); v8::Isolate::Scope isolate_scope(isolate); v8::HandleScope handle_scope(isolate); - v8::Handle<Context> context = v8::Context::New(isolate); + v8::Local<Context> context = v8::Context::New(isolate); v8::Context::Scope context_scope(context); - v8::Handle<String> source = v8::String::NewFromUtf8(isolate, "1+1"); - v8::Handle<Script> script = v8::Script::Compile(source); - v8::Handle<Value> result = script->Run(); + v8::Local<String> source = v8_str("1+1"); + v8::Local<Script> script = + v8::Script::Compile(context, source).ToLocalChecked(); + v8::Local<Value> result = script->Run(context).ToLocalChecked(); v8::String::Utf8Value utf8(result); } isolate->Dispose(); @@ -686,11 +687,12 @@ class IsolateGenesisThread : public JoinableThread { v8::Isolate* isolate = v8::Isolate::New(create_params); { v8::Isolate::Scope isolate_scope(isolate); - CHECK(!i::Isolate::Current()->has_installed_extensions()); + CHECK( + !reinterpret_cast<i::Isolate*>(isolate)->has_installed_extensions()); v8::ExtensionConfiguration extensions(count_, extension_names_); v8::HandleScope handle_scope(isolate); v8::Context::New(isolate, &extensions); - CHECK(i::Isolate::Current()->has_installed_extensions()); + CHECK(reinterpret_cast<i::Isolate*>(isolate)->has_installed_extensions()); } isolate->Dispose(); } diff --git a/deps/v8/test/cctest/test-log-stack-tracer.cc b/deps/v8/test/cctest/test-log-stack-tracer.cc index b9147f82e1..7254ee084f 100644 --- a/deps/v8/test/cctest/test-log-stack-tracer.cc +++ b/deps/v8/test/cctest/test-log-stack-tracer.cc @@ -65,7 +65,8 @@ static bool IsAddressWithinFuncCode(JSFunction* function, Address addr) { static bool IsAddressWithinFuncCode(v8::Local<v8::Context> context, const char* func_name, Address addr) { - v8::Local<v8::Value> func = context->Global()->Get(v8_str(func_name)); + v8::Local<v8::Value> func = + context->Global()->Get(context, v8_str(func_name)).ToLocalChecked(); CHECK(func->IsFunction()); JSFunction* js_func = JSFunction::cast(*v8::Utils::OpenHandle(*func)); return IsAddressWithinFuncCode(js_func, addr); @@ -85,15 +86,18 @@ static void construct_call(const v8::FunctionCallbackInfo<v8::Value>& args) { i::StackFrame* calling_frame = frame_iterator.frame(); CHECK(calling_frame->is_java_script()); + v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); #if defined(V8_HOST_ARCH_32_BIT) int32_t low_bits = reinterpret_cast<int32_t>(calling_frame->fp()); - args.This()->Set(v8_str("low_bits"), v8_num(low_bits >> 1)); + args.This() + ->Set(context, v8_str("low_bits"), v8_num(low_bits >> 1)) + .FromJust(); #elif defined(V8_HOST_ARCH_64_BIT) uint64_t fp = reinterpret_cast<uint64_t>(calling_frame->fp()); int32_t low_bits = static_cast<int32_t>(fp & 0xffffffff); int32_t high_bits = static_cast<int32_t>(fp >> 32); - args.This()->Set(v8_str("low_bits"), v8_num(low_bits)); - args.This()->Set(v8_str("high_bits"), v8_num(high_bits)); + args.This()->Set(context, v8_str("low_bits"), v8_num(low_bits)).FromJust(); + args.This()->Set(context, v8_str("high_bits"), v8_num(high_bits)).FromJust(); #else #error Host architecture is neither 32-bit nor 64-bit. #endif @@ -107,8 +111,9 @@ void CreateFramePointerGrabberConstructor(v8::Local<v8::Context> context, Local<v8::FunctionTemplate> constructor_template = v8::FunctionTemplate::New(context->GetIsolate(), construct_call); constructor_template->SetClassName(v8_str("FPGrabber")); - Local<Function> fun = constructor_template->GetFunction(); - context->Global()->Set(v8_str(constructor_name), fun); + Local<Function> fun = + constructor_template->GetFunction(context).ToLocalChecked(); + context->Global()->Set(context, v8_str(constructor_name), fun).FromJust(); } diff --git a/deps/v8/test/cctest/test-log.cc b/deps/v8/test/cctest/test-log.cc index 925803cc15..adbd1a5a37 100644 --- a/deps/v8/test/cctest/test-log.cc +++ b/deps/v8/test/cctest/test-log.cc @@ -85,7 +85,7 @@ class ScopedLoggerInitializer { i::FLAG_log = saved_log_; } - v8::Handle<v8::Context>& env() { return env_; } + v8::Local<v8::Context>& env() { return env_; } v8::Isolate* isolate() { return isolate_; } @@ -106,7 +106,7 @@ class ScopedLoggerInitializer { v8::Isolate* isolate_; v8::Isolate::Scope isolate_scope_; v8::HandleScope scope_; - v8::Handle<v8::Context> env_; + v8::Local<v8::Context> env_; Logger* logger_; DISALLOW_COPY_AND_ASSIGN(ScopedLoggerInitializer); @@ -307,18 +307,21 @@ class SimpleExternalString : public v8::String::ExternalStringResource { TEST(Issue23768) { v8::HandleScope scope(CcTest::isolate()); - v8::Handle<v8::Context> env = v8::Context::New(CcTest::isolate()); + v8::Local<v8::Context> env = v8::Context::New(CcTest::isolate()); env->Enter(); SimpleExternalString source_ext_str("(function ext() {})();"); v8::Local<v8::String> source = - v8::String::NewExternal(CcTest::isolate(), &source_ext_str); + v8::String::NewExternalTwoByte(CcTest::isolate(), &source_ext_str) + .ToLocalChecked(); // Script needs to have a name in order to trigger InitLineEnds execution. - v8::Handle<v8::String> origin = - v8::String::NewFromUtf8(CcTest::isolate(), "issue-23768-test"); - v8::Handle<v8::Script> evil_script = CompileWithOrigin(source, origin); + v8::Local<v8::String> origin = + v8::String::NewFromUtf8(CcTest::isolate(), "issue-23768-test", + v8::NewStringType::kNormal) + .ToLocalChecked(); + v8::Local<v8::Script> evil_script = CompileWithOrigin(source, origin); CHECK(!evil_script.IsEmpty()); - CHECK(!evil_script->Run().IsEmpty()); + CHECK(!evil_script->Run(env).IsEmpty()); i::Handle<i::ExternalTwoByteString> i_source( i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source))); // This situation can happen if source was an external string disposed @@ -346,14 +349,18 @@ TEST(LogCallbacks) { v8::Local<v8::FunctionTemplate> obj = v8::Local<v8::FunctionTemplate>::New( isolate, v8::FunctionTemplate::New(isolate)); obj->SetClassName(v8_str("Obj")); - v8::Handle<v8::ObjectTemplate> proto = obj->PrototypeTemplate(); + v8::Local<v8::ObjectTemplate> proto = obj->PrototypeTemplate(); v8::Local<v8::Signature> signature = v8::Signature::New(isolate, obj); proto->Set(v8_str("method1"), v8::FunctionTemplate::New(isolate, ObjMethod1, - v8::Handle<v8::Value>(), signature), + v8::Local<v8::Value>(), signature), static_cast<v8::PropertyAttribute>(v8::DontDelete)); - initialize_logger.env()->Global()->Set(v8_str("Obj"), obj->GetFunction()); + initialize_logger.env() + ->Global() + ->Set(initialize_logger.env(), v8_str("Obj"), + obj->GetFunction(initialize_logger.env()).ToLocalChecked()) + .FromJust(); CompileRun("Obj.prototype.method1.toString();"); logger->LogCompiledFunctions(); @@ -401,7 +408,7 @@ TEST(LogAccessorCallbacks) { v8::Local<v8::FunctionTemplate> obj = v8::Local<v8::FunctionTemplate>::New( isolate, v8::FunctionTemplate::New(isolate)); obj->SetClassName(v8_str("Obj")); - v8::Handle<v8::ObjectTemplate> inst = obj->InstanceTemplate(); + v8::Local<v8::ObjectTemplate> inst = obj->InstanceTemplate(); inst->SetAccessor(v8_str("prop1"), Prop1Getter, Prop1Setter); inst->SetAccessor(v8_str("prop2"), Prop2Getter); @@ -475,29 +482,37 @@ TEST(EquivalenceOfLoggingAndTraversal) { i::Vector<const char> log( i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true)); CHECK(exists); - v8::Handle<v8::String> log_str = v8::String::NewFromUtf8( - isolate, log.start(), v8::String::kNormalString, log.length()); - initialize_logger.env()->Global()->Set(v8_str("_log"), log_str); + v8::Local<v8::String> log_str = + v8::String::NewFromUtf8(isolate, log.start(), + v8::NewStringType::kNormal, log.length()) + .ToLocalChecked(); + initialize_logger.env() + ->Global() + ->Set(initialize_logger.env(), v8_str("_log"), log_str) + .FromJust(); i::Vector<const char> source = TestSources::GetScriptsSource(); - v8::Handle<v8::String> source_str = v8::String::NewFromUtf8( - isolate, source.start(), v8::String::kNormalString, source.length()); + v8::Local<v8::String> source_str = + v8::String::NewFromUtf8(isolate, source.start(), + v8::NewStringType::kNormal, source.length()) + .ToLocalChecked(); v8::TryCatch try_catch(isolate); - v8::Handle<v8::Script> script = CompileWithOrigin(source_str, ""); + v8::Local<v8::Script> script = CompileWithOrigin(source_str, ""); if (script.IsEmpty()) { v8::String::Utf8Value exception(try_catch.Exception()); printf("compile: %s\n", *exception); CHECK(false); } - v8::Handle<v8::Value> result = script->Run(); - if (result.IsEmpty()) { + v8::Local<v8::Value> result; + if (!script->Run(initialize_logger.env()).ToLocal(&result)) { v8::String::Utf8Value exception(try_catch.Exception()); printf("run: %s\n", *exception); CHECK(false); } // The result either be a "true" literal or problem description. if (!result->IsTrue()) { - v8::Local<v8::String> s = result->ToString(isolate); + v8::Local<v8::String> s = + result->ToString(initialize_logger.env()).ToLocalChecked(); i::ScopedVector<char> data(s->Utf8Length() + 1); CHECK(data.start()); s->WriteUtf8(data.start()); diff --git a/deps/v8/test/cctest/test-macro-assembler-arm.cc b/deps/v8/test/cctest/test-macro-assembler-arm.cc index b655fc80f9..24ab60e972 100644 --- a/deps/v8/test/cctest/test-macro-assembler-arm.cc +++ b/deps/v8/test/cctest/test-macro-assembler-arm.cc @@ -61,7 +61,7 @@ static bool all_zeroes(const byte* beg, const byte* end) { TEST(CopyBytes) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); const int data_size = 1 * KB; @@ -81,7 +81,8 @@ TEST(CopyBytes) { byte* r0_; byte* r1_; - MacroAssembler assembler(isolate, NULL, 0); + MacroAssembler assembler(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; // Code to be generated: The stuff in CopyBytes followed by a store of R0 and @@ -112,8 +113,8 @@ TEST(CopyBytes) { for (byte* dest = dest_buffer; dest < dest_buffer + fuzz; dest++) { memset(dest_buffer, 0, data_size); CHECK(dest + size < dest_buffer + data_size); - (void) CALL_GENERATED_CODE(f, reinterpret_cast<int>(src), - reinterpret_cast<int>(dest), size, 0, 0); + (void)CALL_GENERATED_CODE(isolate, f, reinterpret_cast<int>(src), + reinterpret_cast<int>(dest), size, 0, 0); // R0 and R1 should point at the first byte after the copied data. CHECK_EQ(src + size, r0_); CHECK_EQ(dest + size, r1_); @@ -144,7 +145,8 @@ TEST(LoadAndStoreWithRepresentation) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. __ sub(sp, sp, Operand(1 * kPointerSize)); Label exit; @@ -221,7 +223,7 @@ TEST(LoadAndStoreWithRepresentation) { // Call the function from C++. F5 f = FUNCTION_CAST<F5>(code->entry()); - CHECK(!CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0)); + CHECK(!CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); } #undef __ diff --git a/deps/v8/test/cctest/test-macro-assembler-ia32.cc b/deps/v8/test/cctest/test-macro-assembler-ia32.cc index 3834b18798..829ada3a61 100644 --- a/deps/v8/test/cctest/test-macro-assembler-ia32.cc +++ b/deps/v8/test/cctest/test-macro-assembler-ia32.cc @@ -56,7 +56,8 @@ TEST(LoadAndStoreWithRepresentation) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. __ push(ebx); __ push(edx); diff --git a/deps/v8/test/cctest/test-macro-assembler-mips.cc b/deps/v8/test/cctest/test-macro-assembler-mips.cc index 515bac9d3a..696ca010ca 100644 --- a/deps/v8/test/cctest/test-macro-assembler-mips.cc +++ b/deps/v8/test/cctest/test-macro-assembler-mips.cc @@ -62,7 +62,7 @@ static bool all_zeroes(const byte* beg, const byte* end) { TEST(CopyBytes) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); const int data_size = 1 * KB; @@ -82,7 +82,8 @@ TEST(CopyBytes) { byte* a0_; byte* a1_; - MacroAssembler assembler(isolate, NULL, 0); + MacroAssembler assembler(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; // Code to be generated: The stuff in CopyBytes followed by a store of a0 and @@ -113,8 +114,8 @@ TEST(CopyBytes) { for (byte* dest = dest_buffer; dest < dest_buffer + fuzz; dest++) { memset(dest_buffer, 0, data_size); CHECK(dest + size < dest_buffer + data_size); - (void) CALL_GENERATED_CODE(f, reinterpret_cast<int>(src), - reinterpret_cast<int>(dest), size, 0, 0); + (void)CALL_GENERATED_CODE(isolate, f, reinterpret_cast<int>(src), + reinterpret_cast<int>(dest), size, 0, 0); // a0 and a1 should point at the first byte after the copied data. CHECK_EQ(src + size, a0_); CHECK_EQ(dest + size, a1_); @@ -142,11 +143,11 @@ static void TestNaN(const char *code) { v8::Local<v8::Context> context = CcTest::NewContext(PRINT_EXTENSION); v8::Context::Scope context_scope(context); - v8::Local<v8::Script> script = v8::Script::Compile(v8_str(code)); - v8::Local<v8::Object> result = v8::Local<v8::Object>::Cast(script->Run()); - // Have to populate the handle manually, as it's not Cast-able. - i::Handle<i::JSObject> o = - v8::Utils::OpenHandle<v8::Object, i::JSObject>(result); + v8::Local<v8::Script> script = + v8::Script::Compile(context, v8_str(code)).ToLocalChecked(); + v8::Local<v8::Object> result = + v8::Local<v8::Object>::Cast(script->Run(context).ToLocalChecked()); + i::Handle<i::JSReceiver> o = v8::Utils::OpenHandle(*result); i::Handle<i::JSArray> array1(reinterpret_cast<i::JSArray*>(*o)); i::FixedDoubleArray* a = i::FixedDoubleArray::cast(array1->elements()); double value = a->get_scalar(0); @@ -184,7 +185,8 @@ TEST(jump_tables4) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assembler(isolate, NULL, 0); + MacroAssembler assembler(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; const int kNumCases = 512; @@ -251,11 +253,164 @@ TEST(jump_tables4) { #endif F1 f = FUNCTION_CAST<F1>(code->entry()); for (int i = 0; i < kNumCases; ++i) { - int res = reinterpret_cast<int>(CALL_GENERATED_CODE(f, i, 0, 0, 0, 0)); + int res = + reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0)); + ::printf("f(%d) = %d\n", i, res); + CHECK_EQ(values[i], res); + } +} + + +TEST(jump_tables5) { + if (!IsMipsArchVariant(kMips32r6)) return; + + // Similar to test-assembler-mips jump_tables1, with extra test for emitting a + // compact branch instruction before emission of the dd table. + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + MacroAssembler assembler(isolate, nullptr, 0, + v8::internal::CodeObjectRequired::kYes); + MacroAssembler* masm = &assembler; + + const int kNumCases = 512; + int values[kNumCases]; + isolate->random_number_generator()->NextBytes(values, sizeof(values)); + Label labels[kNumCases]; + Label done; + + __ addiu(sp, sp, -4); + __ sw(ra, MemOperand(sp)); + + { + __ BlockTrampolinePoolFor(kNumCases * 2 + 7 + 1); + PredictableCodeSizeScope predictable( + masm, kNumCases * kPointerSize + ((7 + 1) * Assembler::kInstrSize)); + Label here; + + __ bal(&here); + __ sll(at, a0, 2); // In delay slot. + __ bind(&here); + __ addu(at, at, ra); + __ lw(at, MemOperand(at, 6 * Assembler::kInstrSize)); + __ jalr(at); + __ nop(); // Branch delay slot nop. + __ bc(&done); + for (int i = 0; i < kNumCases; ++i) { + __ dd(&labels[i]); + } + } + + for (int i = 0; i < kNumCases; ++i) { + __ bind(&labels[i]); + __ lui(v0, (values[i] >> 16) & 0xffff); + __ ori(v0, v0, values[i] & 0xffff); + __ jr(ra); + __ nop(); + } + + __ bind(&done); + __ lw(ra, MemOperand(sp)); + __ addiu(sp, sp, 4); + __ jr(ra); + __ nop(); + + CodeDesc desc; + masm->GetCode(&desc); + Handle<Code> code = isolate->factory()->NewCode( + desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); +#ifdef OBJECT_PRINT + code->Print(std::cout); +#endif + F1 f = FUNCTION_CAST<F1>(code->entry()); + for (int i = 0; i < kNumCases; ++i) { + int32_t res = reinterpret_cast<int32_t>( + CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0)); ::printf("f(%d) = %d\n", i, res); CHECK_EQ(values[i], res); } } +static uint32_t run_lsa(uint32_t rt, uint32_t rs, int8_t sa) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + MacroAssembler assembler(isolate, nullptr, 0, + v8::internal::CodeObjectRequired::kYes); + MacroAssembler* masm = &assembler; + + __ Lsa(v0, a0, a1, sa); + __ jr(ra); + __ nop(); + + CodeDesc desc; + assembler.GetCode(&desc); + Handle<Code> code = isolate->factory()->NewCode( + desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); + + F1 f = FUNCTION_CAST<F1>(code->entry()); + + uint32_t res = reinterpret_cast<uint32_t>( + CALL_GENERATED_CODE(isolate, f, rt, rs, 0, 0, 0)); + + return res; +} + + +TEST(Lsa) { + CcTest::InitializeVM(); + struct TestCaseLsa { + int32_t rt; + int32_t rs; + uint8_t sa; + uint32_t expected_res; + }; + + struct TestCaseLsa tc[] = {// rt, rs, sa, expected_res + {0x4, 0x1, 1, 0x6}, + {0x4, 0x1, 2, 0x8}, + {0x4, 0x1, 3, 0xc}, + {0x4, 0x1, 4, 0x14}, + {0x4, 0x1, 5, 0x24}, + {0x0, 0x1, 1, 0x2}, + {0x0, 0x1, 2, 0x4}, + {0x0, 0x1, 3, 0x8}, + {0x0, 0x1, 4, 0x10}, + {0x0, 0x1, 5, 0x20}, + {0x4, 0x0, 1, 0x4}, + {0x4, 0x0, 2, 0x4}, + {0x4, 0x0, 3, 0x4}, + {0x4, 0x0, 4, 0x4}, + {0x4, 0x0, 5, 0x4}, + + // Shift overflow. + {0x4, INT32_MAX, 1, 0x2}, + {0x4, INT32_MAX >> 1, 2, 0x0}, + {0x4, INT32_MAX >> 2, 3, 0xfffffffc}, + {0x4, INT32_MAX >> 3, 4, 0xfffffff4}, + {0x4, INT32_MAX >> 4, 5, 0xffffffe4}, + + // Signed addition overflow. + {INT32_MAX - 1, 0x1, 1, 0x80000000}, + {INT32_MAX - 3, 0x1, 2, 0x80000000}, + {INT32_MAX - 7, 0x1, 3, 0x80000000}, + {INT32_MAX - 15, 0x1, 4, 0x80000000}, + {INT32_MAX - 31, 0x1, 5, 0x80000000}, + + // Addition overflow. + {-2, 0x1, 1, 0x0}, + {-4, 0x1, 2, 0x0}, + {-8, 0x1, 3, 0x0}, + {-16, 0x1, 4, 0x0}, + {-32, 0x1, 5, 0x0}}; + + size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa); + for (size_t i = 0; i < nr_test_cases; ++i) { + uint32_t res = run_lsa(tc[i].rt, tc[i].rs, tc[i].sa); + PrintF("0x%x =? 0x%x == lsa(v0, %x, %x, %hhu)\n", tc[i].expected_res, res, + tc[i].rt, tc[i].rs, tc[i].sa); + CHECK_EQ(tc[i].expected_res, res); + } +} + #undef __ diff --git a/deps/v8/test/cctest/test-macro-assembler-mips64.cc b/deps/v8/test/cctest/test-macro-assembler-mips64.cc index fadd45f43b..684b554236 100644 --- a/deps/v8/test/cctest/test-macro-assembler-mips64.cc +++ b/deps/v8/test/cctest/test-macro-assembler-mips64.cc @@ -63,7 +63,7 @@ static bool all_zeroes(const byte* beg, const byte* end) { TEST(CopyBytes) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); const int data_size = 1 * KB; @@ -83,7 +83,8 @@ TEST(CopyBytes) { byte* a0_; byte* a1_; - MacroAssembler assembler(isolate, NULL, 0); + MacroAssembler assembler(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; // Code to be generated: The stuff in CopyBytes followed by a store of a0 and @@ -114,9 +115,8 @@ TEST(CopyBytes) { for (byte* dest = dest_buffer; dest < dest_buffer + fuzz; dest++) { memset(dest_buffer, 0, data_size); CHECK(dest + size < dest_buffer + data_size); - (void) CALL_GENERATED_CODE(f, reinterpret_cast<int64_t>(src), - reinterpret_cast<int64_t>(dest), - size, 0, 0); + (void)CALL_GENERATED_CODE(isolate, f, reinterpret_cast<int64_t>(src), + reinterpret_cast<int64_t>(dest), size, 0, 0); // a0 and a1 should point at the first byte after the copied data. CHECK_EQ(src + size, a0_); CHECK_EQ(dest + size, a1_); @@ -138,7 +138,7 @@ TEST(CopyBytes) { TEST(LoadConstants) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); int64_t refConstants[64]; @@ -149,7 +149,8 @@ TEST(LoadConstants) { refConstants[i] = ~(mask << i); } - MacroAssembler assembler(isolate, NULL, 0); + MacroAssembler assembler(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; __ mov(a4, a0); @@ -169,8 +170,8 @@ TEST(LoadConstants) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); ::F f = FUNCTION_CAST< ::F>(code->entry()); - (void) CALL_GENERATED_CODE(f, reinterpret_cast<int64_t>(result), - 0, 0, 0, 0); + (void)CALL_GENERATED_CODE(isolate, f, reinterpret_cast<int64_t>(result), 0, 0, + 0, 0); // Check results. for (int i = 0; i < 64; i++) { CHECK(refConstants[i] == result[i]); @@ -180,10 +181,11 @@ TEST(LoadConstants) { TEST(LoadAddress) { CcTest::InitializeVM(); - Isolate* isolate = Isolate::Current(); + Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, NULL, 0); + MacroAssembler assembler(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; Label to_jump, skip; __ mov(a4, a0); @@ -213,7 +215,7 @@ TEST(LoadAddress) { desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); ::F f = FUNCTION_CAST< ::F>(code->entry()); - (void) CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0); + (void)CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0); // Check results. } @@ -226,7 +228,8 @@ TEST(jump_tables4) { CcTest::InitializeVM(); Isolate* isolate = CcTest::i_isolate(); HandleScope scope(isolate); - MacroAssembler assembler(isolate, NULL, 0); + MacroAssembler assembler(isolate, NULL, 0, + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; const int kNumCases = 512; @@ -237,9 +240,6 @@ TEST(jump_tables4) { __ daddiu(sp, sp, -8); __ sd(ra, MemOperand(sp)); - if ((masm->pc_offset() & 7) == 0) { - __ nop(); - } __ mov(v0, zero_reg); @@ -252,6 +252,7 @@ TEST(jump_tables4) { __ addiu(v0, v0, 1); } + __ Align(8); Label done; { __ BlockTrampolinePoolFor(kNumCases * 2 + 6); @@ -296,11 +297,251 @@ TEST(jump_tables4) { #endif F1 f = FUNCTION_CAST<F1>(code->entry()); for (int i = 0; i < kNumCases; ++i) { - int64_t res = - reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, i, 0, 0, 0, 0)); + int64_t res = reinterpret_cast<int64_t>( + CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0)); ::printf("f(%d) = %" PRId64 "\n", i, res); CHECK_EQ(values[i], res); } } + +TEST(jump_tables5) { + if (kArchVariant != kMips64r6) return; + + // Similar to test-assembler-mips jump_tables1, with extra test for emitting a + // compact branch instruction before emission of the dd table. + CcTest::InitializeVM(); + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + MacroAssembler assembler(isolate, nullptr, 0, + v8::internal::CodeObjectRequired::kYes); + MacroAssembler* masm = &assembler; + + const int kNumCases = 512; + int values[kNumCases]; + isolate->random_number_generator()->NextBytes(values, sizeof(values)); + Label labels[kNumCases]; + Label done; + + __ daddiu(sp, sp, -8); + __ sd(ra, MemOperand(sp)); + + __ Align(8); + { + __ BlockTrampolinePoolFor(kNumCases * 2 + 7 + 1); + PredictableCodeSizeScope predictable( + masm, kNumCases * kPointerSize + ((7 + 1) * Assembler::kInstrSize)); + Label here; + + __ bal(&here); + __ dsll(at, a0, 3); // In delay slot. + __ bind(&here); + __ daddu(at, at, ra); + __ ld(at, MemOperand(at, 6 * Assembler::kInstrSize)); + __ jalr(at); + __ nop(); // Branch delay slot nop. + __ bc(&done); + // A nop instruction must be generated by the forbidden slot guard + // (Assembler::dd(Label*)) so the first label goes to an 8 bytes aligned + // location. + for (int i = 0; i < kNumCases; ++i) { + __ dd(&labels[i]); + } + } + + for (int i = 0; i < kNumCases; ++i) { + __ bind(&labels[i]); + __ lui(v0, (values[i] >> 16) & 0xffff); + __ ori(v0, v0, values[i] & 0xffff); + __ jr(ra); + __ nop(); + } + + __ bind(&done); + __ ld(ra, MemOperand(sp)); + __ daddiu(sp, sp, 8); + __ jr(ra); + __ nop(); + + CodeDesc desc; + masm->GetCode(&desc); + Handle<Code> code = isolate->factory()->NewCode( + desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); +#ifdef OBJECT_PRINT + code->Print(std::cout); +#endif + F1 f = FUNCTION_CAST<F1>(code->entry()); + for (int i = 0; i < kNumCases; ++i) { + int64_t res = reinterpret_cast<int64_t>( + CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0)); + ::printf("f(%d) = %" PRId64 "\n", i, res); + CHECK_EQ(values[i], res); + } +} + + +static uint64_t run_lsa(uint32_t rt, uint32_t rs, int8_t sa) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + MacroAssembler assembler(isolate, nullptr, 0, + v8::internal::CodeObjectRequired::kYes); + MacroAssembler* masm = &assembler; + + __ Lsa(v0, a0, a1, sa); + __ jr(ra); + __ nop(); + + CodeDesc desc; + assembler.GetCode(&desc); + Handle<Code> code = isolate->factory()->NewCode( + desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); + + F1 f = FUNCTION_CAST<F1>(code->entry()); + + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, rt, rs, 0, 0, 0)); + + return res; +} + + +TEST(Lsa) { + CcTest::InitializeVM(); + struct TestCaseLsa { + int32_t rt; + int32_t rs; + uint8_t sa; + uint64_t expected_res; + }; + + struct TestCaseLsa tc[] = {// rt, rs, sa, expected_res + {0x4, 0x1, 1, 0x6}, + {0x4, 0x1, 2, 0x8}, + {0x4, 0x1, 3, 0xc}, + {0x4, 0x1, 4, 0x14}, + {0x4, 0x1, 5, 0x24}, + {0x0, 0x1, 1, 0x2}, + {0x0, 0x1, 2, 0x4}, + {0x0, 0x1, 3, 0x8}, + {0x0, 0x1, 4, 0x10}, + {0x0, 0x1, 5, 0x20}, + {0x4, 0x0, 1, 0x4}, + {0x4, 0x0, 2, 0x4}, + {0x4, 0x0, 3, 0x4}, + {0x4, 0x0, 4, 0x4}, + {0x4, 0x0, 5, 0x4}, + + // Shift overflow. + {0x4, INT32_MAX, 1, 0x2}, + {0x4, INT32_MAX >> 1, 2, 0x0}, + {0x4, INT32_MAX >> 2, 3, 0xfffffffffffffffc}, + {0x4, INT32_MAX >> 3, 4, 0xfffffffffffffff4}, + {0x4, INT32_MAX >> 4, 5, 0xffffffffffffffe4}, + + // Signed addition overflow. + {INT32_MAX - 1, 0x1, 1, 0xffffffff80000000}, + {INT32_MAX - 3, 0x1, 2, 0xffffffff80000000}, + {INT32_MAX - 7, 0x1, 3, 0xffffffff80000000}, + {INT32_MAX - 15, 0x1, 4, 0xffffffff80000000}, + {INT32_MAX - 31, 0x1, 5, 0xffffffff80000000}, + + // Addition overflow. + {-2, 0x1, 1, 0x0}, + {-4, 0x1, 2, 0x0}, + {-8, 0x1, 3, 0x0}, + {-16, 0x1, 4, 0x0}, + {-32, 0x1, 5, 0x0}}; + + size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa); + for (size_t i = 0; i < nr_test_cases; ++i) { + uint64_t res = run_lsa(tc[i].rt, tc[i].rs, tc[i].sa); + PrintF("0x%" PRIx64 " =? 0x%" PRIx64 " == Lsa(v0, %x, %x, %hhu)\n", + tc[i].expected_res, res, tc[i].rt, tc[i].rs, tc[i].sa); + CHECK_EQ(tc[i].expected_res, res); + } +} + + +static uint64_t run_dlsa(uint64_t rt, uint64_t rs, int8_t sa) { + Isolate* isolate = CcTest::i_isolate(); + HandleScope scope(isolate); + MacroAssembler assembler(isolate, nullptr, 0, + v8::internal::CodeObjectRequired::kYes); + MacroAssembler* masm = &assembler; + + __ Dlsa(v0, a0, a1, sa); + __ jr(ra); + __ nop(); + + CodeDesc desc; + assembler.GetCode(&desc); + Handle<Code> code = isolate->factory()->NewCode( + desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); + + ::F f = FUNCTION_CAST<::F>(code->entry()); + + uint64_t res = reinterpret_cast<uint64_t>( + CALL_GENERATED_CODE(isolate, f, rt, rs, 0, 0, 0)); + + return res; +} + + +TEST(Dlsa) { + CcTest::InitializeVM(); + struct TestCaseLsa { + int64_t rt; + int64_t rs; + uint8_t sa; + uint64_t expected_res; + }; + + struct TestCaseLsa tc[] = {// rt, rs, sa, expected_res + {0x4, 0x1, 1, 0x6}, + {0x4, 0x1, 2, 0x8}, + {0x4, 0x1, 3, 0xc}, + {0x4, 0x1, 4, 0x14}, + {0x4, 0x1, 5, 0x24}, + {0x0, 0x1, 1, 0x2}, + {0x0, 0x1, 2, 0x4}, + {0x0, 0x1, 3, 0x8}, + {0x0, 0x1, 4, 0x10}, + {0x0, 0x1, 5, 0x20}, + {0x4, 0x0, 1, 0x4}, + {0x4, 0x0, 2, 0x4}, + {0x4, 0x0, 3, 0x4}, + {0x4, 0x0, 4, 0x4}, + {0x4, 0x0, 5, 0x4}, + + // Shift overflow. + {0x4, INT64_MAX, 1, 0x2}, + {0x4, INT64_MAX >> 1, 2, 0x0}, + {0x4, INT64_MAX >> 2, 3, 0xfffffffffffffffc}, + {0x4, INT64_MAX >> 3, 4, 0xfffffffffffffff4}, + {0x4, INT64_MAX >> 4, 5, 0xffffffffffffffe4}, + + // Signed addition overflow. + {INT64_MAX - 1, 0x1, 1, 0x8000000000000000}, + {INT64_MAX - 3, 0x1, 2, 0x8000000000000000}, + {INT64_MAX - 7, 0x1, 3, 0x8000000000000000}, + {INT64_MAX - 15, 0x1, 4, 0x8000000000000000}, + {INT64_MAX - 31, 0x1, 5, 0x8000000000000000}, + + // Addition overflow. + {-2, 0x1, 1, 0x0}, + {-4, 0x1, 2, 0x0}, + {-8, 0x1, 3, 0x0}, + {-16, 0x1, 4, 0x0}, + {-32, 0x1, 5, 0x0}}; + + size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa); + for (size_t i = 0; i < nr_test_cases; ++i) { + uint64_t res = run_dlsa(tc[i].rt, tc[i].rs, tc[i].sa); + PrintF("0x%" PRIx64 " =? 0x%" PRIx64 " == Dlsa(v0, %" PRIx64 ", %" PRIx64 + ", %hhu)\n", + tc[i].expected_res, res, tc[i].rt, tc[i].rs, tc[i].sa); + CHECK_EQ(tc[i].expected_res, res); + } +} + #undef __ diff --git a/deps/v8/test/cctest/test-macro-assembler-x64.cc b/deps/v8/test/cctest/test-macro-assembler-x64.cc index 4cc52a11e2..612f9e88a3 100644 --- a/deps/v8/test/cctest/test-macro-assembler-x64.cc +++ b/deps/v8/test/cctest/test-macro-assembler-x64.cc @@ -151,7 +151,8 @@ TEST(SmiMove) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. EntryCode(masm); Label exit; @@ -195,7 +196,7 @@ void TestSmiCompare(MacroAssembler* masm, Label* exit, int id, int x, int y) { __ movl(rax, Immediate(id + 2)); __ j(less_equal, exit); } else { - DCHECK_EQ(x, y); + CHECK_EQ(x, y); __ movl(rax, Immediate(id + 3)); __ j(not_equal, exit); } @@ -212,7 +213,7 @@ void TestSmiCompare(MacroAssembler* masm, Label* exit, int id, int x, int y) { __ movl(rax, Immediate(id + 9)); __ j(greater_equal, exit); } else { - DCHECK(y > x); + CHECK(y > x); __ movl(rax, Immediate(id + 10)); __ j(less_equal, exit); } @@ -236,7 +237,8 @@ TEST(SmiCompare) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -284,7 +286,8 @@ TEST(Integer32ToSmi) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -382,7 +385,7 @@ void TestI64PlusConstantToSmi(MacroAssembler* masm, int64_t x, int y) { int64_t result = x + y; - DCHECK(Smi::IsValid(result)); + CHECK(Smi::IsValid(result)); __ movl(rax, Immediate(id)); __ Move(r8, Smi::FromInt(static_cast<int>(result))); __ movq(rcx, x); @@ -410,7 +413,8 @@ TEST(Integer64PlusConstantToSmi) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -452,7 +456,8 @@ TEST(SmiCheck) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -671,7 +676,8 @@ TEST(SmiNeg) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -769,7 +775,7 @@ static void SmiAddOverflowTest(MacroAssembler* masm, int id, int x) { // Adds a Smi to x so that the addition overflows. - DCHECK(x != 0); // Can't overflow by adding a Smi. + CHECK(x != 0); // Can't overflow by adding a Smi. int y_max = (x > 0) ? (Smi::kMaxValue + 0) : (Smi::kMinValue - x - 1); int y_min = (x > 0) ? (Smi::kMaxValue - x + 1) : (Smi::kMinValue + 0); @@ -882,7 +888,8 @@ TEST(SmiAdd) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -983,7 +990,7 @@ static void SmiSubOverflowTest(MacroAssembler* masm, int id, int x) { // Subtracts a Smi from x so that the subtraction overflows. - DCHECK(x != -1); // Can't overflow by subtracting a Smi. + CHECK(x != -1); // Can't overflow by subtracting a Smi. int y_max = (x < 0) ? (Smi::kMaxValue + 0) : (Smi::kMinValue + 0); int y_min = (x < 0) ? (Smi::kMaxValue + x + 2) : (Smi::kMinValue + x); @@ -1098,7 +1105,8 @@ TEST(SmiSub) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -1186,7 +1194,8 @@ TEST(SmiMul) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -1289,7 +1298,8 @@ TEST(SmiDiv) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -1396,7 +1406,8 @@ TEST(SmiMod) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -1447,7 +1458,7 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) { for (int i = 0; i < 8; i++) { __ Move(rcx, Smi::FromInt(x)); SmiIndex index = masm->SmiToIndex(rdx, rcx, i); - DCHECK(index.reg.is(rcx) || index.reg.is(rdx)); + CHECK(index.reg.is(rcx) || index.reg.is(rdx)); __ shlq(index.reg, Immediate(index.scale)); __ Set(r8, static_cast<intptr_t>(x) << i); __ cmpq(index.reg, r8); @@ -1455,7 +1466,7 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) { __ incq(rax); __ Move(rcx, Smi::FromInt(x)); index = masm->SmiToIndex(rcx, rcx, i); - DCHECK(index.reg.is(rcx)); + CHECK(index.reg.is(rcx)); __ shlq(rcx, Immediate(index.scale)); __ Set(r8, static_cast<intptr_t>(x) << i); __ cmpq(rcx, r8); @@ -1464,7 +1475,7 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) { __ Move(rcx, Smi::FromInt(x)); index = masm->SmiToNegativeIndex(rdx, rcx, i); - DCHECK(index.reg.is(rcx) || index.reg.is(rdx)); + CHECK(index.reg.is(rcx) || index.reg.is(rdx)); __ shlq(index.reg, Immediate(index.scale)); __ Set(r8, static_cast<intptr_t>(-x) << i); __ cmpq(index.reg, r8); @@ -1472,7 +1483,7 @@ void TestSmiIndex(MacroAssembler* masm, Label* exit, int id, int x) { __ incq(rax); __ Move(rcx, Smi::FromInt(x)); index = masm->SmiToNegativeIndex(rcx, rcx, i); - DCHECK(index.reg.is(rcx)); + CHECK(index.reg.is(rcx)); __ shlq(rcx, Immediate(index.scale)); __ Set(r8, static_cast<intptr_t>(-x) << i); __ cmpq(rcx, r8); @@ -1490,7 +1501,8 @@ TEST(SmiIndex) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -1556,7 +1568,8 @@ TEST(SmiSelectNonSmi) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -1632,7 +1645,8 @@ TEST(SmiAnd) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -1710,7 +1724,8 @@ TEST(SmiOr) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -1790,7 +1805,8 @@ TEST(SmiXor) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -1854,7 +1870,8 @@ TEST(SmiNot) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -1947,7 +1964,8 @@ TEST(SmiShiftLeft) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -2050,7 +2068,8 @@ TEST(SmiShiftLogicalRight) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -2116,7 +2135,8 @@ TEST(SmiShiftArithmeticRight) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -2144,7 +2164,7 @@ TEST(SmiShiftArithmeticRight) { void TestPositiveSmiPowerUp(MacroAssembler* masm, Label* exit, int id, int x) { - DCHECK(x >= 0); + CHECK(x >= 0); int powers[] = { 0, 1, 2, 3, 8, 16, 24, 31 }; int power_count = 8; __ movl(rax, Immediate(id)); @@ -2177,7 +2197,8 @@ TEST(PositiveSmiTimesPowerOfTwoToInteger64) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; EntryCode(masm); @@ -2217,7 +2238,8 @@ TEST(OperandOffset) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; Label exit; @@ -2567,7 +2589,8 @@ TEST(LoadAndStoreWithRepresentation) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. EntryCode(masm); __ subq(rsp, Immediate(1 * kPointerSize)); diff --git a/deps/v8/test/cctest/test-macro-assembler-x87.cc b/deps/v8/test/cctest/test-macro-assembler-x87.cc index 3cee27add0..ac2a8e3917 100644 --- a/deps/v8/test/cctest/test-macro-assembler-x87.cc +++ b/deps/v8/test/cctest/test-macro-assembler-x87.cc @@ -56,7 +56,8 @@ TEST(LoadAndStoreWithRepresentation) { CHECK(buffer); Isolate* isolate = CcTest::i_isolate(); HandleScope handles(isolate); - MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size)); + MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), + v8::internal::CodeObjectRequired::kYes); MacroAssembler* masm = &assembler; // Create a pointer for the __ macro. __ push(ebx); __ push(edx); diff --git a/deps/v8/test/cctest/test-microtask-delivery.cc b/deps/v8/test/cctest/test-microtask-delivery.cc index 415be3caf2..ecec77fbfd 100644 --- a/deps/v8/test/cctest/test-microtask-delivery.cc +++ b/deps/v8/test/cctest/test-microtask-delivery.cc @@ -55,6 +55,7 @@ class HarmonyIsolate { TEST(MicrotaskDeliverySimple) { + i::FLAG_harmony_object_observe = true; HarmonyIsolate isolate; v8::HandleScope scope(isolate.GetIsolate()); LocalContext context(isolate.GetIsolate()); @@ -82,28 +83,41 @@ TEST(MicrotaskDeliverySimple) { "});" "Object.observe(obj, observer);" "obj.id = 1;"); - CHECK_EQ(6, CompileRun("ordering.length")->Int32Value()); - CHECK_EQ(1, CompileRun("ordering[0]")->Int32Value()); - CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); - CHECK_EQ(3, CompileRun("ordering[2]")->Int32Value()); - CHECK_EQ(4, CompileRun("ordering[3]")->Int32Value()); - CHECK_EQ(5, CompileRun("ordering[4]")->Int32Value()); - CHECK_EQ(6, CompileRun("ordering[5]")->Int32Value()); + CHECK_EQ( + 6, CompileRun("ordering.length")->Int32Value(context.local()).FromJust()); + CHECK_EQ(1, + CompileRun("ordering[0]")->Int32Value(context.local()).FromJust()); + CHECK_EQ(2, + CompileRun("ordering[1]")->Int32Value(context.local()).FromJust()); + CHECK_EQ(3, + CompileRun("ordering[2]")->Int32Value(context.local()).FromJust()); + CHECK_EQ(4, + CompileRun("ordering[3]")->Int32Value(context.local()).FromJust()); + CHECK_EQ(5, + CompileRun("ordering[4]")->Int32Value(context.local()).FromJust()); + CHECK_EQ(6, + CompileRun("ordering[5]")->Int32Value(context.local()).FromJust()); } TEST(MicrotaskPerIsolateState) { + i::FLAG_harmony_object_observe = true; HarmonyIsolate isolate; v8::HandleScope scope(isolate.GetIsolate()); LocalContext context1(isolate.GetIsolate()); isolate.GetIsolate()->SetAutorunMicrotasks(false); CompileRun( "var obj = { calls: 0 };"); - v8::Handle<v8::Value> obj = CompileRun("obj"); + v8::Local<v8::Value> obj = CompileRun("obj"); { LocalContext context2(isolate.GetIsolate()); - context2->Global()->Set( - v8::String::NewFromUtf8(isolate.GetIsolate(), "obj"), obj); + context2->Global() + ->Set(context2.local(), + v8::String::NewFromUtf8(isolate.GetIsolate(), "obj", + v8::NewStringType::kNormal) + .ToLocalChecked(), + obj) + .FromJust(); CompileRun( "var resolver = {};" "new Promise(function(resolve) {" @@ -117,8 +131,13 @@ TEST(MicrotaskPerIsolateState) { } { LocalContext context3(isolate.GetIsolate()); - context3->Global()->Set( - v8::String::NewFromUtf8(isolate.GetIsolate(), "obj"), obj); + context3->Global() + ->Set(context3.local(), + v8::String::NewFromUtf8(isolate.GetIsolate(), "obj", + v8::NewStringType::kNormal) + .ToLocalChecked(), + obj) + .FromJust(); CompileRun( "var foo = { id: 1 };" "Object.observe(foo, function() {" @@ -128,9 +147,15 @@ TEST(MicrotaskPerIsolateState) { } { LocalContext context4(isolate.GetIsolate()); - context4->Global()->Set( - v8::String::NewFromUtf8(isolate.GetIsolate(), "obj"), obj); + context4->Global() + ->Set(context4.local(), + v8::String::NewFromUtf8(isolate.GetIsolate(), "obj", + v8::NewStringType::kNormal) + .ToLocalChecked(), + obj) + .FromJust(); isolate.GetIsolate()->RunMicrotasks(); - CHECK_EQ(2, CompileRun("obj.calls")->Int32Value()); + CHECK_EQ(2, + CompileRun("obj.calls")->Int32Value(context4.local()).FromJust()); } } diff --git a/deps/v8/test/cctest/test-object-observe.cc b/deps/v8/test/cctest/test-object-observe.cc index e0d457f7a6..f0af22e27a 100644 --- a/deps/v8/test/cctest/test-object-observe.cc +++ b/deps/v8/test/cctest/test-object-observe.cc @@ -25,9 +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. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "test/cctest/cctest.h" @@ -42,6 +39,7 @@ inline int32_t ToInt32(v8::Local<v8::Value> value) { TEST(PerIsolateState) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); LocalContext context1(CcTest::isolate()); @@ -105,6 +103,7 @@ TEST(PerIsolateState) { TEST(EndOfMicrotaskDelivery) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); LocalContext context(CcTest::isolate()); CompileRun( @@ -118,6 +117,7 @@ TEST(EndOfMicrotaskDelivery) { TEST(DeliveryOrdering) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); LocalContext context(CcTest::isolate()); CompileRun( @@ -149,6 +149,7 @@ TEST(DeliveryOrdering) { TEST(DeliveryCallbackThrows) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); LocalContext context(CcTest::isolate()); CompileRun( @@ -177,6 +178,7 @@ TEST(DeliveryCallbackThrows) { TEST(DeliveryChangesMutationInCallback) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); LocalContext context(CcTest::isolate()); CompileRun( @@ -202,6 +204,7 @@ TEST(DeliveryChangesMutationInCallback) { TEST(DeliveryOrderingReentrant) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); LocalContext context(CcTest::isolate()); CompileRun( @@ -233,6 +236,7 @@ TEST(DeliveryOrderingReentrant) { TEST(DeliveryOrderingDeliverChangeRecords) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); LocalContext context(CcTest::isolate()); CompileRun( @@ -257,6 +261,7 @@ TEST(DeliveryOrderingDeliverChangeRecords) { TEST(ObjectHashTableGrowth) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); // Initializing this context sets up initial hash tables. LocalContext context(CcTest::isolate()); @@ -352,6 +357,7 @@ static void ExpectRecords(v8::Isolate* isolate, Local<Value> records, arraysize(expectations)) TEST(APITestBasicMutation) { + i::FLAG_harmony_object_observe = true; v8::Isolate* v8_isolate = CcTest::isolate(); HandleScope scope(v8_isolate); LocalContext context(v8_isolate); @@ -411,6 +417,7 @@ TEST(APITestBasicMutation) { TEST(HiddenPrototypeObservation) { + i::FLAG_harmony_object_observe = true; v8::Isolate* v8_isolate = CcTest::isolate(); HandleScope scope(v8_isolate); LocalContext context(v8_isolate); @@ -473,6 +480,7 @@ static int NumberOfElements(i::Handle<i::JSWeakMap> map) { TEST(ObservationWeakMap) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); LocalContext context(CcTest::isolate()); CompileRun( @@ -543,6 +551,7 @@ static int TestObserveSecurity(Local<Context> observer_context, TEST(ObserverSecurityAAA) { + i::FLAG_harmony_object_observe = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Local<Context> contextA = Context::New(isolate); @@ -551,6 +560,7 @@ TEST(ObserverSecurityAAA) { TEST(ObserverSecurityA1A2A3) { + i::FLAG_harmony_object_observe = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); @@ -568,6 +578,7 @@ TEST(ObserverSecurityA1A2A3) { TEST(ObserverSecurityAAB) { + i::FLAG_harmony_object_observe = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Local<Context> contextA = Context::New(isolate); @@ -577,6 +588,7 @@ TEST(ObserverSecurityAAB) { TEST(ObserverSecurityA1A2B) { + i::FLAG_harmony_object_observe = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); @@ -593,6 +605,7 @@ TEST(ObserverSecurityA1A2B) { TEST(ObserverSecurityABA) { + i::FLAG_harmony_object_observe = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Local<Context> contextA = Context::New(isolate); @@ -602,6 +615,7 @@ TEST(ObserverSecurityABA) { TEST(ObserverSecurityA1BA2) { + i::FLAG_harmony_object_observe = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Local<Context> contextA1 = Context::New(isolate); @@ -617,6 +631,7 @@ TEST(ObserverSecurityA1BA2) { TEST(ObserverSecurityBAA) { + i::FLAG_harmony_object_observe = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Local<Context> contextA = Context::New(isolate); @@ -626,6 +641,7 @@ TEST(ObserverSecurityBAA) { TEST(ObserverSecurityBA1A2) { + i::FLAG_harmony_object_observe = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Local<Context> contextA1 = Context::New(isolate); @@ -641,6 +657,7 @@ TEST(ObserverSecurityBA1A2) { TEST(ObserverSecurityNotify) { + i::FLAG_harmony_object_observe = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); v8::Local<Context> contextA = Context::New(isolate); @@ -676,6 +693,7 @@ TEST(ObserverSecurityNotify) { TEST(HiddenPropertiesLeakage) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); LocalContext context(CcTest::isolate()); CompileRun("var obj = {};" @@ -697,6 +715,7 @@ TEST(HiddenPropertiesLeakage) { TEST(GetNotifierFromOtherContext) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); LocalContext context(CcTest::isolate()); CompileRun("var obj = {};"); @@ -713,6 +732,7 @@ TEST(GetNotifierFromOtherContext) { TEST(GetNotifierFromOtherOrigin) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); Local<Value> foo = v8_str("foo"); Local<Value> bar = v8_str("bar"); @@ -733,6 +753,7 @@ TEST(GetNotifierFromOtherOrigin) { TEST(GetNotifierFromSameOrigin) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); Local<Value> foo = v8_str("foo"); LocalContext context(CcTest::isolate()); @@ -784,6 +805,7 @@ static void CheckSurvivingGlobalObjectsCount(int expected) { TEST(DontLeakContextOnObserve) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); Local<Value> foo = v8_str("foo"); LocalContext context(CcTest::isolate()); @@ -804,11 +826,12 @@ TEST(DontLeakContextOnObserve) { } CcTest::isolate()->ContextDisposedNotification(); - CheckSurvivingGlobalObjectsCount(1); + CheckSurvivingGlobalObjectsCount(0); } TEST(DontLeakContextOnGetNotifier) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); Local<Value> foo = v8_str("foo"); LocalContext context(CcTest::isolate()); @@ -827,11 +850,12 @@ TEST(DontLeakContextOnGetNotifier) { } CcTest::isolate()->ContextDisposedNotification(); - CheckSurvivingGlobalObjectsCount(1); + CheckSurvivingGlobalObjectsCount(0); } TEST(DontLeakContextOnNotifierPerformChange) { + i::FLAG_harmony_object_observe = true; HandleScope scope(CcTest::isolate()); Local<Value> foo = v8_str("foo"); LocalContext context(CcTest::isolate()); @@ -858,7 +882,7 @@ TEST(DontLeakContextOnNotifierPerformChange) { } CcTest::isolate()->ContextDisposedNotification(); - CheckSurvivingGlobalObjectsCount(1); + CheckSurvivingGlobalObjectsCount(0); } @@ -869,6 +893,7 @@ static void ObserverCallback(const FunctionCallbackInfo<Value>& args) { TEST(ObjectObserveCallsCppFunction) { + i::FLAG_harmony_object_observe = true; Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); LocalContext context(isolate); @@ -891,6 +916,7 @@ TEST(ObjectObserveCallsCppFunction) { TEST(ObjectObserveCallsFunctionTemplateInstance) { + i::FLAG_harmony_object_observe = true; Isolate* isolate = CcTest::isolate(); HandleScope scope(isolate); LocalContext context(isolate); @@ -926,6 +952,7 @@ static void AccessorSetter(Local<Name> property, Local<Value> value, TEST(APIAccessorsShouldNotNotify) { + i::FLAG_harmony_object_observe = true; Isolate* isolate = CcTest::isolate(); HandleScope handle_scope(isolate); LocalContext context(isolate); @@ -959,6 +986,7 @@ void MockUseCounterCallback(v8::Isolate* isolate, TEST(UseCountObjectObserve) { + i::FLAG_harmony_object_observe = true; i::Isolate* isolate = CcTest::i_isolate(); i::HandleScope scope(isolate); LocalContext env; @@ -986,6 +1014,7 @@ TEST(UseCountObjectObserve) { TEST(UseCountObjectGetNotifier) { + i::FLAG_harmony_object_observe = true; i::Isolate* isolate = CcTest::i_isolate(); i::HandleScope scope(isolate); LocalContext env; @@ -1005,6 +1034,7 @@ static bool NamedAccessCheckAlwaysAllow(Local<v8::Context> accessing_context, TEST(DisallowObserveAccessCheckedObject) { + i::FLAG_harmony_object_observe = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); LocalContext env; @@ -1026,6 +1056,7 @@ TEST(DisallowObserveAccessCheckedObject) { TEST(DisallowGetNotifierAccessCheckedObject) { + i::FLAG_harmony_object_observe = true; v8::Isolate* isolate = CcTest::isolate(); v8::HandleScope scope(isolate); LocalContext env; diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc index dc4ddb0af6..7269e2d5b2 100644 --- a/deps/v8/test/cctest/test-parsing.cc +++ b/deps/v8/test/cctest/test-parsing.cc @@ -25,27 +25,24 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdio.h> #include <stdlib.h> #include <string.h> #include "src/v8.h" -#include "src/ast.h" -#include "src/ast-numbering.h" -#include "src/ast-value-factory.h" +#include "src/ast/ast.h" +#include "src/ast/ast-numbering.h" +#include "src/ast/ast-value-factory.h" #include "src/compiler.h" #include "src/execution.h" #include "src/isolate.h" #include "src/objects.h" -#include "src/parser.h" -#include "src/preparser.h" -#include "src/rewriter.h" -#include "src/scanner-character-streams.h" -#include "src/token.h" +#include "src/parsing/parser.h" +#include "src/parsing/preparser.h" +#include "src/parsing/rewriter.h" +#include "src/parsing/scanner-character-streams.h" +#include "src/parsing/token.h" #include "src/utils.h" #include "test/cctest/cctest.h" @@ -220,7 +217,7 @@ TEST(UsingCachedData) { " 42: 'number literal', for: 'keyword as propertyName', " " f\\u006fr: 'keyword propertyname with escape'};" "var v = /RegExp Literal/;" - "var w = /RegExp Literal\\u0020With Escape/gin;" + "var w = /RegExp Literal\\u0020With Escape/gi;" "var y = { get getter() { return 42; }, " " set setter(v) { this.value = v; }};" "var f = a => function (b) { return a + b; };" @@ -706,7 +703,7 @@ TEST(Utf8CharacterStream) { cursor += unibrow::Utf8::Encode(buffer + cursor, i, unibrow::Utf16::kNoPreviousCharacter, true); } - DCHECK(cursor == kAllUtf8CharsSizeU); + CHECK(cursor == kAllUtf8CharsSizeU); i::Utf8ToUtf16CharacterStream stream(reinterpret_cast<const i::byte*>(buffer), kAllUtf8CharsSizeU); @@ -802,8 +799,8 @@ TEST(StreamScanner) { i::Token::EOS, i::Token::ILLEGAL }; - DCHECK_EQ('{', str2[19]); - DCHECK_EQ('}', str2[37]); + CHECK_EQ('{', str2[19]); + CHECK_EQ('}', str2[37]); TestStreamScanner(&stream2, expectations2, 20, 37); const char* str3 = "{}}}}"; @@ -1151,12 +1148,23 @@ static void CheckParsesToNumber(const char* source, bool with_dot) { TEST(ParseNumbers) { + CheckParsesToNumber("1.", true); CheckParsesToNumber("1.34", true); CheckParsesToNumber("134", false); CheckParsesToNumber("134e44", false); CheckParsesToNumber("134.e44", true); CheckParsesToNumber("134.44e44", true); CheckParsesToNumber(".44", true); + + CheckParsesToNumber("-1.", true); + CheckParsesToNumber("-1.0", true); + CheckParsesToNumber("-1.34", true); + CheckParsesToNumber("-134", false); + CheckParsesToNumber("-134e44", false); + CheckParsesToNumber("-134.e44", true); + CheckParsesToNumber("-134.44e44", true); + CheckParsesToNumber("-.44", true); + CheckParsesToNumber("+x", true); } @@ -1402,13 +1410,13 @@ TEST(DiscardFunctionBody) { // See comments in ParseFunctionLiteral in parser.cc. const char* discard_sources[] = { "(function f() { function g() { var a; } })();", + "(function f() { function g() { { function h() { } } } })();", /* TODO(conradw): In future it may be possible to apply this optimisation * to these productions. "(function f() { 0, function g() { var a; } })();", "(function f() { 0, { g() { var a; } } })();", "(function f() { 0, class c { g() { var a; } } })();", */ - NULL - }; + NULL}; i::Isolate* isolate = CcTest::i_isolate(); i::Factory* factory = isolate->factory(); @@ -1440,6 +1448,7 @@ TEST(DiscardFunctionBody) { } else { // TODO(conradw): This path won't be hit until the other test cases can be // uncommented. + UNREACHABLE(); CHECK_NOT_NULL(inner->body()); CHECK_GE(2, inner->body()->length()); i::Expression* exp = inner->body()->at(1)->AsExpressionStatement()-> @@ -1496,10 +1505,10 @@ enum ParserFlag { kAllowLazy, kAllowNatives, kAllowHarmonyDefaultParameters, - kAllowHarmonyRestParameters, kAllowHarmonySloppy, kAllowHarmonySloppyLet, kAllowHarmonyDestructuring, + kAllowHarmonyDestructuringAssignment, kAllowHarmonyNewTarget, kAllowStrongMode, kNoLegacyConst @@ -1519,12 +1528,12 @@ void SetParserFlags(i::ParserBase<Traits>* parser, parser->set_allow_natives(flags.Contains(kAllowNatives)); parser->set_allow_harmony_default_parameters( flags.Contains(kAllowHarmonyDefaultParameters)); - parser->set_allow_harmony_rest_parameters( - flags.Contains(kAllowHarmonyRestParameters)); parser->set_allow_harmony_sloppy(flags.Contains(kAllowHarmonySloppy)); parser->set_allow_harmony_sloppy_let(flags.Contains(kAllowHarmonySloppyLet)); - parser->set_allow_harmony_destructuring( + parser->set_allow_harmony_destructuring_bind( flags.Contains(kAllowHarmonyDestructuring)); + parser->set_allow_harmony_destructuring_assignment( + flags.Contains(kAllowHarmonyDestructuringAssignment)); parser->set_allow_strong_mode(flags.Contains(kAllowStrongMode)); parser->set_allow_legacy_const(!flags.Contains(kNoLegacyConst)); } @@ -1532,17 +1541,19 @@ void SetParserFlags(i::ParserBase<Traits>* parser, void TestParserSyncWithFlags(i::Handle<i::String> source, i::EnumSet<ParserFlag> flags, - ParserSyncTestResult result) { + ParserSyncTestResult result, + bool is_module = false) { i::Isolate* isolate = CcTest::i_isolate(); i::Factory* factory = isolate->factory(); uintptr_t stack_limit = isolate->stack_guard()->real_climit(); int preparser_materialized_literals = -1; int parser_materialized_literals = -2; + bool test_preparser = !is_module; // Preparse the data. i::CompleteParserRecorder log; - { + if (test_preparser) { i::Scanner scanner(isolate->unicode_cache()); i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); i::Zone zone; @@ -1556,7 +1567,6 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, &preparser_materialized_literals); CHECK_EQ(i::PreParser::kPreParseSuccess, result); } - bool preparse_error = log.HasError(); // Parse the data @@ -1567,7 +1577,11 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, i::ParseInfo info(&zone, script); i::Parser parser(&info); SetParserFlags(&parser, flags); - info.set_global(); + if (is_module) { + info.set_module(); + } else { + info.set_global(); + } parser.Parse(&info); function = info.literal(); if (function) { @@ -1596,7 +1610,7 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, CHECK(false); } - if (!preparse_error) { + if (test_preparser && !preparse_error) { v8::base::OS::Print( "Parser failed on:\n" "\t%s\n" @@ -1607,21 +1621,22 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, CHECK(false); } // Check that preparser and parser produce the same error. - i::Handle<i::String> preparser_message = - FormatMessage(log.ErrorMessageData()); - if (!i::String::Equals(message_string, preparser_message)) { - v8::base::OS::Print( - "Expected parser and preparser to produce the same error on:\n" - "\t%s\n" - "However, found the following error messages\n" - "\tparser: %s\n" - "\tpreparser: %s\n", - source->ToCString().get(), - message_string->ToCString().get(), - preparser_message->ToCString().get()); - CHECK(false); + if (test_preparser) { + i::Handle<i::String> preparser_message = + FormatMessage(log.ErrorMessageData()); + if (!i::String::Equals(message_string, preparser_message)) { + v8::base::OS::Print( + "Expected parser and preparser to produce the same error on:\n" + "\t%s\n" + "However, found the following error messages\n" + "\tparser: %s\n" + "\tpreparser: %s\n", + source->ToCString().get(), message_string->ToCString().get(), + preparser_message->ToCString().get()); + CHECK(false); + } } - } else if (preparse_error) { + } else if (test_preparser && preparse_error) { v8::base::OS::Print( "Preparser failed on:\n" "\t%s\n" @@ -1638,7 +1653,8 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, "However, parser and preparser succeeded", source->ToCString().get()); CHECK(false); - } else if (preparser_materialized_literals != parser_materialized_literals) { + } else if (test_preparser && + preparser_materialized_literals != parser_materialized_literals) { v8::base::OS::Print( "Preparser materialized literals (%d) differ from Parser materialized " "literals (%d) on:\n" @@ -1651,14 +1667,14 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, } -void TestParserSync(const char* source, - const ParserFlag* varying_flags, +void TestParserSync(const char* source, const ParserFlag* varying_flags, size_t varying_flags_length, ParserSyncTestResult result = kSuccessOrError, const ParserFlag* always_true_flags = NULL, size_t always_true_flags_length = 0, const ParserFlag* always_false_flags = NULL, - size_t always_false_flags_length = 0) { + size_t always_false_flags_length = 0, + bool is_module = false) { i::Handle<i::String> str = CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source); for (int bits = 0; bits < (1 << varying_flags_length); bits++) { @@ -1675,7 +1691,7 @@ void TestParserSync(const char* source, ++flag_index) { flags.Remove(always_false_flags[flag_index]); } - TestParserSyncWithFlags(str, flags, result); + TestParserSyncWithFlags(str, flags, result, is_module); } } @@ -1819,12 +1835,11 @@ TEST(StrictOctal) { void RunParserSyncTest(const char* context_data[][2], const char* statement_data[], ParserSyncTestResult result, - const ParserFlag* flags = NULL, - int flags_len = 0, + const ParserFlag* flags = NULL, int flags_len = 0, const ParserFlag* always_true_flags = NULL, int always_true_len = 0, const ParserFlag* always_false_flags = NULL, - int always_false_len = 0) { + int always_false_len = 0, bool is_module = false) { v8::HandleScope handles(CcTest::isolate()); v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate()); v8::Context::Scope context_scope(context); @@ -1877,20 +1892,32 @@ void RunParserSyncTest(const char* context_data[][2], statement_data[j], context_data[i][1]); CHECK(length == kProgramSize); - TestParserSync(program.start(), - flags, - flags_len, - result, - always_true_flags, - always_true_len, - always_false_flags, - always_false_len); + TestParserSync(program.start(), flags, flags_len, result, + always_true_flags, always_true_len, always_false_flags, + always_false_len, is_module); } } delete[] generated_flags; } +void RunModuleParserSyncTest(const char* context_data[][2], + const char* statement_data[], + ParserSyncTestResult result, + const ParserFlag* flags = NULL, int flags_len = 0, + const ParserFlag* always_true_flags = NULL, + int always_true_len = 0, + const ParserFlag* always_false_flags = NULL, + int always_false_len = 0) { + bool flag = i::FLAG_harmony_modules; + i::FLAG_harmony_modules = true; + RunParserSyncTest(context_data, statement_data, result, flags, flags_len, + always_true_flags, always_true_len, always_false_flags, + always_false_len, true); + i::FLAG_harmony_modules = flag; +} + + TEST(ErrorsEvalAndArguments) { // Tests that both preparsing and parsing produce the right kind of errors for // using "eval" and "arguments" as identifiers. Without the strict mode, it's @@ -2203,7 +2230,6 @@ TEST(NoErrorsYieldSloppyGeneratorsEnabled) { "function foo(yield) { }", "function foo(bar, yield) { }", "function * yield() { }", - "(function * yield() { })", "yield = 1;", "var foo = yield = 1;", "yield * 2;", @@ -2264,6 +2290,23 @@ TEST(ErrorsYieldStrict) { } +TEST(ErrorsYieldSloppy) { + const char* context_data[][2] = { + { "", "" }, + { "function not_gen() {", "}" }, + { "(function not_gen() {", "})" }, + { NULL, NULL } + }; + + const char* statement_data[] = { + "(function * yield() { })", + NULL + }; + + RunParserSyncTest(context_data, statement_data, kError); +} + + TEST(NoErrorsGenerator) { const char* context_data[][2] = { { "function * gen() {", "}" }, @@ -2287,6 +2330,7 @@ TEST(NoErrorsGenerator) { "yield 3; yield 4;", "yield * 3; yield * 4;", "(function (yield) { })", + "(function yield() { })", "yield { yield: 12 }", "yield /* comment */ { yield: 12 }", "yield * \n { yield: 12 }", @@ -2336,9 +2380,8 @@ TEST(ErrorsYieldGenerator) { "var foo, yield;", "try { } catch (yield) { }", "function yield() { }", - // The name of the NFE is let-bound in the generator, which does not permit + // The name of the NFE is bound in the generator, which does not permit // yield to be an identifier. - "(function yield() { })", "(function * yield() { })", // Yield isn't valid as a formal parameter for generators. "function * foo(yield) { }", @@ -2761,7 +2804,6 @@ TEST(NoErrorsRegexpLiteral) { const char* statement_data[] = { "/foo/", "/foo/g", - "/foo/whatever", // This is an error but not detected by the parser. NULL }; @@ -3298,8 +3340,8 @@ TEST(SerializationOfMaybeAssignmentFlag) { script_scope->Initialize(); i::Scope* s = i::Scope::DeserializeScopeChain(isolate, &zone, context, script_scope); - DCHECK(s != script_scope); - DCHECK(name != NULL); + CHECK(s != script_scope); + CHECK(name != NULL); // Get result from h's function context (that is f's context) i::Variable* var = s->Lookup(name); @@ -3346,7 +3388,7 @@ TEST(IfArgumentsArrayAccessedThenParametersMaybeAssigned) { script_scope->Initialize(); i::Scope* s = i::Scope::DeserializeScopeChain(isolate, &zone, context, script_scope); - DCHECK(s != script_scope); + CHECK(s != script_scope); const i::AstRawString* name_x = avf.GetOneByteString("x"); // Get result from f's function context (that is g's outer context) @@ -3529,6 +3571,7 @@ TEST(UseAsmUseCount) { TEST(UseConstLegacyCount) { + i::FLAG_legacy_const = true; i::Isolate* isolate = CcTest::i_isolate(); i::HandleScope scope(isolate); LocalContext env; @@ -3643,9 +3686,7 @@ TEST(ErrorsArrowFormalParameters) { nullptr }; - static const ParserFlag always_flags[] = {kAllowHarmonyRestParameters}; - RunParserSyncTest(context_data, assignment_expression_suffix_data, kError, - NULL, 0, always_flags, arraysize(always_flags)); + RunParserSyncTest(context_data, assignment_expression_suffix_data, kError); } @@ -3837,7 +3878,6 @@ TEST(NoErrorsArrowFunctions) { }; static const ParserFlag always_flags[] = {kAllowHarmonyDefaultParameters, - kAllowHarmonyRestParameters, kAllowHarmonyDestructuring}; RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); @@ -3944,7 +3984,6 @@ TEST(ArrowFunctionsYieldParameterNameInGenerator) { }; static const ParserFlag always_flags[] = { kAllowHarmonyDestructuring, - kAllowHarmonyRestParameters, kAllowStrongMode}; RunParserSyncTest(sloppy_function_context_data, arrow_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); @@ -5257,22 +5296,26 @@ TEST(ParseRestParameters) { "/regexp/, 'str', function(){});"}, {NULL, NULL}}; - const char* data[] = { - "...args", - "a, ...args", - "... args", - "a, ... args", - "...\targs", - "a, ...\targs", - "...\r\nargs", - "a, ...\r\nargs", - "...\rargs", - "a, ...\rargs", - "...\t\n\t\t\n args", - "a, ... \n \n args", - NULL}; - static const ParserFlag always_flags[] = {kAllowHarmonyRestParameters}; - RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags, + const char* data[] = {"...args", + "a, ...args", + "... args", + "a, ... args", + "...\targs", + "a, ...\targs", + "...\r\nargs", + "a, ...\r\nargs", + "...\rargs", + "a, ...\rargs", + "...\t\n\t\t\n args", + "a, ... \n \n args", + "...{ length, 0: a, 1: b}", + "...{}", + "...[a, b]", + "...[]", + "...[...[a, b, ...c]]", + NULL}; + static const ParserFlag always_flags[] = {kAllowHarmonyDestructuring}; + RunParserSyncTest(context_data, data, kSuccess, nullptr, 0, always_flags, arraysize(always_flags)); } @@ -5303,9 +5346,7 @@ TEST(ParseRestParametersErrors) { "a,\ra, ...args", "a,\na, ...args", NULL}; - static const ParserFlag always_flags[] = {kAllowHarmonyRestParameters}; - RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, - arraysize(always_flags)); + RunParserSyncTest(context_data, data, kError); } @@ -5320,8 +5361,7 @@ TEST(RestParameterInSetterMethodError) { {nullptr, nullptr}}; const char* data[] = {"...a", "...arguments", "...eval", nullptr}; - static const ParserFlag always_flags[] = {kAllowHarmonyRestParameters, - kAllowHarmonySloppy}; + static const ParserFlag always_flags[] = {kAllowHarmonySloppy}; RunParserSyncTest(context_data, data, kError, nullptr, 0, always_flags, arraysize(always_flags)); } @@ -5344,15 +5384,11 @@ TEST(RestParametersEvalArguments) { "arguments, ...args", NULL}; - static const ParserFlag always_flags[] = {kAllowHarmonyRestParameters}; - // Fail in strict mode - RunParserSyncTest(strict_context_data, data, kError, NULL, 0, always_flags, - arraysize(always_flags)); + RunParserSyncTest(strict_context_data, data, kError); // OK in sloppy mode - RunParserSyncTest(sloppy_context_data, data, kSuccess, NULL, 0, always_flags, - arraysize(always_flags)); + RunParserSyncTest(sloppy_context_data, data, kSuccess); } @@ -5371,12 +5407,9 @@ TEST(RestParametersDuplicateEvalArguments) { "arguments, arguments, ...args", NULL}; - static const ParserFlag always_flags[] = {kAllowHarmonyRestParameters}; - // In strict mode, the error is using "eval" or "arguments" as parameter names // In sloppy mode, the error is that eval / arguments are duplicated - RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, - arraysize(always_flags)); + RunParserSyncTest(context_data, data, kError); } @@ -5718,10 +5751,7 @@ TEST(ModuleParsingInternals) { i::Scope* outer_scope = module_scope->outer_scope(); CHECK(outer_scope->is_script_scope()); CHECK_NULL(outer_scope->outer_scope()); - CHECK_EQ(1, outer_scope->num_modules()); CHECK(module_scope->is_module_scope()); - CHECK_NOT_NULL(module_scope->module_var()); - CHECK_EQ(i::TEMPORARY, module_scope->module_var()->mode()); i::ModuleDescriptor* descriptor = module_scope->module(); CHECK_NOT_NULL(descriptor); CHECK_EQ(1, descriptor->Length()); @@ -6213,8 +6243,7 @@ TEST(StrongConstructorDirective) { "foo() { \"use strong\" } constructor() {}", NULL}; static const ParserFlag always_flags[] = { - kAllowHarmonyRestParameters, kAllowHarmonySloppy, kAllowHarmonySloppyLet, - kAllowStrongMode}; + kAllowHarmonySloppy, kAllowHarmonySloppyLet, kAllowStrongMode}; RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags, arraysize(always_flags)); @@ -6397,6 +6426,7 @@ TEST(ArrowFunctionASIErrors) { TEST(StrongModeFreeVariablesDeclaredByPreviousScript) { i::FLAG_strong_mode = true; + i::FLAG_legacy_const = true; v8::V8::Initialize(); v8::HandleScope scope(CcTest::isolate()); v8::Context::Scope context_scope(v8::Context::New(CcTest::isolate())); @@ -6546,7 +6576,7 @@ TEST(StrongModeFreeVariablesNotDeclared) { TEST(DestructuringPositiveTests) { - i::FLAG_harmony_destructuring = true; + i::FLAG_harmony_destructuring_bind = true; const char* context_data[][2] = {{"'use strict'; let ", " = {};"}, {"var ", " = {};"}, @@ -6605,7 +6635,7 @@ TEST(DestructuringPositiveTests) { TEST(DestructuringNegativeTests) { - i::FLAG_harmony_destructuring = true; + i::FLAG_harmony_destructuring_bind = true; static const ParserFlag always_flags[] = {kAllowHarmonyDestructuring}; { // All modes. @@ -6682,6 +6712,10 @@ TEST(DestructuringNegativeTests) { "{ x : 'foo' }", "{ x : /foo/ }", "{ x : `foo` }", + "{ get a() {} }", + "{ set a() {} }", + "{ method() {} }", + "{ *method() {} }", NULL}; // clang-format on RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, @@ -6775,8 +6809,376 @@ TEST(DestructuringNegativeTests) { } +TEST(DestructuringAssignmentPositiveTests) { + const char* context_data[][2] = { + {"'use strict'; let x, y, z; (", " = {});"}, + {"var x, y, z; (", " = {});"}, + {"'use strict'; let x, y, z; for (x in ", " = {});"}, + {"'use strict'; let x, y, z; for (x of ", " = {});"}, + {"var x, y, z; for (x in ", " = {});"}, + {"var x, y, z; for (x of ", " = {});"}, + {"var x, y, z; for (", " in {});"}, + {"var x, y, z; for (", " of {});"}, + {"'use strict'; var x, y, z; for (", " in {});"}, + {"'use strict'; var x, y, z; for (", " of {});"}, + {NULL, NULL}}; + + const char* mixed_assignments_context_data[][2] = { + {"'use strict'; let x, y, z; (", " = z = {});"}, + {"var x, y, z; (", " = z = {});"}, + {"'use strict'; let x, y, z; (x = ", " = z = {});"}, + {"var x, y, z; (x = ", " = z = {});"}, + {"'use strict'; let x, y, z; for (x in ", " = z = {});"}, + {"'use strict'; let x, y, z; for (x in x = ", " = z = {});"}, + {"'use strict'; let x, y, z; for (x of ", " = z = {});"}, + {"'use strict'; let x, y, z; for (x of x = ", " = z = {});"}, + {"var x, y, z; for (x in ", " = z = {});"}, + {"var x, y, z; for (x in x = ", " = z = {});"}, + {"var x, y, z; for (x of ", " = z = {});"}, + {"var x, y, z; for (x of x = ", " = z = {});"}, + {NULL, NULL}}; + + // clang-format off + const char* data[] = { + "x", + + "{ x : y }", + "{ x : foo().y }", + "{ x : foo()[y] }", + "{ x : y.z }", + "{ x : y[z] }", + "{ x : { y } }", + "{ x : { foo: y } }", + "{ x : { foo: foo().y } }", + "{ x : { foo: foo()[y] } }", + "{ x : { foo: y.z } }", + "{ x : { foo: y[z] } }", + "{ x : [ y ] }", + "{ x : [ foo().y ] }", + "{ x : [ foo()[y] ] }", + "{ x : [ y.z ] }", + "{ x : [ y[z] ] }", + + "{ x : y = 10 }", + "{ x : foo().y = 10 }", + "{ x : foo()[y] = 10 }", + "{ x : y.z = 10 }", + "{ x : y[z] = 10 }", + "{ x : { y = 10 } = {} }", + "{ x : { foo: y = 10 } = {} }", + "{ x : { foo: foo().y = 10 } = {} }", + "{ x : { foo: foo()[y] = 10 } = {} }", + "{ x : { foo: y.z = 10 } = {} }", + "{ x : { foo: y[z] = 10 } = {} }", + "{ x : [ y = 10 ] = {} }", + "{ x : [ foo().y = 10 ] = {} }", + "{ x : [ foo()[y] = 10 ] = {} }", + "{ x : [ y.z = 10 ] = {} }", + "{ x : [ y[z] = 10 ] = {} }", + + "[ x ]", + "[ foo().x ]", + "[ foo()[x] ]", + "[ x.y ]", + "[ x[y] ]", + "[ { x } ]", + "[ { x : y } ]", + "[ { x : foo().y } ]", + "[ { x : foo()[y] } ]", + "[ { x : x.y } ]", + "[ { x : x[y] } ]", + "[ [ x ] ]", + "[ [ foo().x ] ]", + "[ [ foo()[x] ] ]", + "[ [ x.y ] ]", + "[ [ x[y] ] ]", + + "[ x = 10 ]", + "[ foo().x = 10 ]", + "[ foo()[x] = 10 ]", + "[ x.y = 10 ]", + "[ x[y] = 10 ]", + "[ { x = 10 } = {} ]", + "[ { x : y = 10 } = {} ]", + "[ { x : foo().y = 10 } = {} ]", + "[ { x : foo()[y] = 10 } = {} ]", + "[ { x : x.y = 10 } = {} ]", + "[ { x : x[y] = 10 } = {} ]", + "[ [ x = 10 ] = {} ]", + "[ [ foo().x = 10 ] = {} ]", + "[ [ foo()[x] = 10 ] = {} ]", + "[ [ x.y = 10 ] = {} ]", + "[ [ x[y] = 10 ] = {} ]", + "{ x : y = 1 }", + "{ x }", + "{ x, y, z }", + "{ x = 1, y: z, z: y }", + "{x = 42, y = 15}", + "[x]", + "[x = 1]", + "[x,y,z]", + "[x, y = 42, z]", + "{ x : x, y : y }", + "{ x : x = 1, y : y }", + "{ x : x, y : y = 42 }", + "[]", + "{}", + "[{x:x, y:y}, [,x,z,]]", + "[{x:x = 1, y:y = 2}, [z = 3, z = 4, z = 5]]", + "[x,,y]", + "[(x),,(y)]", + "[(x)]", + "{42 : x}", + "{42 : x = 42}", + "{42e-2 : x}", + "{42e-2 : x = 42}", + "{'hi' : x}", + "{'hi' : x = 42}", + "{var: x}", + "{var: x = 42}", + "{var: (x) = 42}", + "{[x] : z}", + "{[1+1] : z}", + "{[1+1] : (z)}", + "{[foo()] : z}", + "{[foo()] : (z)}", + "{[foo()] : foo().bar}", + "{[foo()] : foo()['bar']}", + "{[foo()] : this.bar}", + "{[foo()] : this['bar']}", + "{[foo()] : 'foo'.bar}", + "{[foo()] : 'foo'['bar']}", + "[...x]", + "[x,y,...z]", + "[x,,...z]", + "{ x: y }", + "[x, y]", + "[((x, y) => z).x]", + "{x: ((y, z) => z).x}", + "[((x, y) => z)['x']]", + "{x: ((y, z) => z)['x']}", + + "{x: { y = 10 } }", + "[(({ x } = { x: 1 }) => x).a]", + + // v8:4662 + "{ x: (y) }", + "{ x: (y) = [] }", + "{ x: (foo.bar) }", + "{ x: (foo['bar']) }", + "[ ...(a) ]", + "[ ...(foo['bar']) ]", + "[ ...(foo.bar) ]", + "[ (y) ]", + "[ (foo.bar) ]", + "[ (foo['bar']) ]", + + NULL}; + // clang-format on + static const ParserFlag always_flags[] = { + kAllowHarmonyDestructuringAssignment, kAllowHarmonyDestructuring, + kAllowHarmonyDefaultParameters}; + RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags, + arraysize(always_flags)); + + RunParserSyncTest(mixed_assignments_context_data, data, kSuccess, NULL, 0, + always_flags, arraysize(always_flags)); + + const char* empty_context_data[][2] = { + {"'use strict';", ""}, {"", ""}, {NULL, NULL}}; + + // CoverInitializedName ambiguity handling in various contexts + const char* ambiguity_data[] = { + "var foo = { x = 10 } = {};", + "var foo = { q } = { x = 10 } = {};", + "var foo; foo = { x = 10 } = {};", + "var foo; foo = { q } = { x = 10 } = {};", + "var x; ({ x = 10 } = {});", + "var q, x; ({ q } = { x = 10 } = {});", + "var x; [{ x = 10 } = {}]", + "var x; (true ? { x = true } = {} : { x = false } = {})", + "var q, x; (q, { x = 10 } = {});", + "var { x = 10 } = { x = 20 } = {};", + "var { x = 10 } = (o = { x = 20 } = {});", + "var x; (({ x = 10 } = { x = 20 } = {}) => x)({})", + NULL, + }; + RunParserSyncTest(empty_context_data, ambiguity_data, kSuccess, NULL, 0, + always_flags, arraysize(always_flags)); +} + + +TEST(DestructuringAssignmentNegativeTests) { + const char* context_data[][2] = { + {"'use strict'; let x, y, z; (", " = {});"}, + {"var x, y, z; (", " = {});"}, + {"'use strict'; let x, y, z; for (x in ", " = {});"}, + {"'use strict'; let x, y, z; for (x of ", " = {});"}, + {"var x, y, z; for (x in ", " = {});"}, + {"var x, y, z; for (x of ", " = {});"}, + {NULL, NULL}}; + + // clang-format off + const char* data[] = { + "{ x : ++y }", + "{ x : y * 2 }", + "{ ...x }", + "{ get x() {} }", + "{ set x() {} }", + "{ x: y() }", + "{ this }", + "{ x: this }", + "{ x: this = 1 }", + "{ super }", + "{ x: super }", + "{ x: super = 1 }", + "{ new.target }", + "{ x: new.target }", + "{ x: new.target = 1 }", + "[x--]", + "[--x = 1]", + "[x()]", + "[this]", + "[this = 1]", + "[new.target]", + "[new.target = 1]", + "[super]", + "[super = 1]", + "[function f() {}]", + "[50]", + "[(50)]", + "[(function() {})]", + "[(foo())]", + "{ x: 50 }", + "{ x: (50) }", + "['str']", + "{ x: 'str' }", + "{ x: ('str') }", + "{ x: (foo()) }", + "{ x: (function() {}) }", + "{ x: y } = 'str'", + "[x, y] = 'str'", + "[(x,y) => z]", + "{x: (y) => z}", + "[x, ...y, z]", + "[...x,]", + "[x, y, ...z = 1]", + "[...z = 1]", + + // v8:4657 + "({ x: x4, x: (x+=1e4) })", + "(({ x: x4, x: (x+=1e4) }))", + "({ x: x4, x: (x+=1e4) } = {})", + "(({ x: x4, x: (x+=1e4) } = {}))", + "(({ x: x4, x: (x+=1e4) }) = {})", + "({ x: y } = {})", + "(({ x: y } = {}))", + "(({ x: y }) = {})", + "([a])", + "(([a]))", + "([a] = [])", + "(([a] = []))", + "(([a]) = [])", + + // v8:4662 + "{ x: ([y]) }", + "{ x: ([y] = []) }", + "{ x: ({y}) }", + "{ x: ({y} = {}) }", + "{ x: (++y) }", + "[ (...[a]) ]", + "[ ...([a]) ]", + "[ ...([a] = [])", + "[ ...[ ( [ a ] ) ] ]", + "[ ([a]) ]", + "[ (...[a]) ]", + "[ ([a] = []) ]", + "[ (++y) ]", + "[ ...(++y) ]", + + "[ x += x ]", + "{ foo: x += x }", + + NULL}; + // clang-format on + static const ParserFlag always_flags[] = { + kAllowHarmonyDestructuringAssignment, kAllowHarmonyDestructuring, + kAllowHarmonyDefaultParameters}; + RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, + arraysize(always_flags)); + + const char* empty_context_data[][2] = { + {"'use strict';", ""}, {"", ""}, {NULL, NULL}}; + + // CoverInitializedName ambiguity handling in various contexts + const char* ambiguity_data[] = { + "var foo = { x = 10 };", + "var foo = { q } = { x = 10 };", + "var foo; foo = { x = 10 };", + "var foo; foo = { q } = { x = 10 };", + "var x; ({ x = 10 });", + "var q, x; ({ q } = { x = 10 });", + "var x; [{ x = 10 }]", + "var x; (true ? { x = true } : { x = false })", + "var q, x; (q, { x = 10 });", + "var { x = 10 } = { x = 20 };", + "var { x = 10 } = (o = { x = 20 });", + "var x; (({ x = 10 } = { x = 20 }) => x)({})", + + // Not ambiguous, but uses same context data + "switch([window %= []] = []) { default: }", + + NULL, + }; + RunParserSyncTest(empty_context_data, ambiguity_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); + + // Strict mode errors + const char* strict_context_data[][2] = {{"'use strict'; (", " = {})"}, + {"'use strict'; for (", " of {}) {}"}, + {"'use strict'; for (", " in {}) {}"}, + {NULL, NULL}}; + const char* strict_data[] = {"{ eval }", + "{ arguments }", + "{ foo: eval }", + "{ foo: arguments }", + "{ eval = 0 }", + "{ arguments = 0 }", + "{ foo: eval = 0 }", + "{ foo: arguments = 0 }", + "[ eval ]", + "[ arguments ]", + "[ eval = 0 ]", + "[ arguments = 0 ]", + + // v8:4662 + "{ x: (eval) }", + "{ x: (arguments) }", + "{ x: (eval = 0) }", + "{ x: (arguments = 0) }", + "{ x: (eval) = 0 }", + "{ x: (arguments) = 0 }", + "[ (eval) ]", + "[ (arguments) ]", + "[ (eval = 0) ]", + "[ (arguments = 0) ]", + "[ (eval) = 0 ]", + "[ (arguments) = 0 ]", + "[ ...(eval) ]", + "[ ...(arguments) ]", + "[ ...(eval = 0) ]", + "[ ...(arguments = 0) ]", + "[ ...(eval) = 0 ]", + "[ ...(arguments) = 0 ]", + + NULL}; + RunParserSyncTest(strict_context_data, strict_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); +} + + TEST(DestructuringDisallowPatternsInForVarIn) { - i::FLAG_harmony_destructuring = true; + i::FLAG_harmony_destructuring_bind = true; static const ParserFlag always_flags[] = {kAllowHarmonyDestructuring}; const char* context_data[][2] = { {"", ""}, {"function f() {", "}"}, {NULL, NULL}}; @@ -6800,7 +7202,7 @@ TEST(DestructuringDisallowPatternsInForVarIn) { TEST(DestructuringDuplicateParams) { - i::FLAG_harmony_destructuring = true; + i::FLAG_harmony_destructuring_bind = true; static const ParserFlag always_flags[] = {kAllowHarmonyDestructuring}; const char* context_data[][2] = {{"'use strict';", ""}, {"function outer() { 'use strict';", "}"}, @@ -6826,7 +7228,7 @@ TEST(DestructuringDuplicateParams) { TEST(DestructuringDuplicateParamsSloppy) { - i::FLAG_harmony_destructuring = true; + i::FLAG_harmony_destructuring_bind = true; static const ParserFlag always_flags[] = {kAllowHarmonyDestructuring}; const char* context_data[][2] = { {"", ""}, {"function outer() {", "}"}, {nullptr, nullptr}}; @@ -6847,7 +7249,7 @@ TEST(DestructuringDuplicateParamsSloppy) { TEST(DestructuringDisallowPatternsInSingleParamArrows) { - i::FLAG_harmony_destructuring = true; + i::FLAG_harmony_destructuring_bind = true; static const ParserFlag always_flags[] = {kAllowHarmonyDestructuring}; const char* context_data[][2] = {{"'use strict';", ""}, {"function outer() { 'use strict';", "}"}, @@ -6866,32 +7268,6 @@ TEST(DestructuringDisallowPatternsInSingleParamArrows) { } -TEST(DestructuringDisallowPatternsInRestParams) { - i::FLAG_harmony_destructuring = true; - i::FLAG_harmony_rest_parameters = true; - static const ParserFlag always_flags[] = {kAllowHarmonyRestParameters, - kAllowHarmonyDestructuring}; - const char* context_data[][2] = {{"'use strict';", ""}, - {"function outer() { 'use strict';", "}"}, - {"", ""}, - {"function outer() { ", "}"}, - {nullptr, nullptr}}; - - // clang-format off - const char* error_data[] = { - "function(...{}) {}", - "function(...{x}) {}", - "function(...[x]) {}", - "(...{}) => {}", - "(...{x}) => {}", - "(...[x]) => {}", - nullptr}; - // clang-format on - RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags, - arraysize(always_flags)); -} - - TEST(DefaultParametersYieldInInitializers) { // clang-format off const char* sloppy_function_context_data[][2] = { @@ -6968,9 +7344,8 @@ TEST(DefaultParametersYieldInInitializers) { kSuccess, NULL, 0, always_flags, arraysize(always_flags)); RunParserSyncTest(sloppy_arrow_context_data, parameter_data, kSuccess, NULL, 0, always_flags, arraysize(always_flags)); - // TODO(wingo): Will change to kSuccess when destructuring assignment lands. RunParserSyncTest(sloppy_arrow_context_data, destructuring_assignment_data, - kError, NULL, 0, always_flags, arraysize(always_flags)); + kSuccess, NULL, 0, always_flags, arraysize(always_flags)); RunParserSyncTest(strict_function_context_data, parameter_data, kError, NULL, 0, always_flags, arraysize(always_flags)); @@ -7233,7 +7608,7 @@ TEST(LanguageModeDirectivesNonSimpleParameterListErrors) { static const ParserFlag always_flags[] = { kAllowHarmonyDefaultParameters, kAllowHarmonyDestructuring, - kAllowHarmonyRestParameters, kAllowHarmonySloppy, kAllowStrongMode}; + kAllowHarmonySloppy, kAllowStrongMode}; RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags, arraysize(always_flags)); } @@ -7305,3 +7680,160 @@ TEST(LetSloppyOnly) { RunParserSyncTest(context_data, fail_data, kError, NULL, 0, fail_flags, arraysize(fail_flags)); } + + +TEST(EscapedKeywords) { + // clang-format off + const char* sloppy_context_data[][2] = { + {"", ""}, + {NULL, NULL} + }; + + const char* strict_context_data[][2] = { + {"'use strict';", ""}, + {NULL, NULL} + }; + + const char* fail_data[] = { + "for (var i = 0; i < 100; ++i) { br\\u0065ak; }", + "cl\\u0061ss Foo {}", + "var x = cl\\u0061ss {}", + "\\u0063onst foo = 1;", + "while (i < 10) { if (i++ & 1) c\\u006fntinue; this.x++; }", + "d\\u0065bugger;", + "d\\u0065lete this.a;", + "\\u0063o { } while(0)", + "if (d\\u006f { true }) {}", + "if (false) { this.a = 1; } \\u0065lse { this.b = 1; }", + "e\\u0078port var foo;", + "try { } catch (e) {} f\\u0069nally { }", + "f\\u006fr (var i = 0; i < 10; ++i);", + "f\\u0075nction fn() {}", + "var f = f\\u0075nction() {}", + "\\u0069f (true) { }", + "\\u0069mport blah from './foo.js';", + "n\\u0065w function f() {}", + "(function() { r\\u0065turn; })()", + "class C extends function() {} { constructor() { sup\\u0065r() } }", + "class C extends function() {} { constructor() { sup\\u0065r.a = 1 } }", + "sw\\u0069tch (this.a) {}", + "var x = th\\u0069s;", + "th\\u0069s.a = 1;", + "thr\\u006fw 'boo';", + "t\\u0072y { true } catch (e) {}", + "var x = typ\\u0065of 'blah'", + "v\\u0061r a = true", + "var v\\u0061r = true", + "(function() { return v\\u006fid 0; })()", + "wh\\u0069le (true) { }", + "w\\u0069th (this.scope) { }", + "(function*() { y\\u0069eld 1; })()", + + "var \\u0065num = 1;", + "var { \\u0065num } = {}", + "(\\u0065num = 1);", + + // Null / Boolean literals + "(x === n\\u0075ll);", + "var x = n\\u0075ll;", + "var n\\u0075ll = 1;", + "var { n\\u0075ll } = { 1 };", + "n\\u0075ll = 1;", + "(x === tr\\u0075e);", + "var x = tr\\u0075e;", + "var tr\\u0075e = 1;", + "var { tr\\u0075e } = {};", + "tr\\u0075e = 1;", + "(x === f\\u0061lse);", + "var x = f\\u0061lse;", + "var f\\u0061lse = 1;", + "var { f\\u0061lse } = {};", + "f\\u0061lse = 1;", + + // TODO(caitp): consistent error messages for labeled statements and + // expressions + "switch (this.a) { c\\u0061se 6: break; }", + "try { } c\\u0061tch (e) {}", + "switch (this.a) { d\\u0065fault: break; }", + "class C \\u0065xtends function B() {} {}", + "for (var a i\\u006e this) {}", + "if ('foo' \\u0069n this) {}", + "if (this \\u0069nstanceof Array) {}", + "(n\\u0065w function f() {})", + "(typ\\u0065of 123)", + "(v\\u006fid 0)", + "do { ; } wh\\u0069le (true) { }", + "(function*() { return (n++, y\\u0069eld 1); })()", + "class C { st\\u0061tic bar() {} }", + + "(y\\u0069eld);", + "var y\\u0069eld = 1;", + "var { y\\u0069eld } = {};", + NULL + }; + // clang-format on + + static const ParserFlag always_flags[] = {kAllowHarmonySloppy, + kAllowHarmonyDestructuring}; + RunParserSyncTest(sloppy_context_data, fail_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); + RunParserSyncTest(strict_context_data, fail_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); + RunModuleParserSyncTest(sloppy_context_data, fail_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); + + // clang-format off + const char* let_data[] = { + "var l\\u0065t = 1;", + "l\\u0065t = 1;", + "(l\\u0065t === 1);", + NULL + }; + // clang-format on + + RunParserSyncTest(sloppy_context_data, let_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); + RunParserSyncTest(strict_context_data, let_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); + + static const ParserFlag sloppy_let_flags[] = { + kAllowHarmonySloppy, kAllowHarmonySloppyLet, kAllowHarmonyDestructuring}; + RunParserSyncTest(sloppy_context_data, let_data, kError, NULL, 0, + sloppy_let_flags, arraysize(sloppy_let_flags)); + + // Non-errors in sloppy mode + const char* valid_data[] = {"(\\u0069mplements = 1);", + "var impl\\u0065ments = 1;", + "var { impl\\u0065ments } = {};", + "(\\u0069nterface = 1);", + "var int\\u0065rface = 1;", + "var { int\\u0065rface } = {};", + "(p\\u0061ckage = 1);", + "var packa\\u0067e = 1;", + "var { packa\\u0067e } = {};", + "(p\\u0072ivate = 1);", + "var p\\u0072ivate;", + "var { p\\u0072ivate } = {};", + "(prot\\u0065cted);", + "var prot\\u0065cted = 1;", + "var { prot\\u0065cted } = {};", + "(publ\\u0069c);", + "var publ\\u0069c = 1;", + "var { publ\\u0069c } = {};", + NULL}; + RunParserSyncTest(sloppy_context_data, valid_data, kSuccess, NULL, 0, + always_flags, arraysize(always_flags)); + RunParserSyncTest(strict_context_data, valid_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); + RunModuleParserSyncTest(strict_context_data, valid_data, kError, NULL, 0, + always_flags, arraysize(always_flags)); +} + + +TEST(MiscSyntaxErrors) { + const char* context_data[][2] = { + {"'use strict'", ""}, {"", ""}, {NULL, NULL}}; + const char* error_data[] = {"for (();;) {}", NULL}; + + RunParserSyncTest(context_data, error_data, kError, NULL, 0, NULL, 0); +} diff --git a/deps/v8/test/cctest/test-platform-linux.cc b/deps/v8/test/cctest/test-platform-linux.cc index abe43ad744..613638e78a 100644 --- a/deps/v8/test/cctest/test-platform-linux.cc +++ b/deps/v8/test/cctest/test-platform-linux.cc @@ -27,9 +27,6 @@ // // Tests of the TokenLock class from lock.h -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <pthread.h> #include <stdlib.h> #include <unistd.h> // for usleep() diff --git a/deps/v8/test/cctest/test-platform-win32.cc b/deps/v8/test/cctest/test-platform-win32.cc index 2d87d92f27..cecde74120 100644 --- a/deps/v8/test/cctest/test-platform-win32.cc +++ b/deps/v8/test/cctest/test-platform-win32.cc @@ -27,9 +27,6 @@ // // Tests of the TokenLock class from lock.h -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdlib.h> #include "src/v8.h" diff --git a/deps/v8/test/cctest/test-platform.cc b/deps/v8/test/cctest/test-platform.cc index 771be1fd09..2645a3dc18 100644 --- a/deps/v8/test/cctest/test-platform.cc +++ b/deps/v8/test/cctest/test-platform.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdint.h> #include "src/base/build_config.h" #include "src/base/platform/platform.h" diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc index 65d1a83bc4..82c0f30bd6 100644 --- a/deps/v8/test/cctest/test-profile-generator.cc +++ b/deps/v8/test/cctest/test-profile-generator.cc @@ -27,9 +27,6 @@ // // Tests of profiles generator and utilities. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "include/v8-profiler.h" @@ -51,7 +48,8 @@ using i::Vector; TEST(ProfileNodeFindOrAddChild) { - ProfileTree tree; + CcTest::InitializeVM(); + ProfileTree tree(CcTest::i_isolate()); ProfileNode* node = tree.root(); CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa"); ProfileNode* childNode1 = node->FindOrAddChild(&entry1); @@ -75,8 +73,9 @@ TEST(ProfileNodeFindOrAddChild) { TEST(ProfileNodeFindOrAddChildForSameFunction) { + CcTest::InitializeVM(); const char* aaa = "aaa"; - ProfileTree tree; + ProfileTree tree(CcTest::i_isolate()); ProfileNode* node = tree.root(); CodeEntry entry1(i::Logger::FUNCTION_TAG, aaa); ProfileNode* childNode1 = node->FindOrAddChild(&entry1); @@ -122,10 +121,11 @@ class ProfileTreeTestHelper { TEST(ProfileTreeAddPathFromEnd) { + CcTest::InitializeVM(); CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa"); CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb"); CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc"); - ProfileTree tree; + ProfileTree tree(CcTest::i_isolate()); ProfileTreeTestHelper helper(&tree); CHECK(!helper.Walk(&entry1)); CHECK(!helper.Walk(&entry2)); @@ -181,7 +181,8 @@ TEST(ProfileTreeAddPathFromEnd) { TEST(ProfileTreeCalculateTotalTicks) { - ProfileTree empty_tree; + CcTest::InitializeVM(); + ProfileTree empty_tree(CcTest::i_isolate()); CHECK_EQ(0u, empty_tree.root()->self_ticks()); empty_tree.root()->IncrementSelfTicks(); CHECK_EQ(1u, empty_tree.root()->self_ticks()); @@ -191,7 +192,7 @@ TEST(ProfileTreeCalculateTotalTicks) { Vector<CodeEntry*> e1_path_vec( e1_path, sizeof(e1_path) / sizeof(e1_path[0])); - ProfileTree single_child_tree; + ProfileTree single_child_tree(CcTest::i_isolate()); single_child_tree.AddPathFromEnd(e1_path_vec); single_child_tree.root()->IncrementSelfTicks(); CHECK_EQ(1u, single_child_tree.root()->self_ticks()); @@ -206,7 +207,7 @@ TEST(ProfileTreeCalculateTotalTicks) { Vector<CodeEntry*> e2_e1_path_vec(e2_e1_path, sizeof(e2_e1_path) / sizeof(e2_e1_path[0])); - ProfileTree flat_tree; + ProfileTree flat_tree(CcTest::i_isolate()); ProfileTreeTestHelper flat_helper(&flat_tree); flat_tree.AddPathFromEnd(e1_path_vec); flat_tree.AddPathFromEnd(e1_path_vec); @@ -233,7 +234,7 @@ TEST(ProfileTreeCalculateTotalTicks) { Vector<CodeEntry*> e3_path_vec( e3_path, sizeof(e3_path) / sizeof(e3_path[0])); - ProfileTree wide_tree; + ProfileTree wide_tree(CcTest::i_isolate()); ProfileTreeTestHelper wide_helper(&wide_tree); wide_tree.AddPathFromEnd(e1_path_vec); wide_tree.AddPathFromEnd(e1_path_vec); diff --git a/deps/v8/test/cctest/test-random-number-generator.cc b/deps/v8/test/cctest/test-random-number-generator.cc index f5e05cb396..8a855fe5d5 100644 --- a/deps/v8/test/cctest/test-random-number-generator.cc +++ b/deps/v8/test/cctest/test-random-number-generator.cc @@ -25,9 +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. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "test/cctest/cctest.h" @@ -51,3 +48,127 @@ TEST(RandomSeedFlagIsUsed) { i->Dispose(); } } + + +// Chi squared for getting m 0s out of n bits. +double ChiSquared(int m, int n) { + double ys_minus_np1 = (m - n / 2.0); + double chi_squared_1 = ys_minus_np1 * ys_minus_np1 * 2.0 / n; + double ys_minus_np2 = ((n - m) - n / 2.0); + double chi_squared_2 = ys_minus_np2 * ys_minus_np2 * 2.0 / n; + return chi_squared_1 + chi_squared_2; +} + + +// Test for correlations between recent bits from the PRNG, or bits that are +// biased. +void RandomBitCorrelation(int random_bit) { + FLAG_random_seed = 31415926; + v8::Isolate::CreateParams create_params; + create_params.array_buffer_allocator = CcTest::array_buffer_allocator(); + v8::Isolate* isolate = v8::Isolate::New(create_params); + Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate); + v8::base::RandomNumberGenerator* rng = i_isolate->random_number_generator(); +#ifdef DEBUG + const int kHistory = 2; + const int kRepeats = 1000; +#else + const int kHistory = 8; + const int kRepeats = 10000; +#endif + uint32_t history[kHistory]; + // The predictor bit is either constant 0 or 1, or one of the bits from the + // history. + for (int predictor_bit = -2; predictor_bit < 32; predictor_bit++) { + // The predicted bit is one of the bits from the PRNG. + for (int ago = 0; ago < kHistory; ago++) { + // We don't want to check whether each bit predicts itself. + if (ago == 0 && predictor_bit == random_bit) continue; + + // Enter the new random value into the history + for (int i = ago; i >= 0; i--) { + history[i] = bit_cast<uint32_t>(rng->NextInt()); + } + + // Find out how many of the bits are the same as the prediction bit. + int m = 0; + for (int i = 0; i < kRepeats; i++) { + v8::HandleScope scope(isolate); + uint32_t random = bit_cast<uint32_t>(rng->NextInt()); + for (int j = ago - 1; j >= 0; j--) history[j + 1] = history[j]; + history[0] = random; + + int predicted; + if (predictor_bit >= 0) { + predicted = (history[ago] >> predictor_bit) & 1; + } else { + predicted = predictor_bit == -2 ? 0 : 1; + } + int bit = (random >> random_bit) & 1; + if (bit == predicted) m++; + } + + // Chi squared analysis for k = 2 (2, states: same/not-same) and one + // degree of freedom (k - 1). + double chi_squared = ChiSquared(m, kRepeats); + if (chi_squared > 24) { + int percent = static_cast<int>(m * 100.0 / kRepeats); + if (predictor_bit < 0) { + PrintF("Bit %d is %d %d%% of the time\n", random_bit, + predictor_bit == -2 ? 0 : 1, percent); + } else { + PrintF("Bit %d is the same as bit %d %d ago %d%% of the time\n", + random_bit, predictor_bit, ago, percent); + } + } + + // For 1 degree of freedom this corresponds to 1 in a million. We are + // running ~8000 tests, so that would be surprising. + CHECK(chi_squared <= 24); + + // If the predictor bit is a fixed 0 or 1 then it makes no sense to + // repeat the test with a different age. + if (predictor_bit < 0) break; + } + } + isolate->Dispose(); +} + + +#define TEST_RANDOM_BIT(BIT) \ + TEST(RandomBitCorrelations##BIT) { RandomBitCorrelation(BIT); } + +TEST_RANDOM_BIT(0) +TEST_RANDOM_BIT(1) +TEST_RANDOM_BIT(2) +TEST_RANDOM_BIT(3) +TEST_RANDOM_BIT(4) +TEST_RANDOM_BIT(5) +TEST_RANDOM_BIT(6) +TEST_RANDOM_BIT(7) +TEST_RANDOM_BIT(8) +TEST_RANDOM_BIT(9) +TEST_RANDOM_BIT(10) +TEST_RANDOM_BIT(11) +TEST_RANDOM_BIT(12) +TEST_RANDOM_BIT(13) +TEST_RANDOM_BIT(14) +TEST_RANDOM_BIT(15) +TEST_RANDOM_BIT(16) +TEST_RANDOM_BIT(17) +TEST_RANDOM_BIT(18) +TEST_RANDOM_BIT(19) +TEST_RANDOM_BIT(20) +TEST_RANDOM_BIT(21) +TEST_RANDOM_BIT(22) +TEST_RANDOM_BIT(23) +TEST_RANDOM_BIT(24) +TEST_RANDOM_BIT(25) +TEST_RANDOM_BIT(26) +TEST_RANDOM_BIT(27) +TEST_RANDOM_BIT(28) +TEST_RANDOM_BIT(29) +TEST_RANDOM_BIT(30) +TEST_RANDOM_BIT(31) + +#undef TEST_RANDOM_BIT diff --git a/deps/v8/test/cctest/test-receiver-check-hidden-prototype.cc b/deps/v8/test/cctest/test-receiver-check-hidden-prototype.cc new file mode 100644 index 0000000000..90ed8e7b56 --- /dev/null +++ b/deps/v8/test/cctest/test-receiver-check-hidden-prototype.cc @@ -0,0 +1,73 @@ +// 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 <stdlib.h> + +#include "include/v8-experimental.h" +#include "src/v8.h" +#include "test/cctest/cctest.h" + +namespace { + + +static void SlowCallback(const v8::FunctionCallbackInfo<v8::Value>& info) { + info.GetReturnValue().Set(41); +} + + +TEST(CompatibleReceiverBuiltin) { + // Check that the HandleFastApiCall builtin visits the hidden prototypes + // during the compatible receiver check. + LocalContext context; + v8::Isolate* isolate = context->GetIsolate(); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Context> current_context = isolate->GetCurrentContext(); + + v8::Local<v8::FunctionTemplate> constructor_template = + v8::FunctionTemplate::New(isolate); + v8::Local<v8::FunctionTemplate> prototype_template = + v8::FunctionTemplate::New(isolate); + prototype_template->SetHiddenPrototype(true); + + v8::Local<v8::ObjectTemplate> proto_instance_template = + prototype_template->InstanceTemplate(); + + v8::experimental::FastAccessorBuilder* fast_accessor_builder = + v8::experimental::FastAccessorBuilder::New(isolate); + fast_accessor_builder->ReturnValue( + fast_accessor_builder->IntegerConstant(42)); + v8::Local<v8::FunctionTemplate> accessor_template = + v8::FunctionTemplate::NewWithFastHandler( + isolate, SlowCallback, fast_accessor_builder, v8::Local<v8::Value>(), + v8::Signature::New(isolate, prototype_template)); + + proto_instance_template->SetAccessorProperty( + v8_str("bar"), accessor_template, v8::Local<v8::FunctionTemplate>(), + v8::ReadOnly); + + v8::Local<v8::Object> object = + constructor_template->GetFunction(current_context) + .ToLocalChecked() + ->NewInstance(current_context) + .ToLocalChecked(); + + v8::Local<v8::Object> hidden_prototype = + prototype_template->GetFunction(current_context) + .ToLocalChecked() + ->NewInstance(current_context) + .ToLocalChecked(); + + CHECK(object->SetPrototype(current_context, hidden_prototype).FromJust()); + + context->Global() + ->Set(current_context, v8_str("object"), object) + .FromMaybe(false); + + CHECK_EQ(42, CompileRun("var getter = object.__lookupGetter__('bar');" + "getter.call(object)") + ->Int32Value(current_context) + .FromJust()); +} + +} // namespace diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc index 2e236c20f3..a91058cc24 100644 --- a/deps/v8/test/cctest/test-regexp.cc +++ b/deps/v8/test/cctest/test-regexp.cc @@ -25,21 +25,19 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <cstdlib> #include <sstream> +#include "include/v8.h" #include "src/v8.h" -#include "src/ast.h" +#include "src/ast/ast.h" #include "src/char-predicates-inl.h" #include "src/ostreams.h" -#include "src/parser.h" #include "src/regexp/jsregexp.h" #include "src/regexp/regexp-macro-assembler.h" #include "src/regexp/regexp-macro-assembler-irregexp.h" +#include "src/regexp/regexp-parser.h" #include "src/splay-tree-inl.h" #include "src/string-stream.h" #ifdef V8_INTERPRETED_REGEXP @@ -102,17 +100,21 @@ static bool CheckParse(const char* input) { } -static void CheckParseEq(const char* input, const char* expected) { +static void CheckParseEq(const char* input, const char* expected, + bool unicode = false) { v8::HandleScope scope(CcTest::isolate()); Zone zone; FlatStringReader reader(CcTest::i_isolate(), CStrVector(input)); RegExpCompileData result; CHECK(v8::internal::RegExpParser::ParseRegExp( - CcTest::i_isolate(), &zone, &reader, false, false, &result)); + CcTest::i_isolate(), &zone, &reader, false, unicode, &result)); CHECK(result.tree != NULL); CHECK(result.error.is_null()); std::ostringstream os; result.tree->Print(os, &zone); + if (strcmp(expected, os.str().c_str()) != 0) { + printf("%s | %s\n", expected, os.str().c_str()); + } CHECK_EQ(0, strcmp(expected, os.str().c_str())); } @@ -159,7 +161,11 @@ static MinMaxPair CheckMinMaxMatch(const char* input) { CHECK_EQ(max, min_max.max_match); \ } -TEST(Parser) { + +void TestRegExpParser(bool lookbehind) { + FLAG_harmony_regexp_lookbehind = lookbehind; + FLAG_harmony_unicode_regexps = true; + CHECK_PARSE_ERROR("?"); CheckParseEq("abc", "'abc'"); @@ -191,6 +197,13 @@ TEST(Parser) { CheckParseEq("foo|(bar|baz)|quux", "(| 'foo' (^ (| 'bar' 'baz')) 'quux')"); CheckParseEq("foo(?=bar)baz", "(: 'foo' (-> + 'bar') 'baz')"); CheckParseEq("foo(?!bar)baz", "(: 'foo' (-> - 'bar') 'baz')"); + if (lookbehind) { + CheckParseEq("foo(?<=bar)baz", "(: 'foo' (<- + 'bar') 'baz')"); + CheckParseEq("foo(?<!bar)baz", "(: 'foo' (<- - 'bar') 'baz')"); + } else { + CHECK_PARSE_ERROR("foo(?<=bar)baz"); + CHECK_PARSE_ERROR("foo(?<!bar)baz"); + } CheckParseEq("()", "(^ %)"); CheckParseEq("(?=)", "(-> + %)"); CheckParseEq("[]", "^[\\x00-\\uffff]"); // Doesn't compile on windows @@ -262,14 +275,22 @@ TEST(Parser) { CheckParseEq("(a)\\1", "(: (^ 'a') (<- 1))"); CheckParseEq("(a\\1)", "(^ 'a')"); CheckParseEq("(\\1a)", "(^ 'a')"); + CheckParseEq("(\\2)(\\1)", "(: (^ (<- 2)) (^ (<- 1)))"); CheckParseEq("(?=a)?a", "'a'"); CheckParseEq("(?=a){0,10}a", "'a'"); CheckParseEq("(?=a){1,10}a", "(: (-> + 'a') 'a')"); CheckParseEq("(?=a){9,10}a", "(: (-> + 'a') 'a')"); CheckParseEq("(?!a)?a", "'a'"); - CheckParseEq("\\1(a)", "(^ 'a')"); + CheckParseEq("\\1(a)", "(: (<- 1) (^ 'a'))"); CheckParseEq("(?!(a))\\1", "(: (-> - (^ 'a')) (<- 1))"); - CheckParseEq("(?!\\1(a\\1)\\1)\\1", "(: (-> - (: (^ 'a') (<- 1))) (<- 1))"); + CheckParseEq("(?!\\1(a\\1)\\1)\\1", + "(: (-> - (: (<- 1) (^ 'a') (<- 1))) (<- 1))"); + CheckParseEq("\\1\\2(a(?:\\1(b\\1\\2))\\2)\\1", + "(: (<- 1) (<- 2) (^ (: 'a' (^ 'b') (<- 2))) (<- 1))"); + if (lookbehind) { + CheckParseEq("\\1\\2(a(?<=\\1(b\\1\\2))\\2)\\1", + "(: (<- 1) (<- 2) (^ (: 'a' (<- + (^ 'b')) (<- 2))) (<- 1))"); + } CheckParseEq("[\\0]", "[\\x00]"); CheckParseEq("[\\11]", "[\\x09]"); CheckParseEq("[\\11a]", "[\\x09 a]"); @@ -286,6 +307,15 @@ TEST(Parser) { CheckParseEq("\\u003z", "'u003z'"); CheckParseEq("foo[z]*", "(: 'foo' (# 0 - g [z]))"); + // Unicode regexps + CheckParseEq("\\u{12345}", "'\\ud808\\udf45'", true); + CheckParseEq("\\u{12345}\\u{23456}", "(! '\\ud808\\udf45' '\\ud84d\\udc56')", + true); + CheckParseEq("\\u{12345}|\\u{23456}", "(| '\\ud808\\udf45' '\\ud84d\\udc56')", + true); + CheckParseEq("\\u{12345}{3}", "(# 3 3 g '\\ud808\\udf45')", true); + CheckParseEq("\\u{12345}*", "(# 0 - g '\\ud808\\udf45')", true); + CHECK_SIMPLE("", false); CHECK_SIMPLE("a", true); CHECK_SIMPLE("a|b", false); @@ -361,8 +391,8 @@ TEST(Parser) { CHECK_MIN_MAX("(?:ab)|cde", 2, 3); CHECK_MIN_MAX("(ab)", 2, 2); CHECK_MIN_MAX("(ab|cde)", 2, 3); - CHECK_MIN_MAX("(ab)\\1", 2, 4); - CHECK_MIN_MAX("(ab|cde)\\1", 2, 6); + CHECK_MIN_MAX("(ab)\\1", 2, RegExpTree::kInfinity); + CHECK_MIN_MAX("(ab|cde)\\1", 2, RegExpTree::kInfinity); CHECK_MIN_MAX("(?:ab)?", 0, 2); CHECK_MIN_MAX("(?:ab)*", 0, RegExpTree::kInfinity); CHECK_MIN_MAX("(?:ab)+", 2, RegExpTree::kInfinity); @@ -400,6 +430,16 @@ TEST(Parser) { } +TEST(ParserWithLookbehind) { + TestRegExpParser(true); // Lookbehind enabled. +} + + +TEST(ParserWithoutLookbehind) { + TestRegExpParser(true); // Lookbehind enabled. +} + + TEST(ParserRegression) { CheckParseEq("[A-Z$-][x]", "(! [A-Z $ -] [x])"); CheckParseEq("a{3,4*}", "(: 'a{3,' (# 0 - g '4') '}')"); @@ -790,7 +830,7 @@ TEST(MacroAssemblerNativeSimple) { Label fail, backtrack; m.PushBacktrack(&fail); - m.CheckNotAtStart(NULL); + m.CheckNotAtStart(0, NULL); m.LoadCurrentCharacter(2, NULL); m.CheckNotCharacter('o', NULL); m.LoadCurrentCharacter(1, NULL, false); @@ -857,7 +897,7 @@ TEST(MacroAssemblerNativeSimpleUC16) { Label fail, backtrack; m.PushBacktrack(&fail); - m.CheckNotAtStart(NULL); + m.CheckNotAtStart(0, NULL); m.LoadCurrentCharacter(2, NULL); m.CheckNotCharacter('o', NULL); m.LoadCurrentCharacter(1, NULL, false); @@ -973,12 +1013,12 @@ TEST(MacroAssemblerNativeBackReferenceLATIN1) { m.AdvanceCurrentPosition(2); m.WriteCurrentPositionToRegister(1, 0); Label nomatch; - m.CheckNotBackReference(0, &nomatch); + m.CheckNotBackReference(0, false, &nomatch); m.Fail(); m.Bind(&nomatch); m.AdvanceCurrentPosition(2); Label missing_match; - m.CheckNotBackReference(0, &missing_match); + m.CheckNotBackReference(0, false, &missing_match); m.WriteCurrentPositionToRegister(2, 0); m.Succeed(); m.Bind(&missing_match); @@ -1023,12 +1063,12 @@ TEST(MacroAssemblerNativeBackReferenceUC16) { m.AdvanceCurrentPosition(2); m.WriteCurrentPositionToRegister(1, 0); Label nomatch; - m.CheckNotBackReference(0, &nomatch); + m.CheckNotBackReference(0, false, &nomatch); m.Fail(); m.Bind(&nomatch); m.AdvanceCurrentPosition(2); Label missing_match; - m.CheckNotBackReference(0, &missing_match); + m.CheckNotBackReference(0, false, &missing_match); m.WriteCurrentPositionToRegister(2, 0); m.Succeed(); m.Bind(&missing_match); @@ -1073,7 +1113,7 @@ TEST(MacroAssemblernativeAtStart) { 0); Label not_at_start, newline, fail; - m.CheckNotAtStart(¬_at_start); + m.CheckNotAtStart(0, ¬_at_start); // Check that prevchar = '\n' and current = 'f'. m.CheckCharacter('\n', &newline); m.Bind(&fail); @@ -1138,16 +1178,16 @@ TEST(MacroAssemblerNativeBackRefNoCase) { m.WriteCurrentPositionToRegister(2, 0); m.AdvanceCurrentPosition(3); m.WriteCurrentPositionToRegister(3, 0); - m.CheckNotBackReferenceIgnoreCase(2, &fail); // Match "AbC". - m.CheckNotBackReferenceIgnoreCase(2, &fail); // Match "ABC". + m.CheckNotBackReferenceIgnoreCase(2, false, &fail); // Match "AbC". + m.CheckNotBackReferenceIgnoreCase(2, false, &fail); // Match "ABC". Label expected_fail; - m.CheckNotBackReferenceIgnoreCase(2, &expected_fail); + m.CheckNotBackReferenceIgnoreCase(2, false, &expected_fail); m.Bind(&fail); m.Fail(); m.Bind(&expected_fail); m.AdvanceCurrentPosition(3); // Skip "xYz" - m.CheckNotBackReferenceIgnoreCase(2, &succ); + m.CheckNotBackReferenceIgnoreCase(2, false, &succ); m.Fail(); m.Bind(&succ); @@ -1339,7 +1379,7 @@ TEST(MacroAssemblerNativeLotsOfRegisters) { m.WriteCurrentPositionToRegister(0, 0); m.WriteCurrentPositionToRegister(1, 1); Label done; - m.CheckNotBackReference(0, &done); // Performs a system-stack push. + m.CheckNotBackReference(0, false, &done); // Performs a system-stack push. m.Bind(&done); m.PushRegister(large_number, RegExpMacroAssembler::kNoStackLimitCheck); m.PopRegister(1); @@ -1388,7 +1428,7 @@ TEST(MacroAssembler) { m.Fail(); m.Bind(&start); m.PushBacktrack(&fail); - m.CheckNotAtStart(NULL); + m.CheckNotAtStart(0, NULL); m.LoadCurrentCharacter(0, NULL); m.CheckNotCharacter('f', NULL); m.LoadCurrentCharacter(1, NULL); @@ -1678,26 +1718,26 @@ TEST(CanonicalizeCharacterSets) { list->Add(CharacterRange(30, 40), &zone); list->Add(CharacterRange(50, 60), &zone); set.Canonicalize(); - DCHECK_EQ(3, list->length()); - DCHECK_EQ(10, list->at(0).from()); - DCHECK_EQ(20, list->at(0).to()); - DCHECK_EQ(30, list->at(1).from()); - DCHECK_EQ(40, list->at(1).to()); - DCHECK_EQ(50, list->at(2).from()); - DCHECK_EQ(60, list->at(2).to()); + CHECK_EQ(3, list->length()); + CHECK_EQ(10, list->at(0).from()); + CHECK_EQ(20, list->at(0).to()); + CHECK_EQ(30, list->at(1).from()); + CHECK_EQ(40, list->at(1).to()); + CHECK_EQ(50, list->at(2).from()); + CHECK_EQ(60, list->at(2).to()); list->Rewind(0); list->Add(CharacterRange(10, 20), &zone); list->Add(CharacterRange(50, 60), &zone); list->Add(CharacterRange(30, 40), &zone); set.Canonicalize(); - DCHECK_EQ(3, list->length()); - DCHECK_EQ(10, list->at(0).from()); - DCHECK_EQ(20, list->at(0).to()); - DCHECK_EQ(30, list->at(1).from()); - DCHECK_EQ(40, list->at(1).to()); - DCHECK_EQ(50, list->at(2).from()); - DCHECK_EQ(60, list->at(2).to()); + CHECK_EQ(3, list->length()); + CHECK_EQ(10, list->at(0).from()); + CHECK_EQ(20, list->at(0).to()); + CHECK_EQ(30, list->at(1).from()); + CHECK_EQ(40, list->at(1).to()); + CHECK_EQ(50, list->at(2).from()); + CHECK_EQ(60, list->at(2).to()); list->Rewind(0); list->Add(CharacterRange(30, 40), &zone); @@ -1706,26 +1746,26 @@ TEST(CanonicalizeCharacterSets) { list->Add(CharacterRange(100, 100), &zone); list->Add(CharacterRange(1, 1), &zone); set.Canonicalize(); - DCHECK_EQ(5, list->length()); - DCHECK_EQ(1, list->at(0).from()); - DCHECK_EQ(1, list->at(0).to()); - DCHECK_EQ(10, list->at(1).from()); - DCHECK_EQ(20, list->at(1).to()); - DCHECK_EQ(25, list->at(2).from()); - DCHECK_EQ(25, list->at(2).to()); - DCHECK_EQ(30, list->at(3).from()); - DCHECK_EQ(40, list->at(3).to()); - DCHECK_EQ(100, list->at(4).from()); - DCHECK_EQ(100, list->at(4).to()); + CHECK_EQ(5, list->length()); + CHECK_EQ(1, list->at(0).from()); + CHECK_EQ(1, list->at(0).to()); + CHECK_EQ(10, list->at(1).from()); + CHECK_EQ(20, list->at(1).to()); + CHECK_EQ(25, list->at(2).from()); + CHECK_EQ(25, list->at(2).to()); + CHECK_EQ(30, list->at(3).from()); + CHECK_EQ(40, list->at(3).to()); + CHECK_EQ(100, list->at(4).from()); + CHECK_EQ(100, list->at(4).to()); list->Rewind(0); list->Add(CharacterRange(10, 19), &zone); list->Add(CharacterRange(21, 30), &zone); list->Add(CharacterRange(20, 20), &zone); set.Canonicalize(); - DCHECK_EQ(1, list->length()); - DCHECK_EQ(10, list->at(0).from()); - DCHECK_EQ(30, list->at(0).to()); + CHECK_EQ(1, list->length()); + CHECK_EQ(10, list->at(0).from()); + CHECK_EQ(30, list->at(0).to()); } @@ -1807,8 +1847,8 @@ TEST(CharacterRangeMerge) { offset += 9; } - DCHECK(CharacterRange::IsCanonical(&l1)); - DCHECK(CharacterRange::IsCanonical(&l2)); + CHECK(CharacterRange::IsCanonical(&l1)); + CHECK(CharacterRange::IsCanonical(&l2)); ZoneList<CharacterRange> first_only(4, &zone); ZoneList<CharacterRange> second_only(4, &zone); @@ -1819,3 +1859,82 @@ TEST(CharacterRangeMerge) { TEST(Graph) { Execute("\\b\\w+\\b", false, true, true); } + + +namespace { + +int* global_use_counts = NULL; + +void MockUseCounterCallback(v8::Isolate* isolate, + v8::Isolate::UseCounterFeature feature) { + ++global_use_counts[feature]; +} +} + + +// Test that ES2015 RegExp compatibility fixes are in place, that they +// are not overly broad, and the appropriate UseCounters are incremented +TEST(UseCountRegExp) { + i::FLAG_harmony_regexps = true; + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + LocalContext env; + int use_counts[v8::Isolate::kUseCounterFeatureCount] = {}; + global_use_counts = use_counts; + CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback); + + // Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it + v8::Local<v8::Value> resultSticky = CompileRun("RegExp.prototype.sticky"); + CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]); + CHECK_EQ(0, use_counts[v8::Isolate::kRegExpPrototypeToString]); + CHECK(resultSticky->IsUndefined()); + + // re.sticky has approriate value and doesn't touch UseCounter + v8::Local<v8::Value> resultReSticky = CompileRun("/a/.sticky"); + CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]); + CHECK_EQ(0, use_counts[v8::Isolate::kRegExpPrototypeToString]); + CHECK(resultReSticky->IsFalse()); + + // When the getter is caleld on another object, throw an exception + // and don't increment the UseCounter + v8::Local<v8::Value> resultStickyError = CompileRun( + "var exception;" + "try { " + " Object.getOwnPropertyDescriptor(RegExp.prototype, 'sticky')" + " .get.call(null);" + "} catch (e) {" + " exception = e;" + "}" + "exception"); + CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]); + CHECK_EQ(0, use_counts[v8::Isolate::kRegExpPrototypeToString]); + CHECK(resultStickyError->IsObject()); + + // RegExp.prototype.toString() returns '/(?:)/' as a compatibility fix; + // a UseCounter is incremented to track it. + v8::Local<v8::Value> resultToString = + CompileRun("RegExp.prototype.toString().length"); + CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]); + CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]); + CHECK(resultToString->IsInt32()); + CHECK_EQ(6, + resultToString->Int32Value(isolate->GetCurrentContext()).FromJust()); + + // .toString() works on normal RegExps + v8::Local<v8::Value> resultReToString = CompileRun("/a/.toString().length"); + CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]); + CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]); + CHECK(resultReToString->IsInt32()); + CHECK_EQ( + 3, resultReToString->Int32Value(isolate->GetCurrentContext()).FromJust()); + + // .toString() throws on non-RegExps that aren't RegExp.prototype + v8::Local<v8::Value> resultToStringError = CompileRun( + "var exception;" + "try { RegExp.prototype.toString.call(null) }" + "catch (e) { exception = e; }" + "exception"); + CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]); + CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]); + CHECK(resultToStringError->IsObject()); +} diff --git a/deps/v8/test/cctest/test-reloc-info.cc b/deps/v8/test/cctest/test-reloc-info.cc index d2a780ba62..4346f0083e 100644 --- a/deps/v8/test/cctest/test-reloc-info.cc +++ b/deps/v8/test/cctest/test-reloc-info.cc @@ -25,10 +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. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/assembler.h" +#include "src/macro-assembler.h" #include "test/cctest/cctest.h" namespace v8 { @@ -36,7 +34,7 @@ namespace internal { static void WriteRinfo(RelocInfoWriter* writer, byte* pc, RelocInfo::Mode mode, intptr_t data) { - RelocInfo rinfo(pc, mode, data, NULL); + RelocInfo rinfo(CcTest::i_isolate(), pc, mode, data, NULL); writer->Write(&rinfo); } @@ -44,6 +42,7 @@ static void WriteRinfo(RelocInfoWriter* writer, // Tests that writing both types of positions and then reading either // or both works as expected. TEST(Positions) { + CcTest::InitializeVM(); const int code_size = 10 * KB; int relocation_info_size = 10 * KB; const int buffer_size = code_size + relocation_info_size; @@ -68,8 +67,9 @@ TEST(Positions) { writer.Finish(); relocation_info_size = static_cast<int>(buffer_end - writer.pos()); - CodeDesc desc = {buffer.get(), buffer_size, code_size, relocation_info_size, - 0, NULL}; + MacroAssembler assm(CcTest::i_isolate(), nullptr, 0, CodeObjectRequired::kNo); + CodeDesc desc = {buffer.get(), buffer_size, code_size, + relocation_info_size, 0, &assm}; // Read only (non-statement) positions. { diff --git a/deps/v8/test/cctest/test-representation.cc b/deps/v8/test/cctest/test-representation.cc index 43dbc394c4..fc1f531331 100644 --- a/deps/v8/test/cctest/test-representation.cc +++ b/deps/v8/test/cctest/test-representation.cc @@ -25,9 +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. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "test/cctest/cctest.h" #include "src/property-details.h" diff --git a/deps/v8/test/cctest/test-sampler-api.cc b/deps/v8/test/cctest/test-sampler-api.cc index 3506c4b38b..2cc15f816a 100644 --- a/deps/v8/test/cctest/test-sampler-api.cc +++ b/deps/v8/test/cctest/test-sampler-api.cc @@ -4,9 +4,6 @@ // // Tests the sampling API in include/v8.h -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <map> #include <string> #include "include/v8.h" @@ -94,7 +91,7 @@ class SamplingTestHelper { explicit SamplingTestHelper(const std::string& test_function) : sample_is_taken_(false), isolate_(CcTest::isolate()) { - DCHECK(!instance_); + CHECK(!instance_); instance_ = this; v8::HandleScope scope(isolate_); v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate_); diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc index 644b04a78a..2f29b25fab 100644 --- a/deps/v8/test/cctest/test-serialize.cc +++ b/deps/v8/test/cctest/test-serialize.cc @@ -25,27 +25,25 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <signal.h> #include <sys/stat.h> #include "src/v8.h" +#include "src/ast/scopeinfo.h" #include "src/bootstrapper.h" #include "src/compilation-cache.h" #include "src/debug/debug.h" #include "src/heap/spaces.h" #include "src/objects.h" -#include "src/parser.h" +#include "src/parsing/parser.h" #include "src/runtime/runtime.h" -#include "src/scopeinfo.h" #include "src/snapshot/natives.h" #include "src/snapshot/serialize.h" #include "src/snapshot/snapshot.h" #include "test/cctest/cctest.h" +#include "test/cctest/heap/utils-inl.h" using namespace v8::internal; @@ -95,7 +93,8 @@ void WritePayload(const Vector<const byte>& payload, const char* file_name) { static bool WriteToFile(Isolate* isolate, const char* snapshot_file) { SnapshotByteSink sink; StartupSerializer ser(isolate, &sink); - ser.Serialize(); + ser.SerializeStrongReferences(); + ser.SerializeWeakReferencesAndDeferred(); SnapshotData snapshot_data(ser); WritePayload(snapshot_data.RawData(), snapshot_file); return true; @@ -294,7 +293,7 @@ UNINITIALIZED_TEST(PartialSerialization) { HandleScope scope(isolate); env.Reset(v8_isolate, v8::Context::New(v8_isolate)); } - DCHECK(!env.IsEmpty()); + CHECK(!env.IsEmpty()); { v8::HandleScope handle_scope(v8_isolate); v8::Local<v8::Context>::New(v8_isolate, env)->Enter(); @@ -313,7 +312,7 @@ UNINITIALIZED_TEST(PartialSerialization) { { v8::HandleScope handle_scope(v8_isolate); v8::Local<v8::String> foo = v8_str("foo"); - DCHECK(!foo.IsEmpty()); + CHECK(!foo.IsEmpty()); raw_foo = *(v8::Utils::OpenHandle(*foo)); } @@ -372,17 +371,14 @@ UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) { Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); HandleScope handle_scope(isolate); Handle<Object> root; - Handle<FixedArray> outdated_contexts; // Intentionally empty handle. The deserializer should not come across // any references to the global proxy in this test. Handle<JSGlobalProxy> global_proxy = Handle<JSGlobalProxy>::null(); { SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size)); Deserializer deserializer(&snapshot_data); - root = - deserializer.DeserializePartial(isolate, global_proxy, - &outdated_contexts).ToHandleChecked(); - CHECK_EQ(0, outdated_contexts->length()); + root = deserializer.DeserializePartial(isolate, global_proxy) + .ToHandleChecked(); CHECK(root->IsString()); } @@ -390,9 +386,8 @@ UNINITIALIZED_DEPENDENT_TEST(PartialDeserialization, PartialSerialization) { { SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size)); Deserializer deserializer(&snapshot_data); - root2 = - deserializer.DeserializePartial(isolate, global_proxy, - &outdated_contexts).ToHandleChecked(); + root2 = deserializer.DeserializePartial(isolate, global_proxy) + .ToHandleChecked(); CHECK(root2->IsString()); CHECK(root.is_identical_to(root2)); } @@ -417,7 +412,7 @@ UNINITIALIZED_TEST(ContextSerialization) { HandleScope scope(isolate); env.Reset(v8_isolate, v8::Context::New(v8_isolate)); } - DCHECK(!env.IsEmpty()); + CHECK(!env.IsEmpty()); { v8::HandleScope handle_scope(v8_isolate); v8::Local<v8::Context>::New(v8_isolate, env)->Enter(); @@ -489,27 +484,23 @@ UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) { Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); HandleScope handle_scope(isolate); Handle<Object> root; - Handle<FixedArray> outdated_contexts; Handle<JSGlobalProxy> global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy(); { SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size)); Deserializer deserializer(&snapshot_data); - root = - deserializer.DeserializePartial(isolate, global_proxy, - &outdated_contexts).ToHandleChecked(); + root = deserializer.DeserializePartial(isolate, global_proxy) + .ToHandleChecked(); CHECK(root->IsContext()); CHECK(Handle<Context>::cast(root)->global_proxy() == *global_proxy); - CHECK_EQ(2, outdated_contexts->length()); } Handle<Object> root2; { SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size)); Deserializer deserializer(&snapshot_data); - root2 = - deserializer.DeserializePartial(isolate, global_proxy, - &outdated_contexts).ToHandleChecked(); + root2 = deserializer.DeserializePartial(isolate, global_proxy) + .ToHandleChecked(); CHECK(root2->IsContext()); CHECK(!root.is_identical_to(root2)); } @@ -532,7 +523,7 @@ UNINITIALIZED_TEST(CustomContextSerialization) { HandleScope scope(isolate); env.Reset(v8_isolate, v8::Context::New(v8_isolate)); } - DCHECK(!env.IsEmpty()); + CHECK(!env.IsEmpty()); { v8::HandleScope handle_scope(v8_isolate); v8::Local<v8::Context>::New(v8_isolate, env)->Enter(); @@ -543,7 +534,7 @@ UNINITIALIZED_TEST(CustomContextSerialization) { " e = function(s) { return eval (s); }" "})();" "var o = this;" - "var r = Math.random() + Math.cos(0);" + "var r = Math.sin(0) + Math.cos(0);" "var f = (function(a, b) { return a + b; }).bind(1, 2, 3);" "var s = parseInt('12345');"); @@ -626,20 +617,13 @@ UNINITIALIZED_DEPENDENT_TEST(CustomContextDeserialization, Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate); HandleScope handle_scope(isolate); Handle<Object> root; - Handle<FixedArray> outdated_contexts; Handle<JSGlobalProxy> global_proxy = isolate->factory()->NewUninitializedJSGlobalProxy(); { SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size)); Deserializer deserializer(&snapshot_data); - root = - deserializer.DeserializePartial(isolate, global_proxy, - &outdated_contexts).ToHandleChecked(); - if (FLAG_global_var_shortcuts) { - CHECK_EQ(5, outdated_contexts->length()); - } else { - CHECK_EQ(3, outdated_contexts->length()); - } + root = deserializer.DeserializePartial(isolate, global_proxy) + .ToHandleChecked(); CHECK(root->IsContext()); Handle<Context> context = Handle<Context>::cast(root); CHECK(context->global_proxy() == *global_proxy); @@ -654,7 +638,7 @@ UNINITIALIZED_DEPENDENT_TEST(CustomContextDeserialization, ->ToNumber(v8_isolate->GetCurrentContext()) .ToLocalChecked() ->Value(); - CHECK(r >= 1 && r <= 2); + CHECK_EQ(1, r); int f = CompileRun("f()") ->ToNumber(v8_isolate->GetCurrentContext()) .ToLocalChecked() @@ -1528,7 +1512,7 @@ TEST(SerializeToplevelIsolates) { ->Equals(isolate2->GetCurrentContext(), v8_str("abcdef")) .FromJust()); } - DCHECK(toplevel_test_code_event_found); + CHECK(toplevel_test_code_event_found); isolate2->Dispose(); } diff --git a/deps/v8/test/cctest/test-simd.cc b/deps/v8/test/cctest/test-simd.cc index 98c6c7f9df..1f412affba 100644 --- a/deps/v8/test/cctest/test-simd.cc +++ b/deps/v8/test/cctest/test-simd.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "src/objects.h" diff --git a/deps/v8/test/cctest/test-slots-buffer.cc b/deps/v8/test/cctest/test-slots-buffer.cc index c23cfdfc51..07b70f5217 100644 --- a/deps/v8/test/cctest/test-slots-buffer.cc +++ b/deps/v8/test/cctest/test-slots-buffer.cc @@ -2,11 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/heap/slots-buffer.h" #include "test/cctest/cctest.h" +#include "test/cctest/heap/utils-inl.h" namespace v8 { namespace internal { diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc index 6e0ee04a9c..e992f33c8b 100644 --- a/deps/v8/test/cctest/test-strings.cc +++ b/deps/v8/test/cctest/test-strings.cc @@ -79,7 +79,7 @@ class MyRandomNumberGenerator { } bool next(double threshold) { - DCHECK(threshold >= 0.0 && threshold <= 1.0); + CHECK(threshold >= 0.0 && threshold <= 1.0); if (threshold == 1.0) return true; if (threshold == 0.0) return false; uint32_t value = next() % 100000; @@ -191,9 +191,9 @@ static void InitializeBuildingBlocks(Handle<String>* building_blocks, buf[j] = rng->next(0x10000); } Resource* resource = new Resource(buf, len); - building_blocks[i] = - v8::Utils::OpenHandle( - *v8::String::NewExternal(CcTest::isolate(), resource)); + building_blocks[i] = v8::Utils::OpenHandle( + *v8::String::NewExternalTwoByte(CcTest::isolate(), resource) + .ToLocalChecked()); for (int j = 0; j < len; j++) { CHECK_EQ(buf[j], building_blocks[i]->Get(j)); } @@ -205,9 +205,9 @@ static void InitializeBuildingBlocks(Handle<String>* building_blocks, buf[j] = rng->next(0x80); } OneByteResource* resource = new OneByteResource(buf, len); - building_blocks[i] = - v8::Utils::OpenHandle( - *v8::String::NewExternal(CcTest::isolate(), resource)); + building_blocks[i] = v8::Utils::OpenHandle( + *v8::String::NewExternalOneByte(CcTest::isolate(), resource) + .ToLocalChecked()); for (int j = 0; j < len; j++) { CHECK_EQ(buf[j], building_blocks[i]->Get(j)); } @@ -880,8 +880,10 @@ TEST(Utf8Conversion) { // A simple one-byte string const char* one_byte_string = "abcdef12345"; int len = v8::String::NewFromUtf8(CcTest::isolate(), one_byte_string, - v8::String::kNormalString, - StrLength(one_byte_string))->Utf8Length(); + v8::NewStringType::kNormal, + StrLength(one_byte_string)) + .ToLocalChecked() + ->Utf8Length(); CHECK_EQ(StrLength(one_byte_string), len); // A mixed one-byte and two-byte string // U+02E4 -> CB A4 @@ -896,8 +898,10 @@ TEST(Utf8Conversion) { // The number of bytes expected to be written for each length const int lengths[12] = {0, 0, 2, 3, 3, 3, 6, 7, 7, 7, 10, 11}; const int char_lengths[12] = {0, 0, 1, 2, 2, 2, 3, 4, 4, 4, 5, 5}; - v8::Handle<v8::String> mixed = v8::String::NewFromTwoByte( - CcTest::isolate(), mixed_string, v8::String::kNormalString, 5); + v8::Local<v8::String> mixed = + v8::String::NewFromTwoByte(CcTest::isolate(), mixed_string, + v8::NewStringType::kNormal, 5) + .ToLocalChecked(); CHECK_EQ(10, mixed->Utf8Length()); // Try encoding the string with all capacities char buffer[11]; @@ -929,9 +933,9 @@ TEST(ExternalShortStringAdd) { CHECK_GT(kMaxLength, i::ConsString::kMinLength); // Allocate two JavaScript arrays for holding short strings. - v8::Handle<v8::Array> one_byte_external_strings = + v8::Local<v8::Array> one_byte_external_strings = v8::Array::New(CcTest::isolate(), kMaxLength + 1); - v8::Handle<v8::Array> non_one_byte_external_strings = + v8::Local<v8::Array> non_one_byte_external_strings = v8::Array::New(CcTest::isolate(), kMaxLength + 1); // Generate short one-byte and two-byte external strings. @@ -944,10 +948,13 @@ TEST(ExternalShortStringAdd) { // string data. OneByteResource* one_byte_resource = new OneByteResource(one_byte, i); v8::Local<v8::String> one_byte_external_string = - v8::String::NewExternal(CcTest::isolate(), one_byte_resource); + v8::String::NewExternalOneByte(CcTest::isolate(), one_byte_resource) + .ToLocalChecked(); - one_byte_external_strings->Set(v8::Integer::New(CcTest::isolate(), i), - one_byte_external_string); + one_byte_external_strings->Set(context.local(), + v8::Integer::New(CcTest::isolate(), i), + one_byte_external_string) + .FromJust(); uc16* non_one_byte = NewArray<uc16>(i + 1); for (int j = 0; j < i; j++) { non_one_byte[j] = 0x1234; @@ -956,17 +963,25 @@ TEST(ExternalShortStringAdd) { // string data. Resource* resource = new Resource(non_one_byte, i); v8::Local<v8::String> non_one_byte_external_string = - v8::String::NewExternal(CcTest::isolate(), resource); - non_one_byte_external_strings->Set(v8::Integer::New(CcTest::isolate(), i), - non_one_byte_external_string); + v8::String::NewExternalTwoByte(CcTest::isolate(), resource) + .ToLocalChecked(); + non_one_byte_external_strings->Set(context.local(), + v8::Integer::New(CcTest::isolate(), i), + non_one_byte_external_string) + .FromJust(); } // Add the arrays with the short external strings in the global object. - v8::Handle<v8::Object> global = context->Global(); - global->Set(v8_str("external_one_byte"), one_byte_external_strings); - global->Set(v8_str("external_non_one_byte"), non_one_byte_external_strings); - global->Set(v8_str("max_length"), - v8::Integer::New(CcTest::isolate(), kMaxLength)); + v8::Local<v8::Object> global = context->Global(); + global->Set(context.local(), v8_str("external_one_byte"), + one_byte_external_strings) + .FromJust(); + global->Set(context.local(), v8_str("external_non_one_byte"), + non_one_byte_external_strings) + .FromJust(); + global->Set(context.local(), v8_str("max_length"), + v8::Integer::New(CcTest::isolate(), kMaxLength)) + .FromJust(); // Add short external one-byte and two-byte strings checking the result. static const char* source = @@ -1012,7 +1027,7 @@ TEST(ExternalShortStringAdd) { " return 0;" "};" "test()"; - CHECK_EQ(0, CompileRun(source)->Int32Value()); + CHECK_EQ(0, CompileRun(source)->Int32Value(context.local()).FromJust()); } @@ -1021,14 +1036,19 @@ TEST(JSONStringifySliceMadeExternal) { // Create a sliced string from a one-byte string. The latter is turned // into a two-byte external string. Check that JSON.stringify works. v8::HandleScope handle_scope(CcTest::isolate()); - v8::Handle<v8::String> underlying = + v8::Local<v8::String> underlying = CompileRun( "var underlying = 'abcdefghijklmnopqrstuvwxyz';" - "underlying")->ToString(CcTest::isolate()); - v8::Handle<v8::String> slice = CompileRun( - "var slice = '';" - "slice = underlying.slice(1);" - "slice")->ToString(CcTest::isolate()); + "underlying") + ->ToString(CcTest::isolate()->GetCurrentContext()) + .ToLocalChecked(); + v8::Local<v8::String> slice = + CompileRun( + "var slice = '';" + "slice = underlying.slice(1);" + "slice") + ->ToString(CcTest::isolate()->GetCurrentContext()) + .ToLocalChecked(); CHECK(v8::Utils::OpenHandle(*slice)->IsSlicedString()); CHECK(v8::Utils::OpenHandle(*underlying)->IsSeqOneByteString()); @@ -1079,16 +1099,23 @@ TEST(CachedHashOverflow) { }; const char* line; + v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); for (int i = 0; (line = lines[i]); i++) { printf("%s\n", line); - v8::Local<v8::Value> result = v8::Script::Compile( - v8::String::NewFromUtf8(CcTest::isolate(), line))->Run(); + v8::Local<v8::Value> result = + v8::Script::Compile(context, + v8::String::NewFromUtf8(CcTest::isolate(), line, + v8::NewStringType::kNormal) + .ToLocalChecked()) + .ToLocalChecked() + ->Run(context) + .ToLocalChecked(); CHECK_EQ(results[i]->IsUndefined(), result->IsUndefined()); CHECK_EQ(results[i]->IsNumber(), result->IsNumber()); if (result->IsNumber()) { int32_t value = 0; CHECK(results[i]->ToInt32(&value)); - CHECK_EQ(value, result->ToInt32(CcTest::isolate())->Value()); + CHECK_EQ(value, result->ToInt32(context).ToLocalChecked()->Value()); } } } @@ -1320,7 +1347,8 @@ TEST(CountBreakIterator) { " return iterator.next();" "})();"); CHECK(result->IsNumber()); - int uses = result->ToInt32(CcTest::isolate())->Value() == 0 ? 0 : 1; + int uses = + result->ToInt32(context.local()).ToLocalChecked()->Value() == 0 ? 0 : 1; CHECK_EQ(uses, use_counts[v8::Isolate::kBreakIterator]); // Make sure GC cleans up the break iterator, so we don't get a memory leak // reported by ASAN. @@ -1341,7 +1369,7 @@ TEST(StringReplaceAtomTwoByteResult) { CHECK(string->IsSeqTwoByteString()); v8::Local<v8::String> expected = v8_str("one_byte\x80only\x80string\x80"); - CHECK(expected->Equals(result)); + CHECK(expected->Equals(context.local(), result).FromJust()); } @@ -1477,6 +1505,6 @@ TEST(FormatMessage) { MessageTemplate::FormatMessage(MessageTemplate::kPropertyNotFunction, arg0, arg1, arg2).ToHandleChecked(); Handle<String> expected = isolate->factory()->NewStringFromAsciiChecked( - "Property 'arg0' of object arg1 is not a function"); + "'arg0' returned for property 'arg1' of object 'arg2' is not a function"); CHECK(String::Equals(result, expected)); } diff --git a/deps/v8/test/cctest/test-strtod.cc b/deps/v8/test/cctest/test-strtod.cc index ccefe321aa..7c1118603e 100644 --- a/deps/v8/test/cctest/test-strtod.cc +++ b/deps/v8/test/cctest/test-strtod.cc @@ -25,9 +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. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdlib.h> #include "src/v8.h" diff --git a/deps/v8/test/cctest/test-symbols.cc b/deps/v8/test/cctest/test-symbols.cc index ff4a672390..1024a27edf 100644 --- a/deps/v8/test/cctest/test-symbols.cc +++ b/deps/v8/test/cctest/test-symbols.cc @@ -30,9 +30,6 @@ // of ConsStrings. These operations may not be very fast, but they // should be possible without getting errors due to too deep recursion. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "src/objects.h" diff --git a/deps/v8/test/cctest/test-thread-termination.cc b/deps/v8/test/cctest/test-thread-termination.cc index b39deef144..05a3c3339e 100644 --- a/deps/v8/test/cctest/test-thread-termination.cc +++ b/deps/v8/test/cctest/test-thread-termination.cc @@ -25,9 +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. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "test/cctest/cctest.h" diff --git a/deps/v8/test/cctest/test-threads.cc b/deps/v8/test/cctest/test-threads.cc index 71dd49f50b..a9058a523a 100644 --- a/deps/v8/test/cctest/test-threads.cc +++ b/deps/v8/test/cctest/test-threads.cc @@ -25,9 +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. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "test/cctest/cctest.h" diff --git a/deps/v8/test/cctest/test-trace-event.cc b/deps/v8/test/cctest/test-trace-event.cc new file mode 100644 index 0000000000..a889e088f6 --- /dev/null +++ b/deps/v8/test/cctest/test-trace-event.cc @@ -0,0 +1,258 @@ +// 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 <stdlib.h> +#include <string.h> + +#include "src/v8.h" + +#include "src/list.h" +#include "src/list-inl.h" +#include "test/cctest/cctest.h" + +using v8::IdleTask; +using v8::Task; +using v8::Isolate; + +#include "src/tracing/trace-event.h" + +#define GET_TRACE_OBJECTS_LIST platform.GetMockTraceObjects() + +#define GET_TRACE_OBJECT(Index) GET_TRACE_OBJECTS_LIST->at(Index) + + +struct MockTraceObject { + char phase; + std::string name; + uint64_t id; + uint64_t bind_id; + int num_args; + unsigned int flags; + MockTraceObject(char phase, std::string name, uint64_t id, uint64_t bind_id, + int num_args, int flags) + : phase(phase), + name(name), + id(id), + bind_id(bind_id), + num_args(num_args), + flags(flags) {} +}; + +typedef v8::internal::List<MockTraceObject*> MockTraceObjectList; + +class MockTracingPlatform : public v8::Platform { + public: + explicit MockTracingPlatform(v8::Platform* platform) {} + virtual ~MockTracingPlatform() { + for (int i = 0; i < trace_object_list_.length(); ++i) { + delete trace_object_list_[i]; + } + trace_object_list_.Clear(); + } + void CallOnBackgroundThread(Task* task, + ExpectedRuntime expected_runtime) override {} + + void CallOnForegroundThread(Isolate* isolate, Task* task) override {} + + void CallDelayedOnForegroundThread(Isolate* isolate, Task* task, + double delay_in_seconds) override {} + + double MonotonicallyIncreasingTime() override { return 0.0; } + + void CallIdleOnForegroundThread(Isolate* isolate, IdleTask* task) override {} + + bool IdleTasksEnabled(Isolate* isolate) override { return false; } + + bool PendingIdleTask() { return false; } + + void PerformIdleTask(double idle_time_in_seconds) {} + + bool PendingDelayedTask() { return false; } + + void PerformDelayedTask() {} + + uint64_t AddTraceEvent(char phase, const uint8_t* category_enabled_flag, + const char* name, uint64_t id, uint64_t bind_id, + int num_args, const char** arg_names, + const uint8_t* arg_types, const uint64_t* arg_values, + unsigned int flags) override { + MockTraceObject* to = new MockTraceObject(phase, std::string(name), id, + bind_id, num_args, flags); + trace_object_list_.Add(to); + return 0; + } + + void UpdateTraceEventDuration(const uint8_t* category_enabled_flag, + const char* name, uint64_t handle) override {} + + const uint8_t* GetCategoryGroupEnabled(const char* name) override { + if (strcmp(name, "v8-cat")) { + static uint8_t no = 0; + return &no; + } else { + static uint8_t yes = 0x7; + return &yes; + } + } + + const char* GetCategoryGroupName( + const uint8_t* category_enabled_flag) override { + static const char dummy[] = "dummy"; + return dummy; + } + + MockTraceObjectList* GetMockTraceObjects() { return &trace_object_list_; } + + private: + MockTraceObjectList trace_object_list_; +}; + + +TEST(TraceEventDisabledCategory) { + v8::Platform* old_platform = i::V8::GetCurrentPlatform(); + MockTracingPlatform platform(old_platform); + i::V8::SetPlatformForTesting(&platform); + + // Disabled category, will not add events. + TRACE_EVENT_BEGIN0("cat", "e1"); + TRACE_EVENT_END0("cat", "e1"); + CHECK_EQ(0, GET_TRACE_OBJECTS_LIST->length()); + + i::V8::SetPlatformForTesting(old_platform); +} + + +TEST(TraceEventNoArgs) { + v8::Platform* old_platform = i::V8::GetCurrentPlatform(); + MockTracingPlatform platform(old_platform); + i::V8::SetPlatformForTesting(&platform); + + // Enabled category will add 2 events. + TRACE_EVENT_BEGIN0("v8-cat", "e1"); + TRACE_EVENT_END0("v8-cat", "e1"); + + CHECK_EQ(2, GET_TRACE_OBJECTS_LIST->length()); + CHECK_EQ('B', GET_TRACE_OBJECT(0)->phase); + CHECK_EQ("e1", GET_TRACE_OBJECT(0)->name); + CHECK_EQ(0, GET_TRACE_OBJECT(0)->num_args); + + CHECK_EQ('E', GET_TRACE_OBJECT(1)->phase); + CHECK_EQ("e1", GET_TRACE_OBJECT(1)->name); + CHECK_EQ(0, GET_TRACE_OBJECT(1)->num_args); + + i::V8::SetPlatformForTesting(old_platform); +} + + +TEST(TraceEventWithOneArg) { + v8::Platform* old_platform = i::V8::GetCurrentPlatform(); + MockTracingPlatform platform(old_platform); + i::V8::SetPlatformForTesting(&platform); + + TRACE_EVENT_BEGIN1("v8-cat", "e1", "arg1", 42); + TRACE_EVENT_END1("v8-cat", "e1", "arg1", 42); + TRACE_EVENT_BEGIN1("v8-cat", "e2", "arg1", "abc"); + TRACE_EVENT_END1("v8-cat", "e2", "arg1", "abc"); + + CHECK_EQ(4, GET_TRACE_OBJECTS_LIST->length()); + + CHECK_EQ(1, GET_TRACE_OBJECT(0)->num_args); + CHECK_EQ(1, GET_TRACE_OBJECT(1)->num_args); + CHECK_EQ(1, GET_TRACE_OBJECT(2)->num_args); + CHECK_EQ(1, GET_TRACE_OBJECT(3)->num_args); + + i::V8::SetPlatformForTesting(old_platform); +} + + +TEST(TraceEventWithTwoArgs) { + v8::Platform* old_platform = i::V8::GetCurrentPlatform(); + MockTracingPlatform platform(old_platform); + i::V8::SetPlatformForTesting(&platform); + + TRACE_EVENT_BEGIN2("v8-cat", "e1", "arg1", 42, "arg2", "abc"); + TRACE_EVENT_END2("v8-cat", "e1", "arg1", 42, "arg2", "abc"); + TRACE_EVENT_BEGIN2("v8-cat", "e2", "arg1", "abc", "arg2", 43); + TRACE_EVENT_END2("v8-cat", "e2", "arg1", "abc", "arg2", 43); + + CHECK_EQ(4, GET_TRACE_OBJECTS_LIST->length()); + + CHECK_EQ(2, GET_TRACE_OBJECT(0)->num_args); + CHECK_EQ(2, GET_TRACE_OBJECT(1)->num_args); + CHECK_EQ(2, GET_TRACE_OBJECT(2)->num_args); + CHECK_EQ(2, GET_TRACE_OBJECT(3)->num_args); + + i::V8::SetPlatformForTesting(old_platform); +} + + +TEST(ScopedTraceEvent) { + v8::Platform* old_platform = i::V8::GetCurrentPlatform(); + MockTracingPlatform platform(old_platform); + i::V8::SetPlatformForTesting(&platform); + + { TRACE_EVENT0("v8-cat", "e"); } + + CHECK_EQ(1, GET_TRACE_OBJECTS_LIST->length()); + CHECK_EQ(0, GET_TRACE_OBJECT(0)->num_args); + + { TRACE_EVENT1("v8-cat", "e1", "arg1", "abc"); } + + CHECK_EQ(2, GET_TRACE_OBJECTS_LIST->length()); + CHECK_EQ(1, GET_TRACE_OBJECT(1)->num_args); + + { TRACE_EVENT2("v8-cat", "e1", "arg1", "abc", "arg2", 42); } + + CHECK_EQ(3, GET_TRACE_OBJECTS_LIST->length()); + CHECK_EQ(2, GET_TRACE_OBJECT(2)->num_args); + + i::V8::SetPlatformForTesting(old_platform); +} + + +TEST(TestEventWithFlow) { + v8::Platform* old_platform = i::V8::GetCurrentPlatform(); + MockTracingPlatform platform(old_platform); + i::V8::SetPlatformForTesting(&platform); + + static uint64_t bind_id = 21; + { + TRACE_EVENT_WITH_FLOW0("v8-cat", "f1", bind_id, TRACE_EVENT_FLAG_FLOW_OUT); + } + { + TRACE_EVENT_WITH_FLOW0( + "v8-cat", "f2", bind_id, + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + } + { TRACE_EVENT_WITH_FLOW0("v8-cat", "f3", bind_id, TRACE_EVENT_FLAG_FLOW_IN); } + + CHECK_EQ(3, GET_TRACE_OBJECTS_LIST->length()); + CHECK_EQ(bind_id, GET_TRACE_OBJECT(0)->bind_id); + CHECK_EQ(TRACE_EVENT_FLAG_FLOW_OUT, GET_TRACE_OBJECT(0)->flags); + CHECK_EQ(bind_id, GET_TRACE_OBJECT(1)->bind_id); + CHECK_EQ(TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, + GET_TRACE_OBJECT(1)->flags); + CHECK_EQ(bind_id, GET_TRACE_OBJECT(2)->bind_id); + CHECK_EQ(TRACE_EVENT_FLAG_FLOW_IN, GET_TRACE_OBJECT(2)->flags); + + i::V8::SetPlatformForTesting(old_platform); +} + + +TEST(TestEventWithId) { + v8::Platform* old_platform = i::V8::GetCurrentPlatform(); + MockTracingPlatform platform(old_platform); + i::V8::SetPlatformForTesting(&platform); + + static uint64_t event_id = 21; + TRACE_EVENT_ASYNC_BEGIN0("v8-cat", "a1", event_id); + TRACE_EVENT_ASYNC_END0("v8-cat", "a1", event_id); + + CHECK_EQ(2, GET_TRACE_OBJECTS_LIST->length()); + CHECK_EQ(TRACE_EVENT_PHASE_ASYNC_BEGIN, GET_TRACE_OBJECT(0)->phase); + CHECK_EQ(event_id, GET_TRACE_OBJECT(0)->id); + CHECK_EQ(TRACE_EVENT_PHASE_ASYNC_END, GET_TRACE_OBJECT(1)->phase); + CHECK_EQ(event_id, GET_TRACE_OBJECT(1)->id); + + i::V8::SetPlatformForTesting(old_platform); +} diff --git a/deps/v8/test/cctest/test-transitions.cc b/deps/v8/test/cctest/test-transitions.cc index 60a0706b04..8834f9ade1 100644 --- a/deps/v8/test/cctest/test-transitions.cc +++ b/deps/v8/test/cctest/test-transitions.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdlib.h> #include <utility> @@ -87,7 +84,9 @@ TEST(TransitionArray_SimpleFieldTransitions) { (key == *name2 && target == *map2)); } - DCHECK(TransitionArray::IsSortedNoDuplicates(*map0)); +#ifdef DEBUG + CHECK(TransitionArray::IsSortedNoDuplicates(*map0)); +#endif } @@ -136,7 +135,9 @@ TEST(TransitionArray_FullFieldTransitions) { (key == *name2 && target == *map2)); } - DCHECK(TransitionArray::IsSortedNoDuplicates(*map0)); +#ifdef DEBUG + CHECK(TransitionArray::IsSortedNoDuplicates(*map0)); +#endif } @@ -183,7 +184,9 @@ TEST(TransitionArray_DifferentFieldNames) { } } - DCHECK(TransitionArray::IsSortedNoDuplicates(*map0)); +#ifdef DEBUG + CHECK(TransitionArray::IsSortedNoDuplicates(*map0)); +#endif } @@ -224,7 +227,9 @@ TEST(TransitionArray_SameFieldNamesDifferentAttributesSimple) { CHECK_EQ(*name, TransitionArray::GetKey(map0->raw_transitions(), i)); } - DCHECK(TransitionArray::IsSortedNoDuplicates(*map0)); +#ifdef DEBUG + CHECK(TransitionArray::IsSortedNoDuplicates(*map0)); +#endif } @@ -302,5 +307,7 @@ TEST(TransitionArray_SameFieldNamesDifferentAttributes) { } } - DCHECK(TransitionArray::IsSortedNoDuplicates(*map0)); +#ifdef DEBUG + CHECK(TransitionArray::IsSortedNoDuplicates(*map0)); +#endif } diff --git a/deps/v8/test/cctest/test-typedarrays.cc b/deps/v8/test/cctest/test-typedarrays.cc index f55c560a28..348eb05a3a 100644 --- a/deps/v8/test/cctest/test-typedarrays.cc +++ b/deps/v8/test/cctest/test-typedarrays.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdlib.h> #include "src/v8.h" diff --git a/deps/v8/test/cctest/test-types.cc b/deps/v8/test/cctest/test-types.cc index dda36de46f..4549654501 100644 --- a/deps/v8/test/cctest/test-types.cc +++ b/deps/v8/test/cctest/test-types.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <vector> #include "src/crankshaft/hydrogen-types.h" diff --git a/deps/v8/test/cctest/test-typing-reset.cc b/deps/v8/test/cctest/test-typing-reset.cc index 9102e1fca0..4e9413ac3a 100644 --- a/deps/v8/test/cctest/test-typing-reset.cc +++ b/deps/v8/test/cctest/test-typing-reset.cc @@ -2,18 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdlib.h> #include "src/v8.h" -#include "src/ast.h" -#include "src/ast-expression-visitor.h" -#include "src/parser.h" -#include "src/rewriter.h" -#include "src/scopes.h" +#include "src/ast/ast.h" +#include "src/ast/ast-expression-visitor.h" +#include "src/ast/scopes.h" +#include "src/parsing/parser.h" +#include "src/parsing/rewriter.h" #include "src/typing-reset.h" #include "test/cctest/cctest.h" #include "test/cctest/compiler/function-tester.h" diff --git a/deps/v8/test/cctest/test-unbound-queue.cc b/deps/v8/test/cctest/test-unbound-queue.cc index a19b783392..48e344aaa6 100644 --- a/deps/v8/test/cctest/test-unbound-queue.cc +++ b/deps/v8/test/cctest/test-unbound-queue.cc @@ -27,9 +27,6 @@ // // Tests of the unbound queue. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "test/cctest/cctest.h" diff --git a/deps/v8/test/cctest/test-unboxed-doubles.cc b/deps/v8/test/cctest/test-unboxed-doubles.cc index 3dd56ee09e..3906d848de 100644 --- a/deps/v8/test/cctest/test-unboxed-doubles.cc +++ b/deps/v8/test/cctest/test-unboxed-doubles.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(mythria): Remove this define after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdlib.h> #include <utility> @@ -18,7 +15,7 @@ #include "src/ic/ic.h" #include "src/macro-assembler.h" #include "test/cctest/cctest.h" -#include "test/cctest/heap-tester.h" +#include "test/cctest/heap/utils-inl.h" using namespace v8::base; using namespace v8::internal; @@ -54,10 +51,12 @@ static Handle<String> MakeName(const char* str, int suffix) { Handle<JSObject> GetObject(const char* name) { - return v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( - CcTest::global() - ->Get(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str(name)) - .ToLocalChecked())); + return Handle<JSObject>::cast( + v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast( + CcTest::global() + ->Get(v8::Isolate::GetCurrent()->GetCurrentContext(), + v8_str(name)) + .ToLocalChecked()))); } @@ -66,7 +65,7 @@ static double GetDoubleFieldValue(JSObject* obj, FieldIndex field_index) { return obj->RawFastDoublePropertyAt(field_index); } else { Object* value = obj->RawFastPropertyAt(field_index); - DCHECK(value->IsMutableHeapNumber()); + CHECK(value->IsMutableHeapNumber()); return HeapNumber::cast(value)->value(); } } @@ -742,22 +741,41 @@ TEST(LayoutDescriptorAppendAllDoubles) { static Handle<LayoutDescriptor> TestLayoutDescriptorAppendIfFastOrUseFull( Isolate* isolate, int inobject_properties, Handle<DescriptorArray> descriptors, int number_of_descriptors) { - Handle<Map> map = Map::Create(isolate, inobject_properties); + Handle<Map> initial_map = Map::Create(isolate, inobject_properties); Handle<LayoutDescriptor> full_layout_descriptor = LayoutDescriptor::New( - map, descriptors, descriptors->number_of_descriptors()); + initial_map, descriptors, descriptors->number_of_descriptors()); int nof = 0; bool switched_to_slow_mode = false; - for (int i = 0; i < number_of_descriptors; i++) { - PropertyDetails details = descriptors->GetDetails(i); + // This method calls LayoutDescriptor::AppendIfFastOrUseFull() internally + // and does all the required map-descriptors related book keeping. + Handle<Map> last_map = Map::AddMissingTransitionsForTesting( + initial_map, descriptors, full_layout_descriptor); - // This method calls LayoutDescriptor::AppendIfFastOrUseFull() internally - // and does all the required map-descriptors related book keeping. - map = Map::CopyInstallDescriptorsForTesting(map, i, descriptors, - full_layout_descriptor); + // Follow back pointers to construct a sequence of maps from |map| + // to |last_map|. + int descriptors_length = descriptors->number_of_descriptors(); + std::vector<Handle<Map>> maps(descriptors_length); + { + CHECK(last_map->is_stable()); + Map* map = *last_map; + for (int i = 0; i < descriptors_length; i++) { + maps[descriptors_length - 1 - i] = handle(map, isolate); + Object* maybe_map = map->GetBackPointer(); + CHECK(maybe_map->IsMap()); + map = Map::cast(maybe_map); + CHECK(!map->is_stable()); + } + CHECK_EQ(1, maps[0]->NumberOfOwnDescriptors()); + } + Handle<Map> map; + // Now check layout descriptors of all intermediate maps. + for (int i = 0; i < number_of_descriptors; i++) { + PropertyDetails details = descriptors->GetDetails(i); + map = maps[i]; LayoutDescriptor* layout_desc = map->layout_descriptor(); if (layout_desc->IsSlowLayout()) { diff --git a/deps/v8/test/cctest/test-unique.cc b/deps/v8/test/cctest/test-unique.cc index 56990edfd3..207c2450a0 100644 --- a/deps/v8/test/cctest/test-unique.cc +++ b/deps/v8/test/cctest/test-unique.cc @@ -25,9 +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. -// TODO(mythria): Remove this after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdlib.h> #include "src/v8.h" diff --git a/deps/v8/test/cctest/test-unscopables-hidden-prototype.cc b/deps/v8/test/cctest/test-unscopables-hidden-prototype.cc index 50db316537..de0976825d 100644 --- a/deps/v8/test/cctest/test-unscopables-hidden-prototype.cc +++ b/deps/v8/test/cctest/test-unscopables-hidden-prototype.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(mythria): Remove this after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdlib.h> #include "src/v8.h" diff --git a/deps/v8/test/cctest/test-utils-arm64.cc b/deps/v8/test/cctest/test-utils-arm64.cc index f125cc09bf..bd1ff998b9 100644 --- a/deps/v8/test/cctest/test-utils-arm64.cc +++ b/deps/v8/test/cctest/test-utils-arm64.cc @@ -25,9 +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. -// TODO(mythria): Remove this after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "src/arm64/utils-arm64.h" @@ -98,7 +95,7 @@ bool EqualFP64(double expected, const RegisterDump*, double result) { bool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg) { - DCHECK(reg.Is32Bits()); + CHECK(reg.Is32Bits()); // Retrieve the corresponding X register so we can check that the upper part // was properly cleared. int64_t result_x = core->xreg(reg.code()); @@ -115,7 +112,7 @@ bool Equal32(uint32_t expected, const RegisterDump* core, const Register& reg) { bool Equal64(uint64_t expected, const RegisterDump* core, const Register& reg) { - DCHECK(reg.Is64Bits()); + CHECK(reg.Is64Bits()); uint64_t result = core->xreg(reg.code()); return Equal64(expected, core, result); } @@ -124,7 +121,7 @@ bool Equal64(uint64_t expected, bool EqualFP32(float expected, const RegisterDump* core, const FPRegister& fpreg) { - DCHECK(fpreg.Is32Bits()); + CHECK(fpreg.Is32Bits()); // Retrieve the corresponding D register so we can check that the upper part // was properly cleared. uint64_t result_64 = core->dreg_bits(fpreg.code()); @@ -141,7 +138,7 @@ bool EqualFP32(float expected, bool EqualFP64(double expected, const RegisterDump* core, const FPRegister& fpreg) { - DCHECK(fpreg.Is64Bits()); + CHECK(fpreg.Is64Bits()); return EqualFP64(expected, core, core->dreg(fpreg.code())); } @@ -149,7 +146,7 @@ bool EqualFP64(double expected, bool Equal64(const Register& reg0, const RegisterDump* core, const Register& reg1) { - DCHECK(reg0.Is64Bits() && reg1.Is64Bits()); + CHECK(reg0.Is64Bits() && reg1.Is64Bits()); int64_t expected = core->xreg(reg0.code()); int64_t result = core->xreg(reg1.code()); return Equal64(expected, core, result); @@ -177,8 +174,8 @@ static char FlagV(uint32_t flags) { bool EqualNzcv(uint32_t expected, uint32_t result) { - DCHECK((expected & ~NZCVFlag) == 0); - DCHECK((result & ~NZCVFlag) == 0); + CHECK((expected & ~NZCVFlag) == 0); + CHECK((result & ~NZCVFlag) == 0); if (result != expected) { printf("Expected: %c%c%c%c\t Found: %c%c%c%c\n", FlagN(expected), FlagZ(expected), FlagC(expected), FlagV(expected), @@ -234,7 +231,7 @@ RegList PopulateRegisterArray(Register* w, Register* x, Register* r, } } // Check that we got enough registers. - DCHECK(CountSetBits(list, kNumberOfRegisters) == reg_count); + CHECK(CountSetBits(list, kNumberOfRegisters) == reg_count); return list; } @@ -261,7 +258,7 @@ RegList PopulateFPRegisterArray(FPRegister* s, FPRegister* d, FPRegister* v, } } // Check that we got enough registers. - DCHECK(CountSetBits(list, kNumberOfFPRegisters) == reg_count); + CHECK(CountSetBits(list, kNumberOfFPRegisters) == reg_count); return list; } @@ -273,7 +270,7 @@ void Clobber(MacroAssembler* masm, RegList reg_list, uint64_t const value) { if (reg_list & (1UL << i)) { Register xn = Register::Create(i, kXRegSizeInBits); // We should never write into csp here. - DCHECK(!xn.Is(csp)); + CHECK(!xn.Is(csp)); if (!xn.IsZero()) { if (!first.IsValid()) { // This is the first register we've hit, so construct the literal. @@ -323,7 +320,7 @@ void Clobber(MacroAssembler* masm, CPURegList reg_list) { void RegisterDump::Dump(MacroAssembler* masm) { - DCHECK(__ StackPointer().Is(csp)); + CHECK(__ StackPointer().Is(csp)); // Ensure that we don't unintentionally clobber any registers. RegList old_tmp_list = masm->TmpList()->list(); @@ -399,7 +396,7 @@ void RegisterDump::Dump(MacroAssembler* masm) { // easily restore them. Register dump2_base = x10; Register dump2 = x11; - DCHECK(!AreAliased(dump_base, dump, tmp, dump2_base, dump2)); + CHECK(!AreAliased(dump_base, dump, tmp, dump2_base, dump2)); // Don't lose the dump_ address. __ Mov(dump2_base, dump_base); diff --git a/deps/v8/test/cctest/test-utils-arm64.h b/deps/v8/test/cctest/test-utils-arm64.h index a091bf3932..3ecae23d4b 100644 --- a/deps/v8/test/cctest/test-utils-arm64.h +++ b/deps/v8/test/cctest/test-utils-arm64.h @@ -59,7 +59,7 @@ class RegisterDump { if (code == kSPRegInternalCode) { return wspreg(); } - DCHECK(RegAliasesMatch(code)); + CHECK(RegAliasesMatch(code)); return dump_.w_[code]; } @@ -67,13 +67,13 @@ class RegisterDump { if (code == kSPRegInternalCode) { return spreg(); } - DCHECK(RegAliasesMatch(code)); + CHECK(RegAliasesMatch(code)); return dump_.x_[code]; } // FPRegister accessors. inline uint32_t sreg_bits(unsigned code) const { - DCHECK(FPRegAliasesMatch(code)); + CHECK(FPRegAliasesMatch(code)); return dump_.s_[code]; } @@ -82,7 +82,7 @@ class RegisterDump { } inline uint64_t dreg_bits(unsigned code) const { - DCHECK(FPRegAliasesMatch(code)); + CHECK(FPRegAliasesMatch(code)); return dump_.d_[code]; } @@ -92,19 +92,19 @@ class RegisterDump { // Stack pointer accessors. inline int64_t spreg() const { - DCHECK(SPRegAliasesMatch()); + CHECK(SPRegAliasesMatch()); return dump_.sp_; } inline int32_t wspreg() const { - DCHECK(SPRegAliasesMatch()); + CHECK(SPRegAliasesMatch()); return static_cast<int32_t>(dump_.wsp_); } // Flags accessors. inline uint32_t flags_nzcv() const { - DCHECK(IsComplete()); - DCHECK((dump_.flags_ & ~Flags_mask) == 0); + CHECK(IsComplete()); + CHECK((dump_.flags_ & ~Flags_mask) == 0); return dump_.flags_ & Flags_mask; } @@ -120,21 +120,21 @@ class RegisterDump { // w<code>. A failure of this test most likely represents a failure in the // ::Dump method, or a failure in the simulator. bool RegAliasesMatch(unsigned code) const { - DCHECK(IsComplete()); - DCHECK(code < kNumberOfRegisters); + CHECK(IsComplete()); + CHECK(code < kNumberOfRegisters); return ((dump_.x_[code] & kWRegMask) == dump_.w_[code]); } // As RegAliasesMatch, but for the stack pointer. bool SPRegAliasesMatch() const { - DCHECK(IsComplete()); + CHECK(IsComplete()); return ((dump_.sp_ & kWRegMask) == dump_.wsp_); } // As RegAliasesMatch, but for floating-point registers. bool FPRegAliasesMatch(unsigned code) const { - DCHECK(IsComplete()); - DCHECK(code < kNumberOfFPRegisters); + CHECK(IsComplete()); + CHECK(code < kNumberOfFPRegisters); return (dump_.d_[code] & kSRegMask) == dump_.s_[code]; } diff --git a/deps/v8/test/cctest/test-utils.cc b/deps/v8/test/cctest/test-utils.cc index 979c6f251b..5045b7e591 100644 --- a/deps/v8/test/cctest/test-utils.cc +++ b/deps/v8/test/cctest/test-utils.cc @@ -25,9 +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. -// TODO(mythria): Remove this after it is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <stdlib.h> #include <vector> diff --git a/deps/v8/test/cctest/test-version.cc b/deps/v8/test/cctest/test-version.cc index 77727a03c5..50fca16871 100644 --- a/deps/v8/test/cctest/test-version.cc +++ b/deps/v8/test/cctest/test-version.cc @@ -25,9 +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. -// TODO(mythria): Remove this after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "src/v8.h" #include "src/version.h" diff --git a/deps/v8/test/cctest/test-weakmaps.cc b/deps/v8/test/cctest/test-weakmaps.cc index a877a9eb91..2630110c59 100644 --- a/deps/v8/test/cctest/test-weakmaps.cc +++ b/deps/v8/test/cctest/test-weakmaps.cc @@ -25,15 +25,13 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// TODO(mythria): Remove this after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <utility> #include "src/v8.h" #include "src/global-handles.h" #include "test/cctest/cctest.h" +#include "test/cctest/heap/utils-inl.h" using namespace v8::internal; @@ -59,7 +57,7 @@ static void WeakPointerCallback( std::pair<v8::Persistent<v8::Value>*, int>* p = reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>( data.GetParameter()); - DCHECK_EQ(1234, p->second); + CHECK_EQ(1234, p->second); NumberOfWeakCalls++; p->first->Reset(); } diff --git a/deps/v8/test/cctest/test-weaksets.cc b/deps/v8/test/cctest/test-weaksets.cc index 411c92168d..6998e0f749 100644 --- a/deps/v8/test/cctest/test-weaksets.cc +++ b/deps/v8/test/cctest/test-weaksets.cc @@ -25,15 +25,13 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// TODO(mythria): Remove this after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include <utility> #include "src/v8.h" #include "src/global-handles.h" #include "test/cctest/cctest.h" +#include "test/cctest/heap/utils-inl.h" using namespace v8::internal; @@ -62,7 +60,7 @@ static void WeakPointerCallback( std::pair<v8::Persistent<v8::Value>*, int>* p = reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>( data.GetParameter()); - DCHECK_EQ(1234, p->second); + CHECK_EQ(1234, p->second); NumberOfWeakCalls++; p->first->Reset(); } diff --git a/deps/v8/test/cctest/testcfg.py b/deps/v8/test/cctest/testcfg.py index bd93450a97..d28ef7d004 100644 --- a/deps/v8/test/cctest/testcfg.py +++ b/deps/v8/test/cctest/testcfg.py @@ -44,6 +44,10 @@ class CcTestSuite(testsuite.TestSuite): build_dir = "out" self.serdes_dir = os.path.normpath( os.path.join(root, "..", "..", build_dir, ".serdes")) + + def SetupWorkingDirectory(self): + # This is only called once per machine, while init above is called once per + # process. if os.path.exists(self.serdes_dir): shutil.rmtree(self.serdes_dir, True) os.makedirs(self.serdes_dir) diff --git a/deps/v8/test/cctest/trace-extension.cc b/deps/v8/test/cctest/trace-extension.cc index 5e558cfd05..ea2b2cee3d 100644 --- a/deps/v8/test/cctest/trace-extension.cc +++ b/deps/v8/test/cctest/trace-extension.cc @@ -25,9 +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. -// TODO(mythria): Remove this after this flag is turned on globally -#define V8_IMMINENT_DEPRECATION_WARNINGS - #include "test/cctest/trace-extension.h" #include "src/profiler/sampler.h" diff --git a/deps/v8/test/cctest/wasm/OWNERS b/deps/v8/test/cctest/wasm/OWNERS new file mode 100644 index 0000000000..c2abc8a6ad --- /dev/null +++ b/deps/v8/test/cctest/wasm/OWNERS @@ -0,0 +1,3 @@ +titzer@chromium.org +bradnelson@chromium.org +ahaas@chromium.org diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-js.cc b/deps/v8/test/cctest/wasm/test-run-wasm-js.cc new file mode 100644 index 0000000000..6fcde645cb --- /dev/null +++ b/deps/v8/test/cctest/wasm/test-run-wasm-js.cc @@ -0,0 +1,141 @@ +// 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 <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "src/wasm/wasm-macro-gen.h" + +#include "test/cctest/cctest.h" +#include "test/cctest/wasm/test-signatures.h" +#include "test/cctest/wasm/wasm-run-utils.h" + +using namespace v8::base; +using namespace v8::internal; +using namespace v8::internal::compiler; +using namespace v8::internal::wasm; + +#define BUILD(r, ...) \ + do { \ + byte code[] = {__VA_ARGS__}; \ + r.Build(code, code + arraysize(code)); \ + } while (false) + + +static uint32_t AddJsFunction(TestingModule* module, FunctionSig* sig, + const char* source) { + Handle<JSFunction> jsfunc = Handle<JSFunction>::cast(v8::Utils::OpenHandle( + *v8::Local<v8::Function>::Cast(CompileRun(source)))); + module->AddFunction(sig, Handle<Code>::null()); + uint32_t index = static_cast<uint32_t>(module->module->functions->size() - 1); + Isolate* isolate = CcTest::InitIsolateOnce(); + Handle<Code> code = CompileWasmToJSWrapper(isolate, module, jsfunc, index); + module->function_code->at(index) = code; + return index; +} + + +static Handle<JSFunction> WrapCode(ModuleEnv* module, uint32_t index) { + Isolate* isolate = module->module->shared_isolate; + // Wrap the code so it can be called as a JS function. + Handle<String> name = isolate->factory()->NewStringFromStaticChars("main"); + Handle<JSObject> module_object = Handle<JSObject>(0, isolate); + Handle<Code> code = module->function_code->at(index); + WasmJs::InstallWasmFunctionMap(isolate, isolate->native_context()); + return compiler::CompileJSToWasmWrapper(isolate, module, name, code, + module_object, index); +} + + +static void EXPECT_CALL(double expected, Handle<JSFunction> jsfunc, double a, + double b) { + Isolate* isolate = jsfunc->GetIsolate(); + Handle<Object> buffer[] = {isolate->factory()->NewNumber(a), + isolate->factory()->NewNumber(b)}; + Handle<Object> global(isolate->context()->global_object(), isolate); + MaybeHandle<Object> retval = + Execution::Call(isolate, jsfunc, global, 2, buffer); + + CHECK(!retval.is_null()); + Handle<Object> result = retval.ToHandleChecked(); + if (result->IsSmi()) { + CHECK_EQ(expected, Smi::cast(*result)->value()); + } else { + CHECK(result->IsHeapNumber()); + CHECK_EQ(expected, HeapNumber::cast(*result)->value()); + } +} + + +TEST(Run_Int32Sub_jswrapped) { + TestSignatures sigs; + TestingModule module; + WasmFunctionCompiler t(sigs.i_ii()); + BUILD(t, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd(&module)); + + EXPECT_CALL(33, jsfunc, 44, 11); + EXPECT_CALL(-8723487, jsfunc, -8000000, 723487); +} + + +TEST(Run_Float32Div_jswrapped) { + TestSignatures sigs; + TestingModule module; + WasmFunctionCompiler t(sigs.f_ff()); + BUILD(t, WASM_F32_DIV(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd(&module)); + + EXPECT_CALL(92, jsfunc, 46, 0.5); + EXPECT_CALL(64, jsfunc, -16, -0.25); +} + + +TEST(Run_Float64Add_jswrapped) { + TestSignatures sigs; + TestingModule module; + WasmFunctionCompiler t(sigs.d_dd()); + BUILD(t, WASM_F64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd(&module)); + + EXPECT_CALL(3, jsfunc, 2, 1); + EXPECT_CALL(-5.5, jsfunc, -5.25, -0.25); +} + + +TEST(Run_I32Popcount_jswrapped) { + TestSignatures sigs; + TestingModule module; + WasmFunctionCompiler t(sigs.i_i()); + BUILD(t, WASM_I32_POPCNT(WASM_GET_LOCAL(0))); + Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd(&module)); + + EXPECT_CALL(2, jsfunc, 9, 0); + EXPECT_CALL(3, jsfunc, 11, 0); + EXPECT_CALL(6, jsfunc, 0x3F, 0); + + USE(AddJsFunction); +} + + +#if !V8_TARGET_ARCH_ARM64 +// TODO(titzer): fix wasm->JS calls on arm64 (wrapper issues) + +TEST(Run_CallJS_Add_jswrapped) { + TestSignatures sigs; + TestingModule module; + WasmFunctionCompiler t(sigs.i_i(), &module); + uint32_t js_index = + AddJsFunction(&module, sigs.i_i(), "(function(a) { return a + 99; })"); + BUILD(t, WASM_CALL_FUNCTION(js_index, WASM_GET_LOCAL(0))); + + Handle<JSFunction> jsfunc = WrapCode(&module, t.CompileAndAdd(&module)); + + EXPECT_CALL(101, jsfunc, 2, -8); + EXPECT_CALL(199, jsfunc, 100, -1); + EXPECT_CALL(-666666801, jsfunc, -666666900, -1); +} + +#endif diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-module.cc b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc new file mode 100644 index 0000000000..3b7bae1dda --- /dev/null +++ b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc @@ -0,0 +1,199 @@ +// 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 <stdlib.h> +#include <string.h> + +#include "src/wasm/encoder.h" +#include "src/wasm/wasm-macro-gen.h" +#include "src/wasm/wasm-module.h" +#include "src/wasm/wasm-opcodes.h" + +#include "test/cctest/cctest.h" + +using namespace v8::base; +using namespace v8::internal; +using namespace v8::internal::compiler; +using namespace v8::internal::wasm; + + +namespace { +void TestModule(WasmModuleIndex* module, int32_t expected_result) { + Isolate* isolate = CcTest::InitIsolateOnce(); + int32_t result = + CompileAndRunWasmModule(isolate, module->Begin(), module->End()); + CHECK_EQ(expected_result, result); +} +} // namespace + + +// A raw test that skips the WasmModuleBuilder. +TEST(Run_WasmModule_CallAdd_rev) { + static const byte data[] = { + // sig#0 ------------------------------------------ + kDeclSignatures, 2, 0, kLocalI32, // void -> int + 2, kLocalI32, kLocalI32, kLocalI32, // int,int -> int + // func#0 (main) ---------------------------------- + kDeclFunctions, 2, kDeclFunctionExport, 0, 0, // sig index + 6, 0, // body size + kExprCallFunction, 1, // -- + kExprI8Const, 77, // -- + kExprI8Const, 22, // -- + // func#1 ----------------------------------------- + 0, // no name, not exported + 1, 0, // sig index + 5, 0, // body size + kExprI32Add, // -- + kExprGetLocal, 0, // -- + kExprGetLocal, 1, // -- + }; + + Isolate* isolate = CcTest::InitIsolateOnce(); + int32_t result = + CompileAndRunWasmModule(isolate, data, data + arraysize(data)); + CHECK_EQ(99, result); +} + + +TEST(Run_WasmModule_Return114) { + static const int32_t kReturnValue = 114; + Zone zone; + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); + uint16_t f_index = builder->AddFunction(); + WasmFunctionBuilder* f = builder->FunctionAt(f_index); + f->ReturnType(kAstI32); + f->Exported(1); + byte code[] = {WASM_I8(kReturnValue)}; + f->EmitCode(code, sizeof(code)); + WasmModuleWriter* writer = builder->Build(&zone); + TestModule(writer->WriteTo(&zone), kReturnValue); +} + + +TEST(Run_WasmModule_CallAdd) { + Zone zone; + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); + uint16_t f1_index = builder->AddFunction(); + WasmFunctionBuilder* f = builder->FunctionAt(f1_index); + f->ReturnType(kAstI32); + uint16_t param1 = f->AddParam(kAstI32); + uint16_t param2 = f->AddParam(kAstI32); + byte code1[] = {WASM_I32_ADD(WASM_GET_LOCAL(param1), WASM_GET_LOCAL(param2))}; + uint32_t local_indices1[] = {2, 4}; + f->EmitCode(code1, sizeof(code1), local_indices1, sizeof(local_indices1) / 4); + uint16_t f2_index = builder->AddFunction(); + f = builder->FunctionAt(f2_index); + f->ReturnType(kAstI32); + f->Exported(1); + byte code2[] = {WASM_CALL_FUNCTION(f1_index, WASM_I8(77), WASM_I8(22))}; + f->EmitCode(code2, sizeof(code2)); + WasmModuleWriter* writer = builder->Build(&zone); + TestModule(writer->WriteTo(&zone), 99); +} + + +TEST(Run_WasmModule_ReadLoadedDataSegment) { + static const byte kDataSegmentDest0 = 12; + Zone zone; + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); + uint16_t f_index = builder->AddFunction(); + WasmFunctionBuilder* f = builder->FunctionAt(f_index); + f->ReturnType(kAstI32); + f->Exported(1); + byte code[] = { + WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kDataSegmentDest0))}; + f->EmitCode(code, sizeof(code)); + byte data[] = {0xaa, 0xbb, 0xcc, 0xdd}; + builder->AddDataSegment(new (&zone) WasmDataSegmentEncoder( + &zone, data, sizeof(data), kDataSegmentDest0)); + WasmModuleWriter* writer = builder->Build(&zone); + TestModule(writer->WriteTo(&zone), 0xddccbbaa); +} + + +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define V8_WITH_ASAN 1 +#endif +#endif + + +#if !defined(V8_WITH_ASAN) +// TODO(bradnelson): Figure out why this crashes under asan. +TEST(Run_WasmModule_CheckMemoryIsZero) { + static const int kCheckSize = 16 * 1024; + Zone zone; + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); + uint16_t f_index = builder->AddFunction(); + WasmFunctionBuilder* f = builder->FunctionAt(f_index); + f->ReturnType(kAstI32); + uint16_t localIndex = f->AddLocal(kAstI32); + f->Exported(1); + byte code[] = {WASM_BLOCK( + 2, + WASM_WHILE( + WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I32(kCheckSize)), + WASM_IF_ELSE( + WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(localIndex)), + WASM_BRV(2, WASM_I8(-1)), WASM_INC_LOCAL_BY(localIndex, 4))), + WASM_I8(11))}; + uint32_t local_indices[] = {7, 19, 25, 28}; + f->EmitCode(code, sizeof(code), local_indices, sizeof(local_indices) / 4); + WasmModuleWriter* writer = builder->Build(&zone); + TestModule(writer->WriteTo(&zone), 11); +} +#endif + + +#if !defined(V8_WITH_ASAN) +// TODO(bradnelson): Figure out why this crashes under asan. +TEST(Run_WasmModule_CallMain_recursive) { + Zone zone; + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); + uint16_t f_index = builder->AddFunction(); + WasmFunctionBuilder* f = builder->FunctionAt(f_index); + f->ReturnType(kAstI32); + uint16_t localIndex = f->AddLocal(kAstI32); + f->Exported(1); + byte code[] = {WASM_BLOCK( + 2, WASM_SET_LOCAL(localIndex, + WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)), + WASM_IF_ELSE(WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I8(5)), + WASM_BLOCK(2, WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO, + WASM_INC_LOCAL(localIndex)), + WASM_BRV(1, WASM_CALL_FUNCTION0(0))), + WASM_BRV(0, WASM_I8(55))))}; + uint32_t local_indices[] = {3, 11, 21, 24}; + f->EmitCode(code, sizeof(code), local_indices, sizeof(local_indices) / 4); + WasmModuleWriter* writer = builder->Build(&zone); + TestModule(writer->WriteTo(&zone), 55); +} +#endif + + +#if !defined(V8_WITH_ASAN) +// TODO(bradnelson): Figure out why this crashes under asan. +TEST(Run_WasmModule_Global) { + Zone zone; + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); + uint32_t global1 = builder->AddGlobal(MachineType::Int32(), 0); + uint32_t global2 = builder->AddGlobal(MachineType::Int32(), 0); + uint16_t f1_index = builder->AddFunction(); + WasmFunctionBuilder* f = builder->FunctionAt(f1_index); + f->ReturnType(kAstI32); + byte code1[] = { + WASM_I32_ADD(WASM_LOAD_GLOBAL(global1), WASM_LOAD_GLOBAL(global2))}; + f->EmitCode(code1, sizeof(code1)); + uint16_t f2_index = builder->AddFunction(); + f = builder->FunctionAt(f2_index); + f->ReturnType(kAstI32); + f->Exported(1); + byte code2[] = {WASM_STORE_GLOBAL(global1, WASM_I32(56)), + WASM_STORE_GLOBAL(global2, WASM_I32(41)), + WASM_RETURN(WASM_CALL_FUNCTION0(f1_index))}; + f->EmitCode(code2, sizeof(code2)); + WasmModuleWriter* writer = builder->Build(&zone); + TestModule(writer->WriteTo(&zone), 97); +} +#endif diff --git a/deps/v8/test/cctest/wasm/test-run-wasm.cc b/deps/v8/test/cctest/wasm/test-run-wasm.cc new file mode 100644 index 0000000000..445c3f0aed --- /dev/null +++ b/deps/v8/test/cctest/wasm/test-run-wasm.cc @@ -0,0 +1,3254 @@ +// 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 <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "src/wasm/wasm-macro-gen.h" + +#include "test/cctest/cctest.h" +#include "test/cctest/compiler/value-helper.h" +#include "test/cctest/wasm/test-signatures.h" +#include "test/cctest/wasm/wasm-run-utils.h" + +using namespace v8::base; +using namespace v8::internal; +using namespace v8::internal::compiler; +using namespace v8::internal::wasm; + +#define BUILD(r, ...) \ + do { \ + byte code[] = {__VA_ARGS__}; \ + r.Build(code, code + arraysize(code)); \ + } while (false) + + +TEST(Run_WasmInt8Const) { + WasmRunner<int8_t> r; + const byte kExpectedValue = 121; + // return(kExpectedValue) + BUILD(r, WASM_I8(kExpectedValue)); + CHECK_EQ(kExpectedValue, r.Call()); +} + + +TEST(Run_WasmInt8Const_fallthru1) { + WasmRunner<int8_t> r; + const byte kExpectedValue = 122; + // kExpectedValue + BUILD(r, WASM_I8(kExpectedValue)); + CHECK_EQ(kExpectedValue, r.Call()); +} + + +TEST(Run_WasmInt8Const_fallthru2) { + WasmRunner<int8_t> r; + const byte kExpectedValue = 123; + // -99 kExpectedValue + BUILD(r, WASM_I8(-99), WASM_I8(kExpectedValue)); + CHECK_EQ(kExpectedValue, r.Call()); +} + + +TEST(Run_WasmInt8Const_all) { + for (int value = -128; value <= 127; value++) { + WasmRunner<int8_t> r; + // return(value) + BUILD(r, WASM_I8(value)); + int8_t result = r.Call(); + CHECK_EQ(value, result); + } +} + + +TEST(Run_WasmInt32Const) { + WasmRunner<int32_t> r; + const int32_t kExpectedValue = 0x11223344; + // return(kExpectedValue) + BUILD(r, WASM_I32(kExpectedValue)); + CHECK_EQ(kExpectedValue, r.Call()); +} + + +TEST(Run_WasmInt32Const_many) { + FOR_INT32_INPUTS(i) { + WasmRunner<int32_t> r; + const int32_t kExpectedValue = *i; + // return(kExpectedValue) + BUILD(r, WASM_I32(kExpectedValue)); + CHECK_EQ(kExpectedValue, r.Call()); + } +} + + +TEST(Run_WasmMemorySize) { + WasmRunner<int32_t> r; + TestingModule module; + module.AddMemory(1024); + r.env()->module = &module; + BUILD(r, kExprMemorySize); + CHECK_EQ(1024, r.Call()); +} + + +#if WASM_64 +TEST(Run_WasmInt64Const) { + WasmRunner<int64_t> r; + const int64_t kExpectedValue = 0x1122334455667788LL; + // return(kExpectedValue) + BUILD(r, WASM_I64(kExpectedValue)); + CHECK_EQ(kExpectedValue, r.Call()); +} + + +TEST(Run_WasmInt64Const_many) { + int cntr = 0; + FOR_INT32_INPUTS(i) { + WasmRunner<int64_t> r; + const int64_t kExpectedValue = (static_cast<int64_t>(*i) << 32) | cntr; + // return(kExpectedValue) + BUILD(r, WASM_I64(kExpectedValue)); + CHECK_EQ(kExpectedValue, r.Call()); + cntr++; + } +} +#endif + + +TEST(Run_WasmInt32Param0) { + WasmRunner<int32_t> r(MachineType::Int32()); + // return(local[0]) + BUILD(r, WASM_GET_LOCAL(0)); + FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); } +} + + +TEST(Run_WasmInt32Param0_fallthru) { + WasmRunner<int32_t> r(MachineType::Int32()); + // local[0] + BUILD(r, WASM_GET_LOCAL(0)); + FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); } +} + + +TEST(Run_WasmInt32Param1) { + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + // local[1] + BUILD(r, WASM_GET_LOCAL(1)); + FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(-111, *i)); } +} + + +TEST(Run_WasmInt32Add) { + WasmRunner<int32_t> r; + // 11 + 44 + BUILD(r, WASM_I32_ADD(WASM_I8(11), WASM_I8(44))); + CHECK_EQ(55, r.Call()); +} + + +TEST(Run_WasmInt32Add_P) { + WasmRunner<int32_t> r(MachineType::Int32()); + // p0 + 13 + BUILD(r, WASM_I32_ADD(WASM_I8(13), WASM_GET_LOCAL(0))); + FOR_INT32_INPUTS(i) { CHECK_EQ(*i + 13, r.Call(*i)); } +} + + +TEST(Run_WasmInt32Add_P_fallthru) { + WasmRunner<int32_t> r(MachineType::Int32()); + // p0 + 13 + BUILD(r, WASM_I32_ADD(WASM_I8(13), WASM_GET_LOCAL(0))); + FOR_INT32_INPUTS(i) { CHECK_EQ(*i + 13, r.Call(*i)); } +} + + +TEST(Run_WasmInt32Add_P2) { + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + // p0 + p1 + BUILD(r, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + 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)); + CHECK_EQ(expected, r.Call(*i, *j)); + } + } +} + + +// TODO(titzer): Fix for nosee4 and re-enable. +#if 0 + +TEST(Run_WasmFloat32Add) { + WasmRunner<int32_t> r; + // int(11.5f + 44.5f) + BUILD(r, + WASM_I32_SCONVERT_F32(WASM_F32_ADD(WASM_F32(11.5f), WASM_F32(44.5f)))); + CHECK_EQ(56, r.Call()); +} + + +TEST(Run_WasmFloat64Add) { + WasmRunner<int32_t> r; + // return int(13.5d + 43.5d) + BUILD(r, WASM_I32_SCONVERT_F64(WASM_F64_ADD(WASM_F64(13.5), WASM_F64(43.5)))); + CHECK_EQ(57, r.Call()); +} + +#endif + + +void TestInt32Binop(WasmOpcode opcode, int32_t expected, int32_t a, int32_t b) { + { + WasmRunner<int32_t> r; + // K op K + BUILD(r, WASM_BINOP(opcode, WASM_I32(a), WASM_I32(b))); + CHECK_EQ(expected, r.Call()); + } + { + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + // a op b + BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + CHECK_EQ(expected, r.Call(a, b)); + } +} + + +TEST(Run_WasmInt32Binops) { + TestInt32Binop(kExprI32Add, 88888888, 33333333, 55555555); + TestInt32Binop(kExprI32Sub, -1111111, 7777777, 8888888); + TestInt32Binop(kExprI32Mul, 65130756, 88734, 734); + TestInt32Binop(kExprI32DivS, -66, -4777344, 72384); + TestInt32Binop(kExprI32DivU, 805306368, 0xF0000000, 5); + TestInt32Binop(kExprI32RemS, -3, -3003, 1000); + TestInt32Binop(kExprI32RemU, 4, 4004, 1000); + TestInt32Binop(kExprI32And, 0xEE, 0xFFEE, 0xFF0000FF); + TestInt32Binop(kExprI32Ior, 0xF0FF00FF, 0xF0F000EE, 0x000F0011); + TestInt32Binop(kExprI32Xor, 0xABCDEF01, 0xABCDEFFF, 0xFE); + TestInt32Binop(kExprI32Shl, 0xA0000000, 0xA, 28); + TestInt32Binop(kExprI32ShrU, 0x07000010, 0x70000100, 4); + TestInt32Binop(kExprI32ShrS, 0xFF000000, 0x80000000, 7); + TestInt32Binop(kExprI32Eq, 1, -99, -99); + TestInt32Binop(kExprI32Ne, 0, -97, -97); + + TestInt32Binop(kExprI32LtS, 1, -4, 4); + TestInt32Binop(kExprI32LeS, 0, -2, -3); + TestInt32Binop(kExprI32LtU, 1, 0, -6); + TestInt32Binop(kExprI32LeU, 1, 98978, 0xF0000000); + + TestInt32Binop(kExprI32GtS, 1, 4, -4); + TestInt32Binop(kExprI32GeS, 0, -3, -2); + TestInt32Binop(kExprI32GtU, 1, -6, 0); + TestInt32Binop(kExprI32GeU, 1, 0xF0000000, 98978); +} + + +void TestInt32Unop(WasmOpcode opcode, int32_t expected, int32_t a) { + { + WasmRunner<int32_t> r; + // return op K + BUILD(r, WASM_UNOP(opcode, WASM_I32(a))); + CHECK_EQ(expected, r.Call()); + } + { + WasmRunner<int32_t> r(MachineType::Int32()); + // return op a + BUILD(r, WASM_UNOP(opcode, WASM_GET_LOCAL(0))); + CHECK_EQ(expected, r.Call(a)); + } +} + + +TEST(Run_WasmInt32Clz) { + TestInt32Unop(kExprI32Clz, 0, 0x80001000); + TestInt32Unop(kExprI32Clz, 1, 0x40000500); + TestInt32Unop(kExprI32Clz, 2, 0x20000300); + TestInt32Unop(kExprI32Clz, 3, 0x10000003); + TestInt32Unop(kExprI32Clz, 4, 0x08050000); + TestInt32Unop(kExprI32Clz, 5, 0x04006000); + TestInt32Unop(kExprI32Clz, 6, 0x02000000); + TestInt32Unop(kExprI32Clz, 7, 0x010000a0); + TestInt32Unop(kExprI32Clz, 8, 0x00800c00); + TestInt32Unop(kExprI32Clz, 9, 0x00400000); + TestInt32Unop(kExprI32Clz, 10, 0x0020000d); + TestInt32Unop(kExprI32Clz, 11, 0x00100f00); + TestInt32Unop(kExprI32Clz, 12, 0x00080000); + TestInt32Unop(kExprI32Clz, 13, 0x00041000); + TestInt32Unop(kExprI32Clz, 14, 0x00020020); + TestInt32Unop(kExprI32Clz, 15, 0x00010300); + TestInt32Unop(kExprI32Clz, 16, 0x00008040); + TestInt32Unop(kExprI32Clz, 17, 0x00004005); + TestInt32Unop(kExprI32Clz, 18, 0x00002050); + TestInt32Unop(kExprI32Clz, 19, 0x00001700); + TestInt32Unop(kExprI32Clz, 20, 0x00000870); + TestInt32Unop(kExprI32Clz, 21, 0x00000405); + TestInt32Unop(kExprI32Clz, 22, 0x00000203); + TestInt32Unop(kExprI32Clz, 23, 0x00000101); + TestInt32Unop(kExprI32Clz, 24, 0x00000089); + TestInt32Unop(kExprI32Clz, 25, 0x00000041); + TestInt32Unop(kExprI32Clz, 26, 0x00000022); + TestInt32Unop(kExprI32Clz, 27, 0x00000013); + TestInt32Unop(kExprI32Clz, 28, 0x00000008); + TestInt32Unop(kExprI32Clz, 29, 0x00000004); + TestInt32Unop(kExprI32Clz, 30, 0x00000002); + TestInt32Unop(kExprI32Clz, 31, 0x00000001); + TestInt32Unop(kExprI32Clz, 32, 0x00000000); +} + + +TEST(Run_WasmInt32Ctz) { + TestInt32Unop(kExprI32Ctz, 32, 0x00000000); + TestInt32Unop(kExprI32Ctz, 31, 0x80000000); + TestInt32Unop(kExprI32Ctz, 30, 0x40000000); + TestInt32Unop(kExprI32Ctz, 29, 0x20000000); + TestInt32Unop(kExprI32Ctz, 28, 0x10000000); + TestInt32Unop(kExprI32Ctz, 27, 0xa8000000); + TestInt32Unop(kExprI32Ctz, 26, 0xf4000000); + TestInt32Unop(kExprI32Ctz, 25, 0x62000000); + TestInt32Unop(kExprI32Ctz, 24, 0x91000000); + TestInt32Unop(kExprI32Ctz, 23, 0xcd800000); + TestInt32Unop(kExprI32Ctz, 22, 0x09400000); + TestInt32Unop(kExprI32Ctz, 21, 0xaf200000); + TestInt32Unop(kExprI32Ctz, 20, 0xac100000); + TestInt32Unop(kExprI32Ctz, 19, 0xe0b80000); + TestInt32Unop(kExprI32Ctz, 18, 0x9ce40000); + TestInt32Unop(kExprI32Ctz, 17, 0xc7920000); + TestInt32Unop(kExprI32Ctz, 16, 0xb8f10000); + TestInt32Unop(kExprI32Ctz, 15, 0x3b9f8000); + TestInt32Unop(kExprI32Ctz, 14, 0xdb4c4000); + TestInt32Unop(kExprI32Ctz, 13, 0xe9a32000); + TestInt32Unop(kExprI32Ctz, 12, 0xfca61000); + TestInt32Unop(kExprI32Ctz, 11, 0x6c8a7800); + TestInt32Unop(kExprI32Ctz, 10, 0x8ce5a400); + TestInt32Unop(kExprI32Ctz, 9, 0xcb7d0200); + TestInt32Unop(kExprI32Ctz, 8, 0xcb4dc100); + TestInt32Unop(kExprI32Ctz, 7, 0xdfbec580); + TestInt32Unop(kExprI32Ctz, 6, 0x27a9db40); + TestInt32Unop(kExprI32Ctz, 5, 0xde3bcb20); + TestInt32Unop(kExprI32Ctz, 4, 0xd7e8a610); + TestInt32Unop(kExprI32Ctz, 3, 0x9afdbc88); + TestInt32Unop(kExprI32Ctz, 2, 0x9afdbc84); + TestInt32Unop(kExprI32Ctz, 1, 0x9afdbc82); + TestInt32Unop(kExprI32Ctz, 0, 0x9afdbc81); +} + + +TEST(Run_WasmInt32Popcnt) { + TestInt32Unop(kExprI32Popcnt, 32, 0xffffffff); + TestInt32Unop(kExprI32Popcnt, 0, 0x00000000); + TestInt32Unop(kExprI32Popcnt, 1, 0x00008000); + TestInt32Unop(kExprI32Popcnt, 13, 0x12345678); + TestInt32Unop(kExprI32Popcnt, 19, 0xfedcba09); +} + + +#if WASM_64 +void TestInt64Binop(WasmOpcode opcode, int64_t expected, int64_t a, int64_t b) { + if (!WasmOpcodes::IsSupported(opcode)) return; + { + WasmRunner<int64_t> r; + // return K op K + BUILD(r, WASM_BINOP(opcode, WASM_I64(a), WASM_I64(b))); + CHECK_EQ(expected, r.Call()); + } + { + WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); + // return a op b + BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + CHECK_EQ(expected, r.Call(a, b)); + } +} + + +void TestInt64Cmp(WasmOpcode opcode, int64_t expected, int64_t a, int64_t b) { + if (!WasmOpcodes::IsSupported(opcode)) return; + { + WasmRunner<int32_t> r; + // return K op K + BUILD(r, WASM_BINOP(opcode, WASM_I64(a), WASM_I64(b))); + CHECK_EQ(expected, r.Call()); + } + { + WasmRunner<int32_t> r(MachineType::Int64(), MachineType::Int64()); + // return a op b + BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + CHECK_EQ(expected, r.Call(a, b)); + } +} + + +TEST(Run_WasmInt64Binops) { + // TODO(titzer): real 64-bit numbers + TestInt64Binop(kExprI64Add, 8888888888888LL, 3333333333333LL, + 5555555555555LL); + TestInt64Binop(kExprI64Sub, -111111111111LL, 777777777777LL, 888888888888LL); + TestInt64Binop(kExprI64Mul, 65130756, 88734, 734); + TestInt64Binop(kExprI64DivS, -66, -4777344, 72384); + TestInt64Binop(kExprI64DivU, 805306368, 0xF0000000, 5); + TestInt64Binop(kExprI64RemS, -3, -3003, 1000); + TestInt64Binop(kExprI64RemU, 4, 4004, 1000); + TestInt64Binop(kExprI64And, 0xEE, 0xFFEE, 0xFF0000FF); + TestInt64Binop(kExprI64Ior, 0xF0FF00FF, 0xF0F000EE, 0x000F0011); + TestInt64Binop(kExprI64Xor, 0xABCDEF01, 0xABCDEFFF, 0xFE); + TestInt64Binop(kExprI64Shl, 0xA0000000, 0xA, 28); + TestInt64Binop(kExprI64ShrU, 0x0700001000123456LL, 0x7000010001234567LL, 4); + TestInt64Binop(kExprI64ShrS, 0xFF00000000000000LL, 0x8000000000000000LL, 7); + TestInt64Cmp(kExprI64Eq, 1, -9999, -9999); + TestInt64Cmp(kExprI64Ne, 1, -9199, -9999); + TestInt64Cmp(kExprI64LtS, 1, -4, 4); + TestInt64Cmp(kExprI64LeS, 0, -2, -3); + TestInt64Cmp(kExprI64LtU, 1, 0, -6); + TestInt64Cmp(kExprI64LeU, 1, 98978, 0xF0000000); +} + + +TEST(Run_WasmInt64Clz) { + struct { + int64_t expected; + uint64_t input; + } values[] = {{0, 0x8000100000000000}, {1, 0x4000050000000000}, + {2, 0x2000030000000000}, {3, 0x1000000300000000}, + {4, 0x0805000000000000}, {5, 0x0400600000000000}, + {6, 0x0200000000000000}, {7, 0x010000a000000000}, + {8, 0x00800c0000000000}, {9, 0x0040000000000000}, + {10, 0x0020000d00000000}, {11, 0x00100f0000000000}, + {12, 0x0008000000000000}, {13, 0x0004100000000000}, + {14, 0x0002002000000000}, {15, 0x0001030000000000}, + {16, 0x0000804000000000}, {17, 0x0000400500000000}, + {18, 0x0000205000000000}, {19, 0x0000170000000000}, + {20, 0x0000087000000000}, {21, 0x0000040500000000}, + {22, 0x0000020300000000}, {23, 0x0000010100000000}, + {24, 0x0000008900000000}, {25, 0x0000004100000000}, + {26, 0x0000002200000000}, {27, 0x0000001300000000}, + {28, 0x0000000800000000}, {29, 0x0000000400000000}, + {30, 0x0000000200000000}, {31, 0x0000000100000000}, + {32, 0x0000000080001000}, {33, 0x0000000040000500}, + {34, 0x0000000020000300}, {35, 0x0000000010000003}, + {36, 0x0000000008050000}, {37, 0x0000000004006000}, + {38, 0x0000000002000000}, {39, 0x00000000010000a0}, + {40, 0x0000000000800c00}, {41, 0x0000000000400000}, + {42, 0x000000000020000d}, {43, 0x0000000000100f00}, + {44, 0x0000000000080000}, {45, 0x0000000000041000}, + {46, 0x0000000000020020}, {47, 0x0000000000010300}, + {48, 0x0000000000008040}, {49, 0x0000000000004005}, + {50, 0x0000000000002050}, {51, 0x0000000000001700}, + {52, 0x0000000000000870}, {53, 0x0000000000000405}, + {54, 0x0000000000000203}, {55, 0x0000000000000101}, + {56, 0x0000000000000089}, {57, 0x0000000000000041}, + {58, 0x0000000000000022}, {59, 0x0000000000000013}, + {60, 0x0000000000000008}, {61, 0x0000000000000004}, + {62, 0x0000000000000002}, {63, 0x0000000000000001}, + {64, 0x0000000000000000}}; + + WasmRunner<int64_t> r(MachineType::Uint64()); + BUILD(r, WASM_I64_CLZ(WASM_GET_LOCAL(0))); + for (size_t i = 0; i < arraysize(values); i++) { + CHECK_EQ(values[i].expected, r.Call(values[i].input)); + } +} + + +TEST(Run_WasmInt64Ctz) { + struct { + int64_t expected; + uint64_t input; + } values[] = {{64, 0x0000000000000000}, {63, 0x8000000000000000}, + {62, 0x4000000000000000}, {61, 0x2000000000000000}, + {60, 0x1000000000000000}, {59, 0xa800000000000000}, + {58, 0xf400000000000000}, {57, 0x6200000000000000}, + {56, 0x9100000000000000}, {55, 0xcd80000000000000}, + {54, 0x0940000000000000}, {53, 0xaf20000000000000}, + {52, 0xac10000000000000}, {51, 0xe0b8000000000000}, + {50, 0x9ce4000000000000}, {49, 0xc792000000000000}, + {48, 0xb8f1000000000000}, {47, 0x3b9f800000000000}, + {46, 0xdb4c400000000000}, {45, 0xe9a3200000000000}, + {44, 0xfca6100000000000}, {43, 0x6c8a780000000000}, + {42, 0x8ce5a40000000000}, {41, 0xcb7d020000000000}, + {40, 0xcb4dc10000000000}, {39, 0xdfbec58000000000}, + {38, 0x27a9db4000000000}, {37, 0xde3bcb2000000000}, + {36, 0xd7e8a61000000000}, {35, 0x9afdbc8800000000}, + {34, 0x9afdbc8400000000}, {33, 0x9afdbc8200000000}, + {32, 0x9afdbc8100000000}, {31, 0x0000000080000000}, + {30, 0x0000000040000000}, {29, 0x0000000020000000}, + {28, 0x0000000010000000}, {27, 0x00000000a8000000}, + {26, 0x00000000f4000000}, {25, 0x0000000062000000}, + {24, 0x0000000091000000}, {23, 0x00000000cd800000}, + {22, 0x0000000009400000}, {21, 0x00000000af200000}, + {20, 0x00000000ac100000}, {19, 0x00000000e0b80000}, + {18, 0x000000009ce40000}, {17, 0x00000000c7920000}, + {16, 0x00000000b8f10000}, {15, 0x000000003b9f8000}, + {14, 0x00000000db4c4000}, {13, 0x00000000e9a32000}, + {12, 0x00000000fca61000}, {11, 0x000000006c8a7800}, + {10, 0x000000008ce5a400}, {9, 0x00000000cb7d0200}, + {8, 0x00000000cb4dc100}, {7, 0x00000000dfbec580}, + {6, 0x0000000027a9db40}, {5, 0x00000000de3bcb20}, + {4, 0x00000000d7e8a610}, {3, 0x000000009afdbc88}, + {2, 0x000000009afdbc84}, {1, 0x000000009afdbc82}, + {0, 0x000000009afdbc81}}; + + WasmRunner<int64_t> r(MachineType::Uint64()); + BUILD(r, WASM_I64_CTZ(WASM_GET_LOCAL(0))); + for (size_t i = 0; i < arraysize(values); i++) { + CHECK_EQ(values[i].expected, r.Call(values[i].input)); + } +} + + +TEST(Run_WasmInt64Popcnt) { + struct { + int64_t expected; + uint64_t input; + } values[] = {{64, 0xffffffffffffffff}, + {0, 0x0000000000000000}, + {2, 0x0000080000008000}, + {26, 0x1123456782345678}, + {38, 0xffedcba09edcba09}}; + + WasmRunner<int64_t> r(MachineType::Uint64()); + BUILD(r, WASM_I64_POPCNT(WASM_GET_LOCAL(0))); + for (size_t i = 0; i < arraysize(values); i++) { + CHECK_EQ(values[i].expected, r.Call(values[i].input)); + } +} + + +#endif + +TEST(Run_WASM_Int32DivS_trap) { + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + CHECK_EQ(0, r.Call(0, 100)); + CHECK_TRAP(r.Call(100, 0)); + CHECK_TRAP(r.Call(-1001, 0)); + CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), -1)); + CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), 0)); +} + + +TEST(Run_WASM_Int32RemS_trap) { + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + CHECK_EQ(33, r.Call(133, 100)); + CHECK_EQ(0, r.Call(std::numeric_limits<int32_t>::min(), -1)); + CHECK_TRAP(r.Call(100, 0)); + CHECK_TRAP(r.Call(-1001, 0)); + CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), 0)); +} + + +TEST(Run_WASM_Int32DivU_trap) { + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + CHECK_EQ(0, r.Call(0, 100)); + CHECK_EQ(0, r.Call(std::numeric_limits<int32_t>::min(), -1)); + CHECK_TRAP(r.Call(100, 0)); + CHECK_TRAP(r.Call(-1001, 0)); + CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), 0)); +} + + +TEST(Run_WASM_Int32RemU_trap) { + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + BUILD(r, WASM_I32_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + CHECK_EQ(17, r.Call(217, 100)); + CHECK_TRAP(r.Call(100, 0)); + CHECK_TRAP(r.Call(-1001, 0)); + CHECK_TRAP(r.Call(std::numeric_limits<int32_t>::min(), 0)); + CHECK_EQ(std::numeric_limits<int32_t>::min(), + r.Call(std::numeric_limits<int32_t>::min(), -1)); +} + + +TEST(Run_WASM_Int32DivS_byzero_const) { + for (int8_t denom = -2; denom < 8; denom++) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I8(denom))); + for (int32_t val = -7; val < 8; val++) { + if (denom == 0) { + CHECK_TRAP(r.Call(val)); + } else { + CHECK_EQ(val / denom, r.Call(val)); + } + } + } +} + + +TEST(Run_WASM_Int32DivU_byzero_const) { + for (uint32_t denom = 0xfffffffe; denom < 8; denom++) { + WasmRunner<uint32_t> r(MachineType::Uint32()); + BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_I32(denom))); + + for (uint32_t val = 0xfffffff0; val < 8; val++) { + if (denom == 0) { + CHECK_TRAP(r.Call(val)); + } else { + CHECK_EQ(val / denom, r.Call(val)); + } + } + } +} + + +TEST(Run_WASM_Int32DivS_trap_effect) { + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + TestingModule module; + module.AddMemoryElems<int32_t>(8); + r.env()->module = &module; + + BUILD(r, + WASM_IF_ELSE(WASM_GET_LOCAL(0), + WASM_I32_DIVS(WASM_STORE_MEM(MachineType::Int8(), + WASM_ZERO, WASM_GET_LOCAL(0)), + WASM_GET_LOCAL(1)), + WASM_I32_DIVS(WASM_STORE_MEM(MachineType::Int8(), + WASM_ZERO, WASM_GET_LOCAL(0)), + WASM_GET_LOCAL(1)))); + CHECK_EQ(0, r.Call(0, 100)); + CHECK_TRAP(r.Call(8, 0)); + CHECK_TRAP(r.Call(4, 0)); + CHECK_TRAP(r.Call(0, 0)); +} + + +#if WASM_64 +#define as64(x) static_cast<int64_t>(x) +TEST(Run_WASM_Int64DivS_trap) { + WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); + BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + CHECK_EQ(0, r.Call(as64(0), as64(100))); + CHECK_TRAP64(r.Call(as64(100), as64(0))); + CHECK_TRAP64(r.Call(as64(-1001), as64(0))); + CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(-1))); + CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0))); +} + + +TEST(Run_WASM_Int64RemS_trap) { + WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); + BUILD(r, WASM_I64_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + CHECK_EQ(33, r.Call(as64(133), as64(100))); + CHECK_EQ(0, r.Call(std::numeric_limits<int64_t>::min(), as64(-1))); + CHECK_TRAP64(r.Call(as64(100), as64(0))); + CHECK_TRAP64(r.Call(as64(-1001), as64(0))); + CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0))); +} + + +TEST(Run_WASM_Int64DivU_trap) { + WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); + BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + CHECK_EQ(0, r.Call(as64(0), as64(100))); + CHECK_EQ(0, r.Call(std::numeric_limits<int64_t>::min(), as64(-1))); + CHECK_TRAP64(r.Call(as64(100), as64(0))); + CHECK_TRAP64(r.Call(as64(-1001), as64(0))); + CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0))); +} + + +TEST(Run_WASM_Int64RemU_trap) { + WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); + BUILD(r, WASM_I64_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + CHECK_EQ(17, r.Call(as64(217), as64(100))); + CHECK_TRAP64(r.Call(as64(100), as64(0))); + CHECK_TRAP64(r.Call(as64(-1001), as64(0))); + CHECK_TRAP64(r.Call(std::numeric_limits<int64_t>::min(), as64(0))); + CHECK_EQ(std::numeric_limits<int64_t>::min(), + r.Call(std::numeric_limits<int64_t>::min(), as64(-1))); +} + + +TEST(Run_WASM_Int64DivS_byzero_const) { + for (int8_t denom = -2; denom < 8; denom++) { + WasmRunner<int64_t> r(MachineType::Int64()); + BUILD(r, WASM_I64_DIVS(WASM_GET_LOCAL(0), WASM_I64(denom))); + for (int64_t val = -7; val < 8; val++) { + if (denom == 0) { + CHECK_TRAP64(r.Call(val)); + } else { + CHECK_EQ(val / denom, r.Call(val)); + } + } + } +} + + +TEST(Run_WASM_Int64DivU_byzero_const) { + for (uint64_t denom = 0xfffffffffffffffe; denom < 8; denom++) { + WasmRunner<uint64_t> r(MachineType::Uint64()); + BUILD(r, WASM_I64_DIVU(WASM_GET_LOCAL(0), WASM_I64(denom))); + + for (uint64_t val = 0xfffffffffffffff0; val < 8; val++) { + if (denom == 0) { + CHECK_TRAP64(r.Call(val)); + } else { + CHECK_EQ(val / denom, r.Call(val)); + } + } + } +} +#endif + + +void TestFloat32Binop(WasmOpcode opcode, int32_t expected, float a, float b) { + { + WasmRunner<int32_t> r; + // return K op K + BUILD(r, WASM_BINOP(opcode, WASM_F32(a), WASM_F32(b))); + CHECK_EQ(expected, r.Call()); + } + { + WasmRunner<int32_t> r(MachineType::Float32(), MachineType::Float32()); + // return a op b + BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + CHECK_EQ(expected, r.Call(a, b)); + } +} + + +void TestFloat32BinopWithConvert(WasmOpcode opcode, int32_t expected, float a, + float b) { + { + WasmRunner<int32_t> r; + // return int(K op K) + BUILD(r, + WASM_I32_SCONVERT_F32(WASM_BINOP(opcode, WASM_F32(a), WASM_F32(b)))); + CHECK_EQ(expected, r.Call()); + } + { + WasmRunner<int32_t> r(MachineType::Float32(), MachineType::Float32()); + // return int(a op b) + BUILD(r, WASM_I32_SCONVERT_F32( + WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)))); + CHECK_EQ(expected, r.Call(a, b)); + } +} + + +void TestFloat32UnopWithConvert(WasmOpcode opcode, int32_t expected, float a) { + { + WasmRunner<int32_t> r; + // return int(op(K)) + BUILD(r, WASM_I32_SCONVERT_F32(WASM_UNOP(opcode, WASM_F32(a)))); + CHECK_EQ(expected, r.Call()); + } + { + WasmRunner<int32_t> r(MachineType::Float32()); + // return int(op(a)) + BUILD(r, WASM_I32_SCONVERT_F32(WASM_UNOP(opcode, WASM_GET_LOCAL(0)))); + CHECK_EQ(expected, r.Call(a)); + } +} + + +void TestFloat64Binop(WasmOpcode opcode, int32_t expected, double a, double b) { + { + WasmRunner<int32_t> r; + // return K op K + BUILD(r, WASM_BINOP(opcode, WASM_F64(a), WASM_F64(b))); + CHECK_EQ(expected, r.Call()); + } + { + WasmRunner<int32_t> r(MachineType::Float64(), MachineType::Float64()); + // return a op b + BUILD(r, WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + CHECK_EQ(expected, r.Call(a, b)); + } +} + + +void TestFloat64BinopWithConvert(WasmOpcode opcode, int32_t expected, double a, + double b) { + { + WasmRunner<int32_t> r; + // return int(K op K) + BUILD(r, + WASM_I32_SCONVERT_F64(WASM_BINOP(opcode, WASM_F64(a), WASM_F64(b)))); + CHECK_EQ(expected, r.Call()); + } + { + WasmRunner<int32_t> r(MachineType::Float64(), MachineType::Float64()); + BUILD(r, WASM_I32_SCONVERT_F64( + WASM_BINOP(opcode, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)))); + CHECK_EQ(expected, r.Call(a, b)); + } +} + + +void TestFloat64UnopWithConvert(WasmOpcode opcode, int32_t expected, double a) { + { + WasmRunner<int32_t> r; + // return int(op(K)) + BUILD(r, WASM_I32_SCONVERT_F64(WASM_UNOP(opcode, WASM_F64(a)))); + CHECK_EQ(expected, r.Call()); + } + { + WasmRunner<int32_t> r(MachineType::Float64()); + // return int(op(a)) + BUILD(r, WASM_I32_SCONVERT_F64(WASM_UNOP(opcode, WASM_GET_LOCAL(0)))); + CHECK_EQ(expected, r.Call(a)); + } +} + + +// TODO(titzer): Fix for nosee4 and re-enable. +#if 0 + +TEST(Run_WasmFloat32Binops) { + TestFloat32Binop(kExprF32Eq, 1, 8.125f, 8.125f); + TestFloat32Binop(kExprF32Ne, 1, 8.125f, 8.127f); + TestFloat32Binop(kExprF32Lt, 1, -9.5f, -9.0f); + TestFloat32Binop(kExprF32Le, 1, -1111.0f, -1111.0f); + TestFloat32Binop(kExprF32Gt, 1, -9.0f, -9.5f); + TestFloat32Binop(kExprF32Ge, 1, -1111.0f, -1111.0f); + + TestFloat32BinopWithConvert(kExprF32Add, 10, 3.5f, 6.5f); + TestFloat32BinopWithConvert(kExprF32Sub, 2, 44.5f, 42.5f); + TestFloat32BinopWithConvert(kExprF32Mul, -66, -132.1f, 0.5f); + TestFloat32BinopWithConvert(kExprF32Div, 11, 22.1f, 2.0f); +} + + +TEST(Run_WasmFloat32Unops) { + TestFloat32UnopWithConvert(kExprF32Abs, 8, 8.125f); + TestFloat32UnopWithConvert(kExprF32Abs, 9, -9.125f); + TestFloat32UnopWithConvert(kExprF32Neg, -213, 213.125f); + TestFloat32UnopWithConvert(kExprF32Sqrt, 12, 144.4f); +} + + +TEST(Run_WasmFloat64Binops) { + TestFloat64Binop(kExprF64Eq, 1, 16.25, 16.25); + TestFloat64Binop(kExprF64Ne, 1, 16.25, 16.15); + TestFloat64Binop(kExprF64Lt, 1, -32.4, 11.7); + TestFloat64Binop(kExprF64Le, 1, -88.9, -88.9); + TestFloat64Binop(kExprF64Gt, 1, 11.7, -32.4); + TestFloat64Binop(kExprF64Ge, 1, -88.9, -88.9); + + TestFloat64BinopWithConvert(kExprF64Add, 100, 43.5, 56.5); + TestFloat64BinopWithConvert(kExprF64Sub, 200, 12200.1, 12000.1); + TestFloat64BinopWithConvert(kExprF64Mul, -33, 134, -0.25); + TestFloat64BinopWithConvert(kExprF64Div, -1111, -2222.3, 2); +} + + +TEST(Run_WasmFloat64Unops) { + TestFloat64UnopWithConvert(kExprF64Abs, 108, 108.125); + TestFloat64UnopWithConvert(kExprF64Abs, 209, -209.125); + TestFloat64UnopWithConvert(kExprF64Neg, -209, 209.125); + TestFloat64UnopWithConvert(kExprF64Sqrt, 13, 169.4); +} + +#endif + + +TEST(Run_WasmFloat32Neg) { + WasmRunner<float> r(MachineType::Float32()); + BUILD(r, WASM_F32_NEG(WASM_GET_LOCAL(0))); + + FOR_FLOAT32_INPUTS(i) { + CHECK_EQ(0x80000000, + bit_cast<uint32_t>(*i) ^ bit_cast<uint32_t>(r.Call(*i))); + } +} + + +TEST(Run_WasmFloat64Neg) { + WasmRunner<double> r(MachineType::Float64()); + BUILD(r, WASM_F64_NEG(WASM_GET_LOCAL(0))); + + FOR_FLOAT64_INPUTS(i) { + CHECK_EQ(0x8000000000000000, + bit_cast<uint64_t>(*i) ^ bit_cast<uint64_t>(r.Call(*i))); + } +} + + +TEST(Run_Wasm_IfElse_P) { + WasmRunner<int32_t> r(MachineType::Int32()); + // if (p0) return 11; else return 22; + BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // -- + WASM_I8(11), // -- + WASM_I8(22))); // -- + FOR_INT32_INPUTS(i) { + int32_t expected = *i ? 11 : 22; + CHECK_EQ(expected, r.Call(*i)); + } +} + + +TEST(Run_Wasm_IfElse_Unreachable1) { + WasmRunner<int32_t> r; + // if (0) unreachable; else return 22; + BUILD(r, WASM_IF_ELSE(WASM_ZERO, // -- + WASM_UNREACHABLE, // -- + WASM_I8(27))); // -- + CHECK_EQ(27, r.Call()); +} + + +TEST(Run_Wasm_Return12) { + WasmRunner<int32_t> r; + + BUILD(r, WASM_RETURN(WASM_I8(12))); + CHECK_EQ(12, r.Call()); +} + + +TEST(Run_Wasm_Return17) { + WasmRunner<int32_t> r; + + BUILD(r, WASM_BLOCK(1, WASM_RETURN(WASM_I8(17)))); + CHECK_EQ(17, r.Call()); +} + + +TEST(Run_Wasm_Return_I32) { + WasmRunner<int32_t> r(MachineType::Int32()); + + BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0))); + + FOR_INT32_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); } +} + + +#if WASM_64 +TEST(Run_Wasm_Return_I64) { + WasmRunner<int64_t> r(MachineType::Int64()); + + BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0))); + + FOR_INT64_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); } +} +#endif + + +TEST(Run_Wasm_Return_F32) { + WasmRunner<float> r(MachineType::Float32()); + + BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0))); + + FOR_FLOAT32_INPUTS(i) { + float expect = *i; + float result = r.Call(expect); + if (std::isnan(expect)) { + CHECK(std::isnan(result)); + } else { + CHECK_EQ(expect, result); + } + } +} + + +TEST(Run_Wasm_Return_F64) { + WasmRunner<double> r(MachineType::Float64()); + + BUILD(r, WASM_RETURN(WASM_GET_LOCAL(0))); + + FOR_FLOAT64_INPUTS(i) { + double expect = *i; + double result = r.Call(expect); + if (std::isnan(expect)) { + CHECK(std::isnan(result)); + } else { + CHECK_EQ(expect, result); + } + } +} + + +TEST(Run_Wasm_Select) { + WasmRunner<int32_t> r(MachineType::Int32()); + // return select(a, 11, 22); + BUILD(r, WASM_SELECT(WASM_GET_LOCAL(0), WASM_I8(11), WASM_I8(22))); + FOR_INT32_INPUTS(i) { + int32_t expected = *i ? 11 : 22; + CHECK_EQ(expected, r.Call(*i)); + } +} + + +TEST(Run_Wasm_Select_strict1) { + WasmRunner<int32_t> r(MachineType::Int32()); + // select(a, a = 11, 22); return a + BUILD(r, + WASM_BLOCK(2, WASM_SELECT(WASM_GET_LOCAL(0), + WASM_SET_LOCAL(0, WASM_I8(11)), WASM_I8(22)), + WASM_GET_LOCAL(0))); + FOR_INT32_INPUTS(i) { CHECK_EQ(11, r.Call(*i)); } +} + + +TEST(Run_Wasm_Select_strict2) { + WasmRunner<int32_t> r(MachineType::Int32()); + // select(a, 11, a = 22); return a; + BUILD(r, WASM_BLOCK(2, WASM_SELECT(WASM_GET_LOCAL(0), WASM_I8(11), + WASM_SET_LOCAL(0, WASM_I8(22))), + WASM_GET_LOCAL(0))); + FOR_INT32_INPUTS(i) { CHECK_EQ(22, r.Call(*i)); } +} + + +TEST(Run_Wasm_BrIf_strict) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK( + 2, WASM_BLOCK(1, WASM_BRV_IF(0, WASM_GET_LOCAL(0), + WASM_SET_LOCAL(0, WASM_I8(99)))), + WASM_GET_LOCAL(0))); + + FOR_INT32_INPUTS(i) { CHECK_EQ(99, r.Call(*i)); } +} + + +TEST(Run_Wasm_TableSwitch1) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_TABLESWITCH_OP(1, 1, WASM_CASE(0)), + WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(93)))); + FOR_INT32_INPUTS(i) { CHECK_EQ(93, r.Call(*i)); } +} + + +TEST(Run_Wasm_TableSwitch_br) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_TABLESWITCH_OP(1, 2, WASM_CASE_BR(0), WASM_CASE(0)), + WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(91))), + WASM_I8(99)); + CHECK_EQ(99, r.Call(0)); + CHECK_EQ(91, r.Call(1)); + CHECK_EQ(91, r.Call(2)); + CHECK_EQ(91, r.Call(3)); +} + + +TEST(Run_Wasm_TableSwitch_br2) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK( + 2, WASM_BLOCK(2, WASM_TABLESWITCH_OP( + 1, 4, WASM_CASE_BR(0), WASM_CASE_BR(1), + WASM_CASE_BR(2), WASM_CASE(0)), + WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), + WASM_RETURN(WASM_I8(85))), + WASM_RETURN(WASM_I8(86))), + WASM_RETURN(WASM_I8(87))), + WASM_I8(88)); + CHECK_EQ(86, r.Call(0)); + CHECK_EQ(87, r.Call(1)); + CHECK_EQ(88, r.Call(2)); + CHECK_EQ(85, r.Call(3)); + CHECK_EQ(85, r.Call(4)); + CHECK_EQ(85, r.Call(5)); +} + + +TEST(Run_Wasm_TableSwitch2) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_TABLESWITCH_OP(2, 2, WASM_CASE(0), WASM_CASE(1)), + WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(91)), + WASM_RETURN(WASM_I8(92)))); + FOR_INT32_INPUTS(i) { + int32_t expected = *i == 0 ? 91 : 92; + CHECK_EQ(expected, r.Call(*i)); + } +} + + +TEST(Run_Wasm_TableSwitch2b) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_TABLESWITCH_OP(2, 2, WASM_CASE(1), WASM_CASE(0)), + WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(81)), + WASM_RETURN(WASM_I8(82)))); + FOR_INT32_INPUTS(i) { + int32_t expected = *i == 0 ? 82 : 81; + CHECK_EQ(expected, r.Call(*i)); + } +} + + +TEST(Run_Wasm_TableSwitch4) { + for (int i = 0; i < 4; i++) { + const uint16_t br = 0x8000u; + uint16_t c = 0; + uint16_t cases[] = {i == 0 ? br : c++, i == 1 ? br : c++, i == 2 ? br : c++, + i == 3 ? br : c++}; + byte code[] = { + WASM_BLOCK(1, WASM_TABLESWITCH_OP( + 3, 4, WASM_CASE(cases[0]), WASM_CASE(cases[1]), + WASM_CASE(cases[2]), WASM_CASE(cases[3])), + WASM_TABLESWITCH_BODY( + WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(71)), + WASM_RETURN(WASM_I8(72)), WASM_RETURN(WASM_I8(73)))), + WASM_RETURN(WASM_I8(74))}; + + WasmRunner<int32_t> r(MachineType::Int32()); + r.Build(code, code + arraysize(code)); + + FOR_INT32_INPUTS(i) { + int index = (*i < 0 || *i > 3) ? 3 : *i; + int32_t expected = 71 + cases[index]; + if (expected >= 0x8000) expected = 74; + CHECK_EQ(expected, r.Call(*i)); + } + } +} + + +TEST(Run_Wasm_TableSwitch4b) { + for (int a = 0; a < 2; a++) { + for (int b = 0; b < 2; b++) { + for (int c = 0; c < 2; c++) { + for (int d = 0; d < 2; d++) { + if (a + b + c + d == 0) continue; + if (a + b + c + d == 4) continue; + + byte code[] = { + WASM_TABLESWITCH_OP(2, 4, WASM_CASE(a), WASM_CASE(b), + WASM_CASE(c), WASM_CASE(d)), + WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_RETURN(WASM_I8(61)), + WASM_RETURN(WASM_I8(62)))}; + + WasmRunner<int32_t> r(MachineType::Int32()); + r.Build(code, code + arraysize(code)); + + CHECK_EQ(61 + a, r.Call(0)); + CHECK_EQ(61 + b, r.Call(1)); + CHECK_EQ(61 + c, r.Call(2)); + CHECK_EQ(61 + d, r.Call(3)); + CHECK_EQ(61 + d, r.Call(4)); + } + } + } + } +} + + +TEST(Run_Wasm_TableSwitch4_fallthru) { + byte code[] = { + WASM_TABLESWITCH_OP(4, 4, WASM_CASE(0), WASM_CASE(1), WASM_CASE(2), + WASM_CASE(3)), + WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_INC_LOCAL_BY(1, 1), + WASM_INC_LOCAL_BY(1, 2), WASM_INC_LOCAL_BY(1, 4), + WASM_INC_LOCAL_BY(1, 8)), + WASM_GET_LOCAL(1)}; + + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + r.Build(code, code + arraysize(code)); + + CHECK_EQ(15, r.Call(0, 0)); + CHECK_EQ(14, r.Call(1, 0)); + CHECK_EQ(12, r.Call(2, 0)); + CHECK_EQ(8, r.Call(3, 0)); + CHECK_EQ(8, r.Call(4, 0)); + + CHECK_EQ(115, r.Call(0, 100)); + CHECK_EQ(114, r.Call(1, 100)); + CHECK_EQ(112, r.Call(2, 100)); + CHECK_EQ(108, r.Call(3, 100)); + CHECK_EQ(108, r.Call(4, 100)); +} + + +TEST(Run_Wasm_TableSwitch4_fallthru_br) { + byte code[] = { + WASM_TABLESWITCH_OP(4, 4, WASM_CASE(0), WASM_CASE(1), WASM_CASE(2), + WASM_CASE(3)), + WASM_TABLESWITCH_BODY(WASM_GET_LOCAL(0), WASM_INC_LOCAL_BY(1, 1), + WASM_BRV(0, WASM_INC_LOCAL_BY(1, 2)), + WASM_INC_LOCAL_BY(1, 4), + WASM_BRV(0, WASM_INC_LOCAL_BY(1, 8))), + WASM_GET_LOCAL(1)}; + + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + r.Build(code, code + arraysize(code)); + + CHECK_EQ(3, r.Call(0, 0)); + CHECK_EQ(2, r.Call(1, 0)); + CHECK_EQ(12, r.Call(2, 0)); + CHECK_EQ(8, r.Call(3, 0)); + CHECK_EQ(8, r.Call(4, 0)); + + CHECK_EQ(203, r.Call(0, 200)); + CHECK_EQ(202, r.Call(1, 200)); + CHECK_EQ(212, r.Call(2, 200)); + CHECK_EQ(208, r.Call(3, 200)); + CHECK_EQ(208, r.Call(4, 200)); +} + + +TEST(Run_Wasm_F32ReinterpretI32) { + WasmRunner<int32_t> r; + TestingModule module; + int32_t* memory = module.AddMemoryElems<int32_t>(8); + r.env()->module = &module; + + BUILD(r, WASM_I32_REINTERPRET_F32( + WASM_LOAD_MEM(MachineType::Float32(), WASM_ZERO))); + + FOR_INT32_INPUTS(i) { + int32_t expected = *i; + memory[0] = expected; + CHECK_EQ(expected, r.Call()); + } +} + + +TEST(Run_Wasm_I32ReinterpretF32) { + WasmRunner<int32_t> r(MachineType::Int32()); + TestingModule module; + int32_t* memory = module.AddMemoryElems<int32_t>(8); + r.env()->module = &module; + + BUILD(r, WASM_BLOCK( + 2, WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO, + WASM_F32_REINTERPRET_I32(WASM_GET_LOCAL(0))), + WASM_I8(107))); + + FOR_INT32_INPUTS(i) { + int32_t expected = *i; + CHECK_EQ(107, r.Call(expected)); + CHECK_EQ(expected, memory[0]); + } +} + + +TEST(Run_Wasm_ReturnStore) { + WasmRunner<int32_t> r; + TestingModule module; + int32_t* memory = module.AddMemoryElems<int32_t>(8); + r.env()->module = &module; + + BUILD(r, WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO, + WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO))); + + FOR_INT32_INPUTS(i) { + int32_t expected = *i; + memory[0] = expected; + CHECK_EQ(expected, r.Call()); + } +} + + +TEST(Run_Wasm_VoidReturn1) { + WasmRunner<void> r; + BUILD(r, kExprNop); + r.Call(); +} + + +TEST(Run_Wasm_VoidReturn2) { + WasmRunner<void> r; + BUILD(r, WASM_RETURN0); + r.Call(); +} + + +TEST(Run_Wasm_Block_If_P) { + WasmRunner<int32_t> r(MachineType::Int32()); + // { if (p0) return 51; return 52; } + BUILD(r, WASM_BLOCK(2, // -- + WASM_IF(WASM_GET_LOCAL(0), // -- + WASM_BRV(0, WASM_I8(51))), // -- + WASM_I8(52))); // -- + FOR_INT32_INPUTS(i) { + int32_t expected = *i ? 51 : 52; + CHECK_EQ(expected, r.Call(*i)); + } +} + + +TEST(Run_Wasm_Block_BrIf_P) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(51)), + WASM_I8(52))); + FOR_INT32_INPUTS(i) { + int32_t expected = *i ? 51 : 52; + CHECK_EQ(expected, r.Call(*i)); + } +} + + +TEST(Run_Wasm_Block_IfElse_P_assign) { + WasmRunner<int32_t> r(MachineType::Int32()); + // { if (p0) p0 = 71; else p0 = 72; return p0; } + BUILD(r, WASM_BLOCK(2, // -- + WASM_IF_ELSE(WASM_GET_LOCAL(0), // -- + WASM_SET_LOCAL(0, WASM_I8(71)), // -- + WASM_SET_LOCAL(0, WASM_I8(72))), // -- + WASM_GET_LOCAL(0))); + FOR_INT32_INPUTS(i) { + int32_t expected = *i ? 71 : 72; + CHECK_EQ(expected, r.Call(*i)); + } +} + + +TEST(Run_Wasm_Block_IfElse_P_return) { + WasmRunner<int32_t> r(MachineType::Int32()); + // if (p0) return 81; else return 82; + BUILD(r, // -- + WASM_IF_ELSE(WASM_GET_LOCAL(0), // -- + WASM_RETURN(WASM_I8(81)), // -- + WASM_RETURN(WASM_I8(82)))); // -- + FOR_INT32_INPUTS(i) { + int32_t expected = *i ? 81 : 82; + CHECK_EQ(expected, r.Call(*i)); + } +} + + +TEST(Run_Wasm_Block_If_P_assign) { + WasmRunner<int32_t> r(MachineType::Int32()); + // { if (p0) p0 = 61; p0; } + BUILD(r, WASM_BLOCK( + 2, WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(0, WASM_I8(61))), + WASM_GET_LOCAL(0))); + FOR_INT32_INPUTS(i) { + int32_t expected = *i ? 61 : *i; + CHECK_EQ(expected, r.Call(*i)); + } +} + + +TEST(Run_Wasm_DanglingAssign) { + WasmRunner<int32_t> r(MachineType::Int32()); + // { return 0; p0 = 0; } + BUILD(r, + WASM_BLOCK(2, WASM_RETURN(WASM_I8(99)), WASM_SET_LOCAL(0, WASM_ZERO))); + CHECK_EQ(99, r.Call(1)); +} + + +TEST(Run_Wasm_ExprIf_P) { + WasmRunner<int32_t> r(MachineType::Int32()); + // p0 ? 11 : 22; + BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // -- + WASM_I8(11), // -- + WASM_I8(22))); // -- + FOR_INT32_INPUTS(i) { + int32_t expected = *i ? 11 : 22; + CHECK_EQ(expected, r.Call(*i)); + } +} + + +TEST(Run_Wasm_ExprIf_P_fallthru) { + WasmRunner<int32_t> r(MachineType::Int32()); + // p0 ? 11 : 22; + BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // -- + WASM_I8(11), // -- + WASM_I8(22))); // -- + FOR_INT32_INPUTS(i) { + int32_t expected = *i ? 11 : 22; + CHECK_EQ(expected, r.Call(*i)); + } +} + + +TEST(Run_Wasm_CountDown) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, + WASM_BLOCK( + 2, WASM_LOOP( + 1, WASM_IF(WASM_GET_LOCAL(0), + WASM_BRV(0, WASM_SET_LOCAL( + 0, WASM_I32_SUB(WASM_GET_LOCAL(0), + WASM_I8(1)))))), + WASM_GET_LOCAL(0))); + CHECK_EQ(0, r.Call(1)); + CHECK_EQ(0, r.Call(10)); + CHECK_EQ(0, r.Call(100)); +} + + +TEST(Run_Wasm_CountDown_fallthru) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, + WASM_BLOCK( + 2, WASM_LOOP(3, WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)), WASM_BREAK(0)), + WASM_SET_LOCAL( + 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))), + WASM_CONTINUE(0)), + WASM_GET_LOCAL(0))); + CHECK_EQ(0, r.Call(1)); + CHECK_EQ(0, r.Call(10)); + CHECK_EQ(0, r.Call(100)); +} + + +TEST(Run_Wasm_WhileCountDown) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK( + 2, WASM_WHILE(WASM_GET_LOCAL(0), + WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), + WASM_I8(1)))), + WASM_GET_LOCAL(0))); + CHECK_EQ(0, r.Call(1)); + CHECK_EQ(0, r.Call(10)); + CHECK_EQ(0, r.Call(100)); +} + + +TEST(Run_Wasm_Loop_if_break1) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK(2, WASM_LOOP(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BREAK(0)), + WASM_SET_LOCAL(0, WASM_I8(99))), + WASM_GET_LOCAL(0))); + CHECK_EQ(99, r.Call(0)); + CHECK_EQ(3, r.Call(3)); + CHECK_EQ(10000, r.Call(10000)); + CHECK_EQ(-29, r.Call(-29)); +} + + +TEST(Run_Wasm_Loop_if_break2) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK(2, WASM_LOOP(2, WASM_BR_IF(1, WASM_GET_LOCAL(0)), + WASM_SET_LOCAL(0, WASM_I8(99))), + WASM_GET_LOCAL(0))); + CHECK_EQ(99, r.Call(0)); + CHECK_EQ(3, r.Call(3)); + CHECK_EQ(10000, r.Call(10000)); + CHECK_EQ(-29, r.Call(-29)); +} + + +TEST(Run_Wasm_Loop_if_break_fallthru) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK(1, WASM_LOOP(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BREAK(1)), + WASM_SET_LOCAL(0, WASM_I8(93)))), + WASM_GET_LOCAL(0)); + CHECK_EQ(93, r.Call(0)); + CHECK_EQ(3, r.Call(3)); + CHECK_EQ(10001, r.Call(10001)); + CHECK_EQ(-22, r.Call(-22)); +} + + +TEST(Run_Wasm_LoadMemI32) { + WasmRunner<int32_t> r(MachineType::Int32()); + TestingModule module; + int32_t* memory = module.AddMemoryElems<int32_t>(8); + module.RandomizeMemory(1111); + r.env()->module = &module; + + BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(0))); + + memory[0] = 99999999; + CHECK_EQ(99999999, r.Call(0)); + + memory[0] = 88888888; + CHECK_EQ(88888888, r.Call(0)); + + memory[0] = 77777777; + CHECK_EQ(77777777, r.Call(0)); +} + + +TEST(Run_Wasm_LoadMemI32_oob) { + WasmRunner<int32_t> r(MachineType::Uint32()); + TestingModule module; + int32_t* memory = module.AddMemoryElems<int32_t>(8); + module.RandomizeMemory(1111); + r.env()->module = &module; + + BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0))); + + memory[0] = 88888888; + CHECK_EQ(88888888, r.Call(0u)); + for (uint32_t offset = 29; offset < 40; offset++) { + CHECK_TRAP(r.Call(offset)); + } + + for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) { + CHECK_TRAP(r.Call(offset)); + } +} + + +TEST(Run_Wasm_LoadMemI32_oob_asm) { + WasmRunner<int32_t> r(MachineType::Uint32()); + TestingModule module; + module.asm_js = true; + int32_t* memory = module.AddMemoryElems<int32_t>(8); + module.RandomizeMemory(1112); + r.env()->module = &module; + + BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0))); + + memory[0] = 999999; + CHECK_EQ(999999, r.Call(0u)); + // TODO(titzer): offset 29-31 should also be OOB. + for (uint32_t offset = 32; offset < 40; offset++) { + CHECK_EQ(0, r.Call(offset)); + } + + for (uint32_t offset = 0x80000000; offset < 0x80000010; offset++) { + CHECK_EQ(0, r.Call(offset)); + } +} + + +TEST(Run_Wasm_LoadMem_offset_oob) { + TestingModule module; + module.AddMemoryElems<int32_t>(8); + + static const MachineType machineTypes[] = { + MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(), + MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(), + MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(), + MachineType::Float64()}; + + for (size_t m = 0; m < arraysize(machineTypes); m++) { + module.RandomizeMemory(1116 + static_cast<int>(m)); + WasmRunner<int32_t> r(MachineType::Uint32()); + r.env()->module = &module; + uint32_t boundary = 24 - WasmOpcodes::MemSize(machineTypes[m]); + + BUILD(r, WASM_LOAD_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0)), + WASM_ZERO); + + CHECK_EQ(0, r.Call(boundary)); // in bounds. + + for (uint32_t offset = boundary + 1; offset < boundary + 19; offset++) { + CHECK_TRAP(r.Call(offset)); // out of bounds. + } + } +} + + +TEST(Run_Wasm_LoadMemI32_offset) { + WasmRunner<int32_t> r(MachineType::Int32()); + TestingModule module; + int32_t* memory = module.AddMemoryElems<int32_t>(4); + module.RandomizeMemory(1111); + r.env()->module = &module; + + BUILD(r, WASM_LOAD_MEM_OFFSET(MachineType::Int32(), 4, WASM_GET_LOCAL(0))); + + memory[0] = 66666666; + memory[1] = 77777777; + memory[2] = 88888888; + memory[3] = 99999999; + CHECK_EQ(77777777, r.Call(0)); + CHECK_EQ(88888888, r.Call(4)); + CHECK_EQ(99999999, r.Call(8)); + + memory[0] = 11111111; + memory[1] = 22222222; + memory[2] = 33333333; + memory[3] = 44444444; + CHECK_EQ(22222222, r.Call(0)); + CHECK_EQ(33333333, r.Call(4)); + CHECK_EQ(44444444, r.Call(8)); +} + + +// TODO(titzer): Fix for mips and re-enable. +#if !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64 + +TEST(Run_Wasm_LoadMemI32_const_oob) { + TestingModule module; + const int kMemSize = 12; + module.AddMemoryElems<byte>(kMemSize); + + for (int offset = 0; offset < kMemSize + 5; offset++) { + for (int index = 0; index < kMemSize + 5; index++) { + WasmRunner<int32_t> r; + r.env()->module = &module; + module.RandomizeMemory(); + + BUILD(r, + WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset, WASM_I8(index))); + + if ((offset + index) <= (kMemSize - sizeof(int32_t))) { + CHECK_EQ(module.raw_val_at<int32_t>(offset + index), r.Call()); + } else { + CHECK_TRAP(r.Call()); + } + } + } +} + +#endif + + +TEST(Run_Wasm_StoreMemI32_offset) { + WasmRunner<int32_t> r(MachineType::Int32()); + const int32_t kWritten = 0xaabbccdd; + TestingModule module; + int32_t* memory = module.AddMemoryElems<int32_t>(4); + r.env()->module = &module; + + BUILD(r, WASM_STORE_MEM_OFFSET(MachineType::Int32(), 4, WASM_GET_LOCAL(0), + WASM_I32(kWritten))); + + for (int i = 0; i < 2; i++) { + module.RandomizeMemory(1111); + memory[0] = 66666666; + memory[1] = 77777777; + memory[2] = 88888888; + memory[3] = 99999999; + CHECK_EQ(kWritten, r.Call(i * 4)); + CHECK_EQ(66666666, memory[0]); + CHECK_EQ(i == 0 ? kWritten : 77777777, memory[1]); + CHECK_EQ(i == 1 ? kWritten : 88888888, memory[2]); + CHECK_EQ(i == 2 ? kWritten : 99999999, memory[3]); + } +} + + +TEST(Run_Wasm_StoreMem_offset_oob) { + TestingModule module; + byte* memory = module.AddMemoryElems<byte>(32); + +#if WASM_64 + static const MachineType machineTypes[] = { + MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(), + MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(), + MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(), + MachineType::Float64()}; +#else + static const MachineType machineTypes[] = { + MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(), + MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(), + MachineType::Float32(), MachineType::Float64()}; +#endif + + for (size_t m = 0; m < arraysize(machineTypes); m++) { + module.RandomizeMemory(1119 + static_cast<int>(m)); + WasmRunner<int32_t> r(MachineType::Uint32()); + r.env()->module = &module; + + BUILD(r, WASM_STORE_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0), + WASM_LOAD_MEM(machineTypes[m], WASM_ZERO)), + WASM_ZERO); + + byte memsize = WasmOpcodes::MemSize(machineTypes[m]); + uint32_t boundary = 24 - memsize; + CHECK_EQ(0, r.Call(boundary)); // in bounds. + CHECK_EQ(0, memcmp(&memory[0], &memory[8 + boundary], memsize)); + + for (uint32_t offset = boundary + 1; offset < boundary + 19; offset++) { + CHECK_TRAP(r.Call(offset)); // out of bounds. + } + } +} + + +#if WASM_64 +TEST(Run_Wasm_F64ReinterpretI64) { + WasmRunner<int64_t> r; + TestingModule module; + int64_t* memory = module.AddMemoryElems<int64_t>(8); + r.env()->module = &module; + + BUILD(r, WASM_I64_REINTERPRET_F64( + WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO))); + + FOR_INT32_INPUTS(i) { + int64_t expected = static_cast<int64_t>(*i) * 0x300010001; + memory[0] = expected; + CHECK_EQ(expected, r.Call()); + } +} + + +TEST(Run_Wasm_I64ReinterpretF64) { + WasmRunner<int64_t> r(MachineType::Int64()); + TestingModule module; + int64_t* memory = module.AddMemoryElems<int64_t>(8); + r.env()->module = &module; + + BUILD(r, WASM_BLOCK( + 2, WASM_STORE_MEM(MachineType::Float64(), WASM_ZERO, + WASM_F64_REINTERPRET_I64(WASM_GET_LOCAL(0))), + WASM_GET_LOCAL(0))); + + FOR_INT32_INPUTS(i) { + int64_t expected = static_cast<int64_t>(*i) * 0x300010001; + CHECK_EQ(expected, r.Call(expected)); + CHECK_EQ(expected, memory[0]); + } +} + + +TEST(Run_Wasm_LoadMemI64) { + WasmRunner<int64_t> r; + TestingModule module; + int64_t* memory = module.AddMemoryElems<int64_t>(8); + module.RandomizeMemory(1111); + r.env()->module = &module; + + BUILD(r, WASM_LOAD_MEM(MachineType::Int64(), WASM_I8(0))); + + memory[0] = 0xaabbccdd00112233LL; + CHECK_EQ(0xaabbccdd00112233LL, r.Call()); + + memory[0] = 0x33aabbccdd001122LL; + CHECK_EQ(0x33aabbccdd001122LL, r.Call()); + + memory[0] = 77777777; + CHECK_EQ(77777777, r.Call()); +} +#endif + + +TEST(Run_Wasm_LoadMemI32_P) { + const int kNumElems = 8; + WasmRunner<int32_t> r(MachineType::Int32()); + TestingModule module; + int32_t* memory = module.AddMemoryElems<int32_t>(kNumElems); + module.RandomizeMemory(2222); + r.env()->module = &module; + + BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0))); + + for (int i = 0; i < kNumElems; i++) { + CHECK_EQ(memory[i], r.Call(i * 4)); + } +} + + +TEST(Run_Wasm_MemI32_Sum) { + WasmRunner<uint32_t> r(MachineType::Int32()); + const int kNumElems = 20; + const byte kSum = r.AllocateLocal(kAstI32); + TestingModule module; + uint32_t* memory = module.AddMemoryElems<uint32_t>(kNumElems); + r.env()->module = &module; + + BUILD(r, WASM_BLOCK( + 2, WASM_WHILE( + WASM_GET_LOCAL(0), + WASM_BLOCK( + 2, WASM_SET_LOCAL( + kSum, WASM_I32_ADD( + WASM_GET_LOCAL(kSum), + WASM_LOAD_MEM(MachineType::Int32(), + WASM_GET_LOCAL(0)))), + WASM_SET_LOCAL( + 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(4))))), + WASM_GET_LOCAL(1))); + + // Run 4 trials. + for (int i = 0; i < 3; i++) { + module.RandomizeMemory(i * 33); + uint32_t expected = 0; + for (size_t j = kNumElems - 1; j > 0; j--) { + expected += memory[j]; + } + uint32_t result = r.Call(static_cast<int>(4 * (kNumElems - 1))); + CHECK_EQ(expected, result); + } +} + + +TEST(Run_Wasm_CheckMachIntsZero) { + WasmRunner<uint32_t> r(MachineType::Int32()); + const int kNumElems = 55; + TestingModule module; + module.AddMemoryElems<uint32_t>(kNumElems); + r.env()->module = &module; + + BUILD(r, kExprBlock, 2, kExprLoop, 1, kExprIf, kExprGetLocal, 0, kExprBr, 0, + kExprIfElse, kExprI32LoadMem, 0, kExprGetLocal, 0, kExprBr, 2, + kExprI8Const, 255, kExprSetLocal, 0, kExprI32Sub, kExprGetLocal, 0, + kExprI8Const, 4, kExprI8Const, 0); + + module.BlankMemory(); + CHECK_EQ(0, r.Call((kNumElems - 1) * 4)); +} + + +TEST(Run_Wasm_MemF32_Sum) { + WasmRunner<int32_t> r(MachineType::Int32()); + const byte kSum = r.AllocateLocal(kAstF32); + const int kSize = 5; + TestingModule module; + module.AddMemoryElems<float>(kSize); + float* buffer = module.raw_mem_start<float>(); + buffer[0] = -99.25; + buffer[1] = -888.25; + buffer[2] = -77.25; + buffer[3] = 66666.25; + buffer[4] = 5555.25; + r.env()->module = &module; + + BUILD(r, WASM_BLOCK( + 3, WASM_WHILE( + WASM_GET_LOCAL(0), + WASM_BLOCK( + 2, WASM_SET_LOCAL( + kSum, WASM_F32_ADD( + WASM_GET_LOCAL(kSum), + WASM_LOAD_MEM(MachineType::Float32(), + WASM_GET_LOCAL(0)))), + WASM_SET_LOCAL( + 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(4))))), + WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO, + WASM_GET_LOCAL(kSum)), + WASM_GET_LOCAL(0))); + + CHECK_EQ(0, r.Call(4 * (kSize - 1))); + CHECK_NE(-99.25, buffer[0]); + CHECK_EQ(71256.0f, buffer[0]); +} + + +#if WASM_64 +TEST(Run_Wasm_MemI64_Sum) { + WasmRunner<uint64_t> r(MachineType::Int32()); + const int kNumElems = 20; + const byte kSum = r.AllocateLocal(kAstI64); + TestingModule module; + uint64_t* memory = module.AddMemoryElems<uint64_t>(kNumElems); + r.env()->module = &module; + + BUILD(r, WASM_BLOCK( + 2, WASM_WHILE( + WASM_GET_LOCAL(0), + WASM_BLOCK( + 2, WASM_SET_LOCAL( + kSum, WASM_I64_ADD( + WASM_GET_LOCAL(kSum), + WASM_LOAD_MEM(MachineType::Int64(), + WASM_GET_LOCAL(0)))), + WASM_SET_LOCAL( + 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(8))))), + WASM_GET_LOCAL(1))); + + // Run 4 trials. + for (int i = 0; i < 3; i++) { + module.RandomizeMemory(i * 33); + uint64_t expected = 0; + for (size_t j = kNumElems - 1; j > 0; j--) { + expected += memory[j]; + } + uint64_t result = r.Call(8 * (kNumElems - 1)); + CHECK_EQ(expected, result); + } +} +#endif + + +template <typename T> +T GenerateAndRunFold(WasmOpcode binop, T* buffer, size_t size, + LocalType astType, MachineType memType) { + WasmRunner<int32_t> r(MachineType::Int32()); + const byte kAccum = r.AllocateLocal(astType); + TestingModule module; + module.AddMemoryElems<T>(size); + for (size_t i = 0; i < size; i++) { + module.raw_mem_start<T>()[i] = buffer[i]; + } + r.env()->module = &module; + + BUILD( + r, + WASM_BLOCK( + 4, WASM_SET_LOCAL(kAccum, WASM_LOAD_MEM(memType, WASM_ZERO)), + WASM_WHILE( + WASM_GET_LOCAL(0), + WASM_BLOCK( + 2, WASM_SET_LOCAL( + kAccum, + WASM_BINOP(binop, WASM_GET_LOCAL(kAccum), + WASM_LOAD_MEM(memType, WASM_GET_LOCAL(0)))), + WASM_SET_LOCAL( + 0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(sizeof(T)))))), + WASM_STORE_MEM(memType, WASM_ZERO, WASM_GET_LOCAL(kAccum)), + WASM_GET_LOCAL(0))); + r.Call(static_cast<int>(sizeof(T) * (size - 1))); + return module.raw_mem_at<double>(0); +} + + +TEST(Run_Wasm_MemF64_Mul) { + const size_t kSize = 6; + double buffer[kSize] = {1, 2, 2, 2, 2, 2}; + double result = GenerateAndRunFold<double>(kExprF64Mul, buffer, kSize, + kAstF64, MachineType::Float64()); + CHECK_EQ(32, result); +} + + +TEST(Build_Wasm_Infinite_Loop) { + WasmRunner<int32_t> r(MachineType::Int32()); + // Only build the graph and compile, don't run. + BUILD(r, WASM_INFINITE_LOOP); +} + + +TEST(Build_Wasm_Infinite_Loop_effect) { + WasmRunner<int32_t> r(MachineType::Int32()); + TestingModule module; + module.AddMemoryElems<int8_t>(16); + r.env()->module = &module; + + // Only build the graph and compile, don't run. + BUILD(r, WASM_LOOP(1, WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO))); +} + + +TEST(Run_Wasm_Unreachable0a) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, + WASM_BLOCK(2, WASM_BRV(0, WASM_I8(9)), WASM_RETURN(WASM_GET_LOCAL(0)))); + CHECK_EQ(9, r.Call(0)); + CHECK_EQ(9, r.Call(1)); +} + + +TEST(Run_Wasm_Unreachable0b) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK(2, WASM_BRV(0, WASM_I8(7)), WASM_UNREACHABLE)); + CHECK_EQ(7, r.Call(0)); + CHECK_EQ(7, r.Call(1)); +} + + +TEST(Build_Wasm_Unreachable1) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_UNREACHABLE); +} + + +TEST(Build_Wasm_Unreachable2) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_UNREACHABLE, WASM_UNREACHABLE); +} + + +TEST(Build_Wasm_Unreachable3) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_UNREACHABLE, WASM_UNREACHABLE, WASM_UNREACHABLE); +} + + +TEST(Build_Wasm_UnreachableIf1) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_UNREACHABLE, WASM_IF(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0))); +} + + +TEST(Build_Wasm_UnreachableIf2) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_UNREACHABLE, + WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_GET_LOCAL(0), WASM_UNREACHABLE)); +} + + +TEST(Run_Wasm_Unreachable_Load) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK(2, WASM_BRV(0, WASM_GET_LOCAL(0)), + WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0)))); + CHECK_EQ(11, r.Call(11)); + CHECK_EQ(21, r.Call(21)); +} + + +TEST(Run_Wasm_Infinite_Loop_not_taken1) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK(2, WASM_IF(WASM_GET_LOCAL(0), WASM_INFINITE_LOOP), + WASM_I8(45))); + // Run the code, but don't go into the infinite loop. + CHECK_EQ(45, r.Call(0)); +} + + +TEST(Run_Wasm_Infinite_Loop_not_taken2) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, + WASM_BLOCK(1, WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(45)), + WASM_INFINITE_LOOP))); + // Run the code, but don't go into the infinite loop. + CHECK_EQ(45, r.Call(1)); +} + + +TEST(Run_Wasm_Infinite_Loop_not_taken2_brif) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(45)), + WASM_INFINITE_LOOP)); + // Run the code, but don't go into the infinite loop. + CHECK_EQ(45, r.Call(1)); +} + + +static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) { + if (!WasmOpcodes::IsSupported(opcode)) return; + + Zone zone; + Isolate* isolate = CcTest::InitIsolateOnce(); + HandleScope scope(isolate); + // Enable all optional operators. + CommonOperatorBuilder common(&zone); + MachineOperatorBuilder machine(&zone, MachineType::PointerRepresentation(), + MachineOperatorBuilder::kAllOptionalOps); + Graph graph(&zone); + JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); + FunctionEnv env; + FunctionSig* sig = WasmOpcodes::Signature(opcode); + init_env(&env, sig); + + if (sig->parameter_count() == 1) { + byte code[] = {static_cast<byte>(opcode), kExprGetLocal, 0}; + TestBuildingGraph(&zone, &jsgraph, &env, code, code + arraysize(code)); + } else { + CHECK_EQ(2, sig->parameter_count()); + byte code[] = {static_cast<byte>(opcode), kExprGetLocal, 0, kExprGetLocal, + 1}; + TestBuildingGraph(&zone, &jsgraph, &env, code, code + arraysize(code)); + } +} + + +TEST(Build_Wasm_SimpleExprs) { +// Test that the decoder can build a graph for all supported simple expressions. +#define GRAPH_BUILD_TEST(name, opcode, sig) \ + TestBuildGraphForSimpleExpression(kExpr##name); + + FOREACH_SIMPLE_OPCODE(GRAPH_BUILD_TEST); + +#undef GRAPH_BUILD_TEST +} + + +TEST(Run_Wasm_Int32LoadInt8_signext) { + TestingModule module; + const int kNumElems = 16; + int8_t* memory = module.AddMemoryElems<int8_t>(kNumElems); + module.RandomizeMemory(); + memory[0] = -1; + WasmRunner<int32_t> r(MachineType::Int32()); + r.env()->module = &module; + BUILD(r, WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0))); + + for (size_t i = 0; i < kNumElems; i++) { + CHECK_EQ(memory[i], r.Call(static_cast<int>(i))); + } +} + + +TEST(Run_Wasm_Int32LoadInt8_zeroext) { + TestingModule module; + const int kNumElems = 16; + byte* memory = module.AddMemory(kNumElems); + module.RandomizeMemory(77); + memory[0] = 255; + WasmRunner<int32_t> r(MachineType::Int32()); + r.env()->module = &module; + BUILD(r, WASM_LOAD_MEM(MachineType::Uint8(), WASM_GET_LOCAL(0))); + + for (size_t i = 0; i < kNumElems; i++) { + CHECK_EQ(memory[i], r.Call(static_cast<int>(i))); + } +} + + +TEST(Run_Wasm_Int32LoadInt16_signext) { + TestingModule module; + const int kNumBytes = 16; + byte* memory = module.AddMemory(kNumBytes); + module.RandomizeMemory(888); + memory[1] = 200; + WasmRunner<int32_t> r(MachineType::Int32()); + r.env()->module = &module; + BUILD(r, WASM_LOAD_MEM(MachineType::Int16(), WASM_GET_LOCAL(0))); + + for (size_t i = 0; i < kNumBytes; i += 2) { + int32_t expected = memory[i] | (static_cast<int8_t>(memory[i + 1]) << 8); + CHECK_EQ(expected, r.Call(static_cast<int>(i))); + } +} + + +TEST(Run_Wasm_Int32LoadInt16_zeroext) { + TestingModule module; + const int kNumBytes = 16; + byte* memory = module.AddMemory(kNumBytes); + module.RandomizeMemory(9999); + memory[1] = 204; + WasmRunner<int32_t> r(MachineType::Int32()); + r.env()->module = &module; + BUILD(r, WASM_LOAD_MEM(MachineType::Uint16(), WASM_GET_LOCAL(0))); + + for (size_t i = 0; i < kNumBytes; i += 2) { + int32_t expected = memory[i] | (memory[i + 1] << 8); + CHECK_EQ(expected, r.Call(static_cast<int>(i))); + } +} + + +TEST(Run_WasmInt32Global) { + TestingModule module; + int32_t* global = module.AddGlobal<int32_t>(MachineType::Int32()); + WasmRunner<int32_t> r(MachineType::Int32()); + r.env()->module = &module; + // global = global + p0 + BUILD(r, WASM_STORE_GLOBAL( + 0, WASM_I32_ADD(WASM_LOAD_GLOBAL(0), WASM_GET_LOCAL(0)))); + + *global = 116; + for (int i = 9; i < 444444; i += 111111) { + int32_t expected = *global + i; + r.Call(i); + CHECK_EQ(expected, *global); + } +} + + +TEST(Run_WasmInt32Globals_DontAlias) { + const int kNumGlobals = 3; + TestingModule module; + int32_t* globals[] = {module.AddGlobal<int32_t>(MachineType::Int32()), + module.AddGlobal<int32_t>(MachineType::Int32()), + module.AddGlobal<int32_t>(MachineType::Int32())}; + + for (int g = 0; g < kNumGlobals; g++) { + // global = global + p0 + WasmRunner<int32_t> r(MachineType::Int32()); + r.env()->module = &module; + BUILD(r, WASM_STORE_GLOBAL( + g, WASM_I32_ADD(WASM_LOAD_GLOBAL(g), WASM_GET_LOCAL(0)))); + + // Check that reading/writing global number {g} doesn't alter the others. + *globals[g] = 116 * g; + int32_t before[kNumGlobals]; + for (int i = 9; i < 444444; i += 111113) { + int32_t sum = *globals[g] + i; + for (int j = 0; j < kNumGlobals; j++) before[j] = *globals[j]; + r.Call(i); + for (int j = 0; j < kNumGlobals; j++) { + int32_t expected = j == g ? sum : before[j]; + CHECK_EQ(expected, *globals[j]); + } + } + } +} + + +#if WASM_64 +TEST(Run_WasmInt64Global) { + TestingModule module; + int64_t* global = module.AddGlobal<int64_t>(MachineType::Int64()); + WasmRunner<int32_t> r(MachineType::Int32()); + r.env()->module = &module; + // global = global + p0 + BUILD(r, WASM_BLOCK(2, WASM_STORE_GLOBAL( + 0, WASM_I64_ADD( + WASM_LOAD_GLOBAL(0), + WASM_I64_SCONVERT_I32(WASM_GET_LOCAL(0)))), + WASM_ZERO)); + + *global = 0xFFFFFFFFFFFFFFFFLL; + for (int i = 9; i < 444444; i += 111111) { + int64_t expected = *global + i; + r.Call(i); + CHECK_EQ(expected, *global); + } +} +#endif + + +TEST(Run_WasmFloat32Global) { + TestingModule module; + float* global = module.AddGlobal<float>(MachineType::Float32()); + WasmRunner<int32_t> r(MachineType::Int32()); + r.env()->module = &module; + // global = global + p0 + BUILD(r, WASM_BLOCK(2, WASM_STORE_GLOBAL( + 0, WASM_F32_ADD( + WASM_LOAD_GLOBAL(0), + WASM_F32_SCONVERT_I32(WASM_GET_LOCAL(0)))), + WASM_ZERO)); + + *global = 1.25; + for (int i = 9; i < 4444; i += 1111) { + volatile float expected = *global + i; + r.Call(i); + CHECK_EQ(expected, *global); + } +} + + +TEST(Run_WasmFloat64Global) { + TestingModule module; + double* global = module.AddGlobal<double>(MachineType::Float64()); + WasmRunner<int32_t> r(MachineType::Int32()); + r.env()->module = &module; + // global = global + p0 + BUILD(r, WASM_BLOCK(2, WASM_STORE_GLOBAL( + 0, WASM_F64_ADD( + WASM_LOAD_GLOBAL(0), + WASM_F64_SCONVERT_I32(WASM_GET_LOCAL(0)))), + WASM_ZERO)); + + *global = 1.25; + for (int i = 9; i < 4444; i += 1111) { + volatile double expected = *global + i; + r.Call(i); + CHECK_EQ(expected, *global); + } +} + + +TEST(Run_WasmMixedGlobals) { + TestingModule module; + int32_t* unused = module.AddGlobal<int32_t>(MachineType::Int32()); + byte* memory = module.AddMemory(32); + + int8_t* var_int8 = module.AddGlobal<int8_t>(MachineType::Int8()); + uint8_t* var_uint8 = module.AddGlobal<uint8_t>(MachineType::Uint8()); + int16_t* var_int16 = module.AddGlobal<int16_t>(MachineType::Int16()); + uint16_t* var_uint16 = module.AddGlobal<uint16_t>(MachineType::Uint16()); + int32_t* var_int32 = module.AddGlobal<int32_t>(MachineType::Int32()); + uint32_t* var_uint32 = module.AddGlobal<uint32_t>(MachineType::Uint32()); + float* var_float = module.AddGlobal<float>(MachineType::Float32()); + double* var_double = module.AddGlobal<double>(MachineType::Float64()); + + WasmRunner<int32_t> r(MachineType::Int32()); + r.env()->module = &module; + + BUILD( + r, + WASM_BLOCK( + 9, + WASM_STORE_GLOBAL(1, WASM_LOAD_MEM(MachineType::Int8(), WASM_ZERO)), + WASM_STORE_GLOBAL(2, WASM_LOAD_MEM(MachineType::Uint8(), WASM_ZERO)), + WASM_STORE_GLOBAL(3, WASM_LOAD_MEM(MachineType::Int16(), WASM_ZERO)), + WASM_STORE_GLOBAL(4, WASM_LOAD_MEM(MachineType::Uint16(), WASM_ZERO)), + WASM_STORE_GLOBAL(5, WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)), + WASM_STORE_GLOBAL(6, WASM_LOAD_MEM(MachineType::Uint32(), WASM_ZERO)), + WASM_STORE_GLOBAL(7, + WASM_LOAD_MEM(MachineType::Float32(), WASM_ZERO)), + WASM_STORE_GLOBAL(8, + WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO)), + WASM_ZERO)); + + memory[0] = 0xaa; + memory[1] = 0xcc; + memory[2] = 0x55; + memory[3] = 0xee; + memory[4] = 0x33; + memory[5] = 0x22; + memory[6] = 0x11; + memory[7] = 0x99; + r.Call(1); + + CHECK(static_cast<int8_t>(0xaa) == *var_int8); + CHECK(static_cast<uint8_t>(0xaa) == *var_uint8); + CHECK(static_cast<int16_t>(0xccaa) == *var_int16); + CHECK(static_cast<uint16_t>(0xccaa) == *var_uint16); + CHECK(static_cast<int32_t>(0xee55ccaa) == *var_int32); + CHECK(static_cast<uint32_t>(0xee55ccaa) == *var_uint32); + CHECK(bit_cast<float>(0xee55ccaa) == *var_float); + CHECK(bit_cast<double>(0x99112233ee55ccaaULL) == *var_double); + + USE(unused); +} + + +#if WASM_64 +// Test the WasmRunner with an Int64 return value and different numbers of +// Int64 parameters. +TEST(Run_TestI64WasmRunner) { + { + FOR_INT64_INPUTS(i) { + WasmRunner<int64_t> r; + BUILD(r, WASM_I64(*i)); + CHECK_EQ(*i, r.Call()); + } + } + { + WasmRunner<int64_t> r(MachineType::Int64()); + BUILD(r, WASM_GET_LOCAL(0)); + FOR_INT64_INPUTS(i) { CHECK_EQ(*i, r.Call(*i)); } + } + { + WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); + BUILD(r, WASM_I64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + FOR_INT64_INPUTS(i) { + FOR_INT64_INPUTS(j) { CHECK_EQ(*i + *j, r.Call(*i, *j)); } + } + } + { + WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64(), + MachineType::Int64()); + BUILD(r, WASM_I64_ADD(WASM_GET_LOCAL(0), + WASM_I64_ADD(WASM_GET_LOCAL(1), WASM_GET_LOCAL(2)))); + FOR_INT64_INPUTS(i) { + FOR_INT64_INPUTS(j) { + CHECK_EQ(*i + *j + *j, r.Call(*i, *j, *j)); + CHECK_EQ(*j + *i + *j, r.Call(*j, *i, *j)); + CHECK_EQ(*j + *j + *i, r.Call(*j, *j, *i)); + } + } + } + { + WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64(), + MachineType::Int64(), MachineType::Int64()); + BUILD(r, WASM_I64_ADD(WASM_GET_LOCAL(0), + WASM_I64_ADD(WASM_GET_LOCAL(1), + WASM_I64_ADD(WASM_GET_LOCAL(2), + WASM_GET_LOCAL(3))))); + FOR_INT64_INPUTS(i) { + FOR_INT64_INPUTS(j) { + CHECK_EQ(*i + *j + *j + *j, r.Call(*i, *j, *j, *j)); + CHECK_EQ(*j + *i + *j + *j, r.Call(*j, *i, *j, *j)); + CHECK_EQ(*j + *j + *i + *j, r.Call(*j, *j, *i, *j)); + CHECK_EQ(*j + *j + *j + *i, r.Call(*j, *j, *j, *i)); + } + } + } +} +#endif + + +TEST(Run_WasmCallEmpty) { + const int32_t kExpected = -414444; + // Build the target function. + TestSignatures sigs; + TestingModule module; + WasmFunctionCompiler t(sigs.i_v()); + BUILD(t, WASM_I32(kExpected)); + uint32_t index = t.CompileAndAdd(&module); + + // Build the calling function. + WasmRunner<int32_t> r; + r.env()->module = &module; + BUILD(r, WASM_CALL_FUNCTION0(index)); + + int32_t result = r.Call(); + CHECK_EQ(kExpected, result); +} + + +// TODO(tizer): Fix on arm and reenable. +#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 + +TEST(Run_WasmCallF32StackParameter) { + // Build the target function. + LocalType param_types[20]; + for (int i = 0; i < 20; i++) param_types[i] = kAstF32; + FunctionSig sig(1, 19, param_types); + TestingModule module; + WasmFunctionCompiler t(&sig); + BUILD(t, WASM_GET_LOCAL(17)); + uint32_t index = t.CompileAndAdd(&module); + + // Build the calling function. + WasmRunner<float> r; + r.env()->module = &module; + BUILD(r, WASM_CALL_FUNCTION( + index, WASM_F32(1.0f), WASM_F32(2.0f), WASM_F32(4.0f), + WASM_F32(8.0f), WASM_F32(16.0f), WASM_F32(32.0f), + WASM_F32(64.0f), WASM_F32(128.0f), WASM_F32(256.0f), + WASM_F32(1.5f), WASM_F32(2.5f), WASM_F32(4.5f), WASM_F32(8.5f), + WASM_F32(16.5f), WASM_F32(32.5f), WASM_F32(64.5f), + WASM_F32(128.5f), WASM_F32(256.5f), WASM_F32(512.5f))); + + float result = r.Call(); + CHECK_EQ(256.5f, result); +} + + +TEST(Run_WasmCallF64StackParameter) { + // Build the target function. + LocalType param_types[20]; + for (int i = 0; i < 20; i++) param_types[i] = kAstF64; + FunctionSig sig(1, 19, param_types); + TestingModule module; + WasmFunctionCompiler t(&sig); + BUILD(t, WASM_GET_LOCAL(17)); + uint32_t index = t.CompileAndAdd(&module); + + // Build the calling function. + WasmRunner<double> r; + r.env()->module = &module; + BUILD(r, WASM_CALL_FUNCTION(index, WASM_F64(1.0), WASM_F64(2.0), + WASM_F64(4.0), WASM_F64(8.0), WASM_F64(16.0), + WASM_F64(32.0), WASM_F64(64.0), WASM_F64(128.0), + WASM_F64(256.0), WASM_F64(1.5), WASM_F64(2.5), + WASM_F64(4.5), WASM_F64(8.5), WASM_F64(16.5), + WASM_F64(32.5), WASM_F64(64.5), WASM_F64(128.5), + WASM_F64(256.5), WASM_F64(512.5))); + + float result = r.Call(); + CHECK_EQ(256.5, result); +} + +#endif + + +TEST(Run_WasmCallVoid) { + const byte kMemOffset = 8; + const int32_t kElemNum = kMemOffset / sizeof(int32_t); + const int32_t kExpected = -414444; + // Build the target function. + TestSignatures sigs; + TestingModule module; + module.AddMemory(16); + module.RandomizeMemory(); + WasmFunctionCompiler t(sigs.v_v()); + t.env.module = &module; + BUILD(t, WASM_STORE_MEM(MachineType::Int32(), WASM_I8(kMemOffset), + WASM_I32(kExpected))); + uint32_t index = t.CompileAndAdd(&module); + + // Build the calling function. + WasmRunner<int32_t> r; + r.env()->module = &module; + BUILD(r, WASM_CALL_FUNCTION0(index), + WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kMemOffset))); + + int32_t result = r.Call(); + CHECK_EQ(kExpected, result); + CHECK_EQ(kExpected, module.raw_mem_start<int32_t>()[kElemNum]); +} + + +TEST(Run_WasmCall_Int32Add) { + // Build the target function. + TestSignatures sigs; + TestingModule module; + WasmFunctionCompiler t(sigs.i_ii()); + BUILD(t, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + uint32_t index = t.CompileAndAdd(&module); + + // Build the caller function. + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + r.env()->module = &module; + BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + + 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)); + CHECK_EQ(expected, r.Call(*i, *j)); + } + } +} + + +#if WASM_64 +TEST(Run_WasmCall_Int64Sub) { + // Build the target function. + TestSignatures sigs; + TestingModule module; + WasmFunctionCompiler t(sigs.l_ll()); + BUILD(t, WASM_I64_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + uint32_t index = t.CompileAndAdd(&module); + + // Build the caller function. + WasmRunner<int64_t> r(MachineType::Int64(), MachineType::Int64()); + r.env()->module = &module; + BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + + FOR_INT32_INPUTS(i) { + FOR_INT32_INPUTS(j) { + int64_t a = static_cast<int64_t>(*i) << 32 | + (static_cast<int64_t>(*j) | 0xFFFFFFFF); + int64_t b = static_cast<int64_t>(*j) << 32 | + (static_cast<int64_t>(*i) | 0xFFFFFFFF); + + int64_t expected = static_cast<int64_t>(static_cast<uint64_t>(a) - + static_cast<uint64_t>(b)); + CHECK_EQ(expected, r.Call(a, b)); + } + } +} +#endif + + +TEST(Run_WasmCall_Float32Sub) { + TestSignatures sigs; + WasmFunctionCompiler t(sigs.f_ff()); + + // Build the target function. + TestingModule module; + BUILD(t, WASM_F32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + uint32_t index = t.CompileAndAdd(&module); + + // Builder the caller function. + WasmRunner<float> r(MachineType::Float32(), MachineType::Float32()); + r.env()->module = &module; + BUILD(r, WASM_CALL_FUNCTION(index, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + + FOR_FLOAT32_INPUTS(i) { + FOR_FLOAT32_INPUTS(j) { + volatile float expected = *i - *j; + CheckFloatEq(expected, r.Call(*i, *j)); + } + } +} + + +TEST(Run_WasmCall_Float64Sub) { + WasmRunner<int32_t> r; + TestingModule module; + double* memory = module.AddMemoryElems<double>(16); + r.env()->module = &module; + + // TODO(titzer): convert to a binop test. + BUILD(r, WASM_BLOCK( + 2, WASM_STORE_MEM( + MachineType::Float64(), WASM_ZERO, + WASM_F64_SUB( + WASM_LOAD_MEM(MachineType::Float64(), WASM_ZERO), + WASM_LOAD_MEM(MachineType::Float64(), WASM_I8(8)))), + WASM_I8(107))); + + FOR_FLOAT64_INPUTS(i) { + FOR_FLOAT64_INPUTS(j) { + memory[0] = *i; + memory[1] = *j; + double expected = *i - *j; + CHECK_EQ(107, r.Call()); + if (expected != expected) { + CHECK(memory[0] != memory[0]); + } else { + CHECK_EQ(expected, memory[0]); + } + } + } +} + +#define ADD_CODE(vec, ...) \ + do { \ + byte __buf[] = {__VA_ARGS__}; \ + for (size_t i = 0; i < sizeof(__buf); i++) vec.push_back(__buf[i]); \ + } while (false) + + +static void Run_WasmMixedCall_N(int start) { + const int kExpected = 6333; + const int kElemSize = 8; + TestSignatures sigs; + +#if WASM_64 + static MachineType mixed[] = { + MachineType::Int32(), MachineType::Float32(), MachineType::Int64(), + MachineType::Float64(), MachineType::Float32(), MachineType::Int64(), + MachineType::Int32(), MachineType::Float64(), MachineType::Float32(), + MachineType::Float64(), MachineType::Int32(), MachineType::Int64(), + MachineType::Int32(), MachineType::Int32()}; +#else + static MachineType mixed[] = { + MachineType::Int32(), MachineType::Float32(), MachineType::Float64(), + MachineType::Float32(), MachineType::Int32(), MachineType::Float64(), + MachineType::Float32(), MachineType::Float64(), MachineType::Int32(), + MachineType::Int32(), MachineType::Int32()}; +#endif + + int num_params = static_cast<int>(arraysize(mixed)) - start; + for (int which = 0; which < num_params; which++) { + Zone zone; + TestingModule module; + module.AddMemory(1024); + MachineType* memtypes = &mixed[start]; + MachineType result = memtypes[which]; + + // ========================================================================= + // Build the selector function. + // ========================================================================= + uint32_t index; + FunctionSig::Builder b(&zone, 1, num_params); + b.AddReturn(WasmOpcodes::LocalTypeFor(result)); + for (int i = 0; i < num_params; i++) { + b.AddParam(WasmOpcodes::LocalTypeFor(memtypes[i])); + } + WasmFunctionCompiler t(b.Build()); + t.env.module = &module; + BUILD(t, WASM_GET_LOCAL(which)); + index = t.CompileAndAdd(&module); + + // ========================================================================= + // Build the calling function. + // ========================================================================= + WasmRunner<int32_t> r; + r.env()->module = &module; + + { + std::vector<byte> code; + ADD_CODE(code, + static_cast<byte>(WasmOpcodes::LoadStoreOpcodeOf(result, true)), + WasmOpcodes::LoadStoreAccessOf(false)); + ADD_CODE(code, WASM_ZERO); + ADD_CODE(code, kExprCallFunction, static_cast<byte>(index)); + + for (int i = 0; i < num_params; i++) { + int offset = (i + 1) * kElemSize; + ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I8(offset))); + } + + ADD_CODE(code, WASM_I32(kExpected)); + size_t end = code.size(); + code.push_back(0); + r.Build(&code[0], &code[end]); + } + + // Run the code. + for (int t = 0; t < 10; t++) { + module.RandomizeMemory(); + CHECK_EQ(kExpected, r.Call()); + + int size = WasmOpcodes::MemSize(result); + for (int i = 0; i < size; i++) { + int base = (which + 1) * kElemSize; + byte expected = module.raw_mem_at<byte>(base + i); + byte result = module.raw_mem_at<byte>(i); + CHECK_EQ(expected, result); + } + } + } +} + + +TEST(Run_WasmMixedCall_0) { Run_WasmMixedCall_N(0); } +TEST(Run_WasmMixedCall_1) { Run_WasmMixedCall_N(1); } +TEST(Run_WasmMixedCall_2) { Run_WasmMixedCall_N(2); } +TEST(Run_WasmMixedCall_3) { Run_WasmMixedCall_N(3); } + + +TEST(Run_Wasm_CountDown_expr) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_LOOP( + 3, WASM_IF(WASM_NOT(WASM_GET_LOCAL(0)), + WASM_BREAKV(0, WASM_GET_LOCAL(0))), + WASM_SET_LOCAL(0, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_I8(1))), + WASM_CONTINUE(0))); + CHECK_EQ(0, r.Call(1)); + CHECK_EQ(0, r.Call(10)); + CHECK_EQ(0, r.Call(100)); +} + + +TEST(Run_Wasm_ExprBlock2a) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(1))), + WASM_I8(1))); + CHECK_EQ(1, r.Call(0)); + CHECK_EQ(1, r.Call(1)); +} + + +TEST(Run_Wasm_ExprBlock2b) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK(2, WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(1))), + WASM_I8(2))); + CHECK_EQ(2, r.Call(0)); + CHECK_EQ(1, r.Call(1)); +} + + +TEST(Run_Wasm_ExprBlock2c) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(1)), + WASM_I8(1))); + CHECK_EQ(1, r.Call(0)); + CHECK_EQ(1, r.Call(1)); +} + + +TEST(Run_Wasm_ExprBlock2d) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK(2, WASM_BRV_IF(0, WASM_GET_LOCAL(0), WASM_I8(1)), + WASM_I8(2))); + CHECK_EQ(2, r.Call(0)); + CHECK_EQ(1, r.Call(1)); +} + + +TEST(Run_Wasm_ExprBlock_ManualSwitch) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, WASM_BLOCK(6, WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(1)), + WASM_BRV(0, WASM_I8(11))), + WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(2)), + WASM_BRV(0, WASM_I8(12))), + WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(3)), + WASM_BRV(0, WASM_I8(13))), + WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(4)), + WASM_BRV(0, WASM_I8(14))), + WASM_IF(WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(5)), + WASM_BRV(0, WASM_I8(15))), + WASM_I8(99))); + CHECK_EQ(99, r.Call(0)); + CHECK_EQ(11, r.Call(1)); + CHECK_EQ(12, r.Call(2)); + CHECK_EQ(13, r.Call(3)); + CHECK_EQ(14, r.Call(4)); + CHECK_EQ(15, r.Call(5)); + CHECK_EQ(99, r.Call(6)); +} + + +TEST(Run_Wasm_ExprBlock_ManualSwitch_brif) { + WasmRunner<int32_t> r(MachineType::Int32()); + BUILD(r, + WASM_BLOCK(6, WASM_BRV_IF(0, WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(1)), + WASM_I8(11)), + WASM_BRV_IF(0, WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(2)), + WASM_I8(12)), + WASM_BRV_IF(0, WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(3)), + WASM_I8(13)), + WASM_BRV_IF(0, WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(4)), + WASM_I8(14)), + WASM_BRV_IF(0, WASM_I32_EQ(WASM_GET_LOCAL(0), WASM_I8(5)), + WASM_I8(15)), + WASM_I8(99))); + CHECK_EQ(99, r.Call(0)); + CHECK_EQ(11, r.Call(1)); + CHECK_EQ(12, r.Call(2)); + CHECK_EQ(13, r.Call(3)); + CHECK_EQ(14, r.Call(4)); + CHECK_EQ(15, r.Call(5)); + CHECK_EQ(99, r.Call(6)); +} + + +TEST(Run_Wasm_nested_ifs) { + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + + BUILD(r, WASM_IF_ELSE( + WASM_GET_LOCAL(0), + WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_I8(11), WASM_I8(12)), + WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_I8(13), WASM_I8(14)))); + + + CHECK_EQ(11, r.Call(1, 1)); + CHECK_EQ(12, r.Call(1, 0)); + CHECK_EQ(13, r.Call(0, 1)); + CHECK_EQ(14, r.Call(0, 0)); +} + + +TEST(Run_Wasm_ExprBlock_if) { + WasmRunner<int32_t> r(MachineType::Int32()); + + BUILD(r, + WASM_BLOCK(1, WASM_IF_ELSE(WASM_GET_LOCAL(0), WASM_BRV(0, WASM_I8(11)), + WASM_BRV(0, WASM_I8(14))))); + + CHECK_EQ(11, r.Call(1)); + CHECK_EQ(14, r.Call(0)); +} + + +TEST(Run_Wasm_ExprBlock_nested_ifs) { + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + + BUILD(r, WASM_BLOCK( + 1, WASM_IF_ELSE( + WASM_GET_LOCAL(0), + WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(11)), + WASM_BRV(0, WASM_I8(12))), + WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(13)), + WASM_BRV(0, WASM_I8(14)))))); + + + CHECK_EQ(11, r.Call(1, 1)); + CHECK_EQ(12, r.Call(1, 0)); + CHECK_EQ(13, r.Call(0, 1)); + CHECK_EQ(14, r.Call(0, 0)); +} + + +TEST(Run_Wasm_ExprLoop_nested_ifs) { + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); + + BUILD(r, WASM_LOOP( + 1, WASM_IF_ELSE( + WASM_GET_LOCAL(0), + WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(11)), + WASM_BRV(1, WASM_I8(12))), + WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(13)), + WASM_BRV(1, WASM_I8(14)))))); + + + CHECK_EQ(11, r.Call(1, 1)); + CHECK_EQ(12, r.Call(1, 0)); + CHECK_EQ(13, r.Call(0, 1)); + CHECK_EQ(14, r.Call(0, 0)); +} + + +#if WASM_64 +TEST(Run_Wasm_LoadStoreI64_sx) { + byte loads[] = {kExprI64LoadMem8S, kExprI64LoadMem16S, kExprI64LoadMem32S, + kExprI64LoadMem}; + + for (size_t m = 0; m < arraysize(loads); m++) { + WasmRunner<int64_t> r; + TestingModule module; + byte* memory = module.AddMemoryElems<byte>(16); + r.env()->module = &module; + + byte code[] = {kExprI64StoreMem, 0, kExprI8Const, 8, + loads[m], 0, kExprI8Const, 0}; + + r.Build(code, code + arraysize(code)); + + // Try a bunch of different negative values. + for (int i = -1; i >= -128; i -= 11) { + int size = 1 << m; + module.BlankMemory(); + memory[size - 1] = static_cast<byte>(i); // set the high order byte. + + int64_t expected = static_cast<int64_t>(i) << ((size - 1) * 8); + + CHECK_EQ(expected, r.Call()); + CHECK_EQ(static_cast<byte>(i), memory[8 + size - 1]); + for (int j = size; j < 8; j++) { + CHECK_EQ(255, memory[8 + j]); + } + } + } +} + + +#endif + + +TEST(Run_Wasm_SimpleCallIndirect) { + Isolate* isolate = CcTest::InitIsolateOnce(); + + WasmRunner<int32_t> r(MachineType::Int32()); + TestSignatures sigs; + TestingModule module; + r.env()->module = &module; + WasmFunctionCompiler t1(sigs.i_ii()); + BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + t1.CompileAndAdd(&module); + + WasmFunctionCompiler t2(sigs.i_ii()); + BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + t2.CompileAndAdd(&module); + + // Signature table. + module.AddSignature(sigs.f_ff()); + module.AddSignature(sigs.i_ii()); + module.AddSignature(sigs.d_dd()); + + // Function table. + int table_size = 2; + module.module->function_table = new std::vector<uint16_t>; + module.module->function_table->push_back(0); + module.module->function_table->push_back(1); + + // Function table. + Handle<FixedArray> fixed = isolate->factory()->NewFixedArray(2 * table_size); + fixed->set(0, Smi::FromInt(1)); + fixed->set(1, Smi::FromInt(1)); + fixed->set(2, *module.function_code->at(0)); + fixed->set(3, *module.function_code->at(1)); + module.function_table = fixed; + + // Builder the caller function. + BUILD(r, WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22))); + + CHECK_EQ(88, r.Call(0)); + CHECK_EQ(44, r.Call(1)); + CHECK_TRAP(r.Call(2)); +} + + +TEST(Run_Wasm_MultipleCallIndirect) { + Isolate* isolate = CcTest::InitIsolateOnce(); + + WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32(), + MachineType::Int32()); + TestSignatures sigs; + TestingModule module; + r.env()->module = &module; + WasmFunctionCompiler t1(sigs.i_ii()); + BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + t1.CompileAndAdd(&module); + + WasmFunctionCompiler t2(sigs.i_ii()); + BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + t2.CompileAndAdd(&module); + + // Signature table. + module.AddSignature(sigs.f_ff()); + module.AddSignature(sigs.i_ii()); + module.AddSignature(sigs.d_dd()); + + // Function table. + int table_size = 2; + module.module->function_table = new std::vector<uint16_t>; + module.module->function_table->push_back(0); + module.module->function_table->push_back(1); + + // Function table. + Handle<FixedArray> fixed = isolate->factory()->NewFixedArray(2 * table_size); + fixed->set(0, Smi::FromInt(1)); + fixed->set(1, Smi::FromInt(1)); + fixed->set(2, *module.function_code->at(0)); + fixed->set(3, *module.function_code->at(1)); + module.function_table = fixed; + + // Builder the caller function. + BUILD(r, + WASM_I32_ADD(WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), + WASM_GET_LOCAL(2)), + WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(1), WASM_GET_LOCAL(2), + WASM_GET_LOCAL(0)))); + + CHECK_EQ(5, r.Call(0, 1, 2)); + CHECK_EQ(19, r.Call(0, 1, 9)); + CHECK_EQ(1, r.Call(1, 0, 2)); + CHECK_EQ(1, r.Call(1, 0, 9)); + + CHECK_TRAP(r.Call(0, 2, 1)); + CHECK_TRAP(r.Call(1, 2, 0)); + CHECK_TRAP(r.Call(2, 0, 1)); + CHECK_TRAP(r.Call(2, 1, 0)); +} + + +// TODO(titzer): Fix for nosee4 and re-enable. +#if 0 + +TEST(Run_Wasm_F32Floor) { + WasmRunner<float> r(MachineType::Float32()); + BUILD(r, WASM_F32_FLOOR(WASM_GET_LOCAL(0))); + + FOR_FLOAT32_INPUTS(i) { CheckFloatEq(floor(*i), r.Call(*i)); } +} + + +TEST(Run_Wasm_F32Ceil) { + WasmRunner<float> r(MachineType::Float32()); + BUILD(r, WASM_F32_CEIL(WASM_GET_LOCAL(0))); + + FOR_FLOAT32_INPUTS(i) { CheckFloatEq(ceil(*i), r.Call(*i)); } +} + + +TEST(Run_Wasm_F32Trunc) { + WasmRunner<float> r(MachineType::Float32()); + BUILD(r, WASM_F32_TRUNC(WASM_GET_LOCAL(0))); + + FOR_FLOAT32_INPUTS(i) { CheckFloatEq(trunc(*i), r.Call(*i)); } +} + + +TEST(Run_Wasm_F32NearestInt) { + WasmRunner<float> r(MachineType::Float32()); + BUILD(r, WASM_F32_NEARESTINT(WASM_GET_LOCAL(0))); + + FOR_FLOAT32_INPUTS(i) { CheckFloatEq(nearbyint(*i), r.Call(*i)); } +} + + +TEST(Run_Wasm_F64Floor) { + WasmRunner<double> r(MachineType::Float64()); + BUILD(r, WASM_F64_FLOOR(WASM_GET_LOCAL(0))); + + FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(floor(*i), r.Call(*i)); } +} + + +TEST(Run_Wasm_F64Ceil) { + WasmRunner<double> r(MachineType::Float64()); + BUILD(r, WASM_F64_CEIL(WASM_GET_LOCAL(0))); + + FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(ceil(*i), r.Call(*i)); } +} + + +TEST(Run_Wasm_F64Trunc) { + WasmRunner<double> r(MachineType::Float64()); + BUILD(r, WASM_F64_TRUNC(WASM_GET_LOCAL(0))); + + FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(trunc(*i), r.Call(*i)); } +} + + +TEST(Run_Wasm_F64NearestInt) { + WasmRunner<double> r(MachineType::Float64()); + BUILD(r, WASM_F64_NEARESTINT(WASM_GET_LOCAL(0))); + + FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(nearbyint(*i), r.Call(*i)); } +} + +#endif + + +TEST(Run_Wasm_F32Min) { + WasmRunner<float> r(MachineType::Float32(), MachineType::Float32()); + BUILD(r, WASM_F32_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + + FOR_FLOAT32_INPUTS(i) { + FOR_FLOAT32_INPUTS(j) { + float expected; + if (*i < *j) { + expected = *i; + } else if (*j < *i) { + expected = *j; + } else if (*i != *i) { + // If *i or *j is NaN, then the result is NaN. + expected = *i; + } else { + expected = *j; + } + + CheckFloatEq(expected, r.Call(*i, *j)); + } + } +} + + +TEST(Run_Wasm_F64Min) { + WasmRunner<double> r(MachineType::Float64(), MachineType::Float64()); + BUILD(r, WASM_F64_MIN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + + FOR_FLOAT64_INPUTS(i) { + FOR_FLOAT64_INPUTS(j) { + double expected; + if (*i < *j) { + expected = *i; + } else if (*j < *i) { + expected = *j; + } else if (*i != *i) { + // If *i or *j is NaN, then the result is NaN. + expected = *i; + } else { + expected = *j; + } + + CheckDoubleEq(expected, r.Call(*i, *j)); + } + } +} + + +TEST(Run_Wasm_F32Max) { + WasmRunner<float> r(MachineType::Float32(), MachineType::Float32()); + BUILD(r, WASM_F32_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + + FOR_FLOAT32_INPUTS(i) { + FOR_FLOAT32_INPUTS(j) { + float expected; + if (*i > *j) { + expected = *i; + } else if (*j > *i) { + expected = *j; + } else if (*i != *i) { + // If *i or *j is NaN, then the result is NaN. + expected = *i; + } else { + expected = *j; + } + + CheckFloatEq(expected, r.Call(*i, *j)); + } + } +} + + +TEST(Run_Wasm_F64Max) { + WasmRunner<double> r(MachineType::Float64(), MachineType::Float64()); + BUILD(r, WASM_F64_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + + FOR_FLOAT64_INPUTS(i) { + FOR_FLOAT64_INPUTS(j) { + double expected; + if (*i > *j) { + expected = *i; + } else if (*j > *i) { + expected = *j; + } else if (*i != *i) { + // If *i or *j is NaN, then the result is NaN. + expected = *i; + } else { + expected = *j; + } + + CheckDoubleEq(expected, r.Call(*i, *j)); + } + } +} + + +#if WASM_64 +TEST(Run_Wasm_F32SConvertI64) { + WasmRunner<float> r(MachineType::Int64()); + BUILD(r, WASM_F32_SCONVERT_I64(WASM_GET_LOCAL(0))); + FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), r.Call(*i)); } +} + + +#if !defined(_WIN64) +// TODO(ahaas): Fix this failure. +TEST(Run_Wasm_F32UConvertI64) { + WasmRunner<float> r(MachineType::Uint64()); + BUILD(r, WASM_F32_UCONVERT_I64(WASM_GET_LOCAL(0))); + FOR_UINT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), r.Call(*i)); } +} +#endif + + +TEST(Run_Wasm_F64SConvertI64) { + WasmRunner<double> r(MachineType::Int64()); + BUILD(r, WASM_F64_SCONVERT_I64(WASM_GET_LOCAL(0))); + FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), r.Call(*i)); } +} + + +#if !defined(_WIN64) +// TODO(ahaas): Fix this failure. +TEST(Run_Wasm_F64UConvertI64) { + WasmRunner<double> r(MachineType::Uint64()); + BUILD(r, WASM_F64_UCONVERT_I64(WASM_GET_LOCAL(0))); + FOR_UINT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), r.Call(*i)); } +} +#endif + + +TEST(Run_Wasm_I64SConvertF32) { + WasmRunner<int64_t> r(MachineType::Float32()); + BUILD(r, WASM_I64_SCONVERT_F32(WASM_GET_LOCAL(0))); + + FOR_FLOAT32_INPUTS(i) { + if (*i < static_cast<float>(INT64_MAX) && + *i >= static_cast<float>(INT64_MIN)) { + CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); + } else { + CHECK_TRAP64(r.Call(*i)); + } + } +} + + +TEST(Run_Wasm_I64SConvertF64) { + WasmRunner<int64_t> r(MachineType::Float64()); + BUILD(r, WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0))); + + FOR_FLOAT64_INPUTS(i) { + if (*i < static_cast<double>(INT64_MAX) && + *i >= static_cast<double>(INT64_MIN)) { + CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); + } else { + CHECK_TRAP64(r.Call(*i)); + } + } +} + + +TEST(Run_Wasm_I64UConvertF32) { + WasmRunner<uint64_t> r(MachineType::Float32()); + BUILD(r, WASM_I64_UCONVERT_F32(WASM_GET_LOCAL(0))); + + FOR_FLOAT32_INPUTS(i) { + if (*i < static_cast<float>(UINT64_MAX) && *i > -1) { + CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i)); + } else { + CHECK_TRAP64(r.Call(*i)); + } + } +} + + +TEST(Run_Wasm_I64UConvertF64) { + WasmRunner<uint64_t> r(MachineType::Float64()); + BUILD(r, WASM_I64_UCONVERT_F64(WASM_GET_LOCAL(0))); + + FOR_FLOAT64_INPUTS(i) { + if (*i < static_cast<float>(UINT64_MAX) && *i > -1) { + CHECK_EQ(static_cast<uint64_t>(*i), r.Call(*i)); + } else { + CHECK_TRAP64(r.Call(*i)); + } + } +} +#endif + + +// TODO(titzer): Fix and re-enable. +#if 0 +TEST(Run_Wasm_I32SConvertF32) { + WasmRunner<int32_t> r(MachineType::Float32()); + BUILD(r, WASM_I32_SCONVERT_F32(WASM_GET_LOCAL(0))); + + FOR_FLOAT32_INPUTS(i) { + if (*i < static_cast<float>(INT32_MAX) && + *i >= static_cast<float>(INT32_MIN)) { + CHECK_EQ(static_cast<int32_t>(*i), r.Call(*i)); + } else { + CHECK_TRAP32(r.Call(*i)); + } + } +} + + +TEST(Run_Wasm_I32SConvertF64) { + WasmRunner<int32_t> r(MachineType::Float64()); + BUILD(r, WASM_I32_SCONVERT_F64(WASM_GET_LOCAL(0))); + + FOR_FLOAT64_INPUTS(i) { + if (*i < static_cast<double>(INT32_MAX) && + *i >= static_cast<double>(INT32_MIN)) { + CHECK_EQ(static_cast<int64_t>(*i), r.Call(*i)); + } else { + CHECK_TRAP32(r.Call(*i)); + } + } +} + + +TEST(Run_Wasm_I32UConvertF32) { + WasmRunner<uint32_t> r(MachineType::Float32()); + BUILD(r, WASM_I32_UCONVERT_F32(WASM_GET_LOCAL(0))); + + FOR_FLOAT32_INPUTS(i) { + if (*i < static_cast<float>(UINT32_MAX) && *i > -1) { + CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i)); + } else { + CHECK_TRAP32(r.Call(*i)); + } + } +} + + +TEST(Run_Wasm_I32UConvertF64) { + WasmRunner<uint32_t> r(MachineType::Float64()); + BUILD(r, WASM_I32_UCONVERT_F64(WASM_GET_LOCAL(0))); + + FOR_FLOAT64_INPUTS(i) { + if (*i < static_cast<float>(UINT32_MAX) && *i > -1) { + CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i)); + } else { + CHECK_TRAP32(r.Call(*i)); + } + } +} +#endif + + +TEST(Run_Wasm_F64CopySign) { + WasmRunner<double> r(MachineType::Float64(), MachineType::Float64()); + BUILD(r, WASM_F64_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + + FOR_FLOAT64_INPUTS(i) { + FOR_FLOAT64_INPUTS(j) { CheckDoubleEq(copysign(*i, *j), r.Call(*i, *j)); } + } +} + + +// TODO(tizer): Fix on arm and reenable. +#if !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_ARM64 + +TEST(Run_Wasm_F32CopySign) { + WasmRunner<float> r(MachineType::Float32(), MachineType::Float32()); + BUILD(r, WASM_F32_COPYSIGN(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); + + FOR_FLOAT32_INPUTS(i) { + FOR_FLOAT32_INPUTS(j) { CheckFloatEq(copysign(*i, *j), r.Call(*i, *j)); } + } +} + +#endif diff --git a/deps/v8/test/cctest/wasm/test-signatures.h b/deps/v8/test/cctest/wasm/test-signatures.h new file mode 100644 index 0000000000..30ea605386 --- /dev/null +++ b/deps/v8/test/cctest/wasm/test-signatures.h @@ -0,0 +1,111 @@ +// 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 TEST_SIGNATURES_H +#define TEST_SIGNATURES_H + +#include "src/signature.h" +#include "src/wasm/wasm-opcodes.h" + +namespace v8 { +namespace internal { +namespace wasm { + +typedef Signature<LocalType> FunctionSig; + +// A helper class with many useful signatures in order to simplify tests. +class TestSignatures { + public: + TestSignatures() + : sig_i_v(1, 0, kIntTypes4), + sig_i_i(1, 1, kIntTypes4), + sig_i_ii(1, 2, kIntTypes4), + sig_i_iii(1, 3, kIntTypes4), + sig_i_f(1, 1, kIntFloatTypes4), + sig_i_ff(1, 2, kIntFloatTypes4), + sig_i_d(1, 1, kIntDoubleTypes4), + sig_i_dd(1, 2, kIntDoubleTypes4), + sig_l_v(1, 0, kLongTypes4), + sig_l_l(1, 1, kLongTypes4), + sig_l_ll(1, 2, kLongTypes4), + sig_i_ll(1, 2, kIntLongTypes4), + sig_f_ff(1, 2, kFloatTypes4), + sig_d_dd(1, 2, kDoubleTypes4), + sig_v_v(0, 0, kIntTypes4), + sig_v_i(0, 1, kIntTypes4), + sig_v_ii(0, 2, kIntTypes4), + sig_v_iii(0, 3, kIntTypes4) { + // I used C++ and you won't believe what happened next.... + for (int i = 0; i < 4; i++) kIntTypes4[i] = kAstI32; + for (int i = 0; i < 4; i++) kLongTypes4[i] = kAstI64; + for (int i = 0; i < 4; i++) kFloatTypes4[i] = kAstF32; + for (int i = 0; i < 4; i++) kDoubleTypes4[i] = kAstF64; + for (int i = 0; i < 4; i++) kIntLongTypes4[i] = kAstI64; + for (int i = 0; i < 4; i++) kIntFloatTypes4[i] = kAstF32; + for (int i = 0; i < 4; i++) kIntDoubleTypes4[i] = kAstF64; + kIntLongTypes4[0] = kAstI32; + kIntFloatTypes4[0] = kAstI32; + kIntDoubleTypes4[0] = kAstI32; + } + + FunctionSig* i_v() { return &sig_i_v; } + FunctionSig* i_i() { return &sig_i_i; } + FunctionSig* i_ii() { return &sig_i_ii; } + FunctionSig* i_iii() { return &sig_i_iii; } + + FunctionSig* i_f() { return &sig_i_f; } + FunctionSig* i_ff() { return &sig_i_ff; } + FunctionSig* i_d() { return &sig_i_d; } + FunctionSig* i_dd() { return &sig_i_dd; } + + FunctionSig* l_v() { return &sig_l_v; } + FunctionSig* l_l() { return &sig_l_l; } + FunctionSig* l_ll() { return &sig_l_ll; } + FunctionSig* i_ll() { return &sig_i_ll; } + + FunctionSig* f_ff() { return &sig_f_ff; } + FunctionSig* d_dd() { return &sig_d_dd; } + + FunctionSig* v_v() { return &sig_v_v; } + FunctionSig* v_i() { return &sig_v_i; } + FunctionSig* v_ii() { return &sig_v_ii; } + FunctionSig* v_iii() { return &sig_v_iii; } + + private: + LocalType kIntTypes4[4]; + LocalType kLongTypes4[4]; + LocalType kFloatTypes4[4]; + LocalType kDoubleTypes4[4]; + LocalType kIntLongTypes4[4]; + LocalType kIntFloatTypes4[4]; + LocalType kIntDoubleTypes4[4]; + + FunctionSig sig_i_v; + FunctionSig sig_i_i; + FunctionSig sig_i_ii; + FunctionSig sig_i_iii; + + FunctionSig sig_i_f; + FunctionSig sig_i_ff; + FunctionSig sig_i_d; + FunctionSig sig_i_dd; + + FunctionSig sig_l_v; + FunctionSig sig_l_l; + FunctionSig sig_l_ll; + FunctionSig sig_i_ll; + + FunctionSig sig_f_ff; + FunctionSig sig_d_dd; + + FunctionSig sig_v_v; + FunctionSig sig_v_i; + FunctionSig sig_v_ii; + FunctionSig sig_v_iii; +}; +} // namespace wasm +} // namespace internal +} // namespace v8 + +#endif // TEST_SIGNATURES_H diff --git a/deps/v8/test/cctest/wasm/wasm-run-utils.h b/deps/v8/test/cctest/wasm/wasm-run-utils.h new file mode 100644 index 0000000000..cc23b46b73 --- /dev/null +++ b/deps/v8/test/cctest/wasm/wasm-run-utils.h @@ -0,0 +1,391 @@ +// Copyright 2016 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 WASM_RUN_UTILS_H +#define WASM_RUN_UTILS_H + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "src/base/utils/random-number-generator.h" + +#include "src/compiler/graph-visualizer.h" +#include "src/compiler/js-graph.h" +#include "src/compiler/wasm-compiler.h" + +#include "src/wasm/ast-decoder.h" +#include "src/wasm/wasm-js.h" +#include "src/wasm/wasm-module.h" +#include "src/wasm/wasm-opcodes.h" + +#include "test/cctest/cctest.h" +#include "test/cctest/compiler/codegen-tester.h" +#include "test/cctest/compiler/graph-builder-tester.h" + +// TODO(titzer): pull WASM_64 up to a common header. +#if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64 +#define WASM_64 1 +#else +#define WASM_64 0 +#endif + +// TODO(titzer): check traps more robustly in tests. +// Currently, in tests, we just return 0xdeadbeef from the function in which +// the trap occurs if the runtime context is not available to throw a JavaScript +// exception. +#define CHECK_TRAP32(x) \ + CHECK_EQ(0xdeadbeef, (bit_cast<uint32_t>(x)) & 0xFFFFFFFF) +#define CHECK_TRAP64(x) \ + CHECK_EQ(0xdeadbeefdeadbeef, (bit_cast<uint64_t>(x)) & 0xFFFFFFFFFFFFFFFF) +#define CHECK_TRAP(x) CHECK_TRAP32(x) + +namespace { +using namespace v8::base; +using namespace v8::internal; +using namespace v8::internal::compiler; +using namespace v8::internal::wasm; + +inline void init_env(FunctionEnv* env, FunctionSig* sig) { + env->module = nullptr; + env->sig = sig; + env->local_int32_count = 0; + env->local_int64_count = 0; + env->local_float32_count = 0; + env->local_float64_count = 0; + env->SumLocals(); +} + +const uint32_t kMaxGlobalsSize = 128; + +// A helper for module environments that adds the ability to allocate memory +// and global variables. +class TestingModule : public ModuleEnv { + public: + TestingModule() : mem_size(0), global_offset(0) { + globals_area = 0; + mem_start = 0; + mem_end = 0; + module = nullptr; + linker = nullptr; + function_code = nullptr; + asm_js = false; + memset(global_data, 0, sizeof(global_data)); + } + + ~TestingModule() { + if (mem_start) { + free(raw_mem_start<byte>()); + } + if (function_code) delete function_code; + if (module) delete module; + } + + byte* AddMemory(size_t size) { + CHECK_EQ(0, mem_start); + CHECK_EQ(0, mem_size); + mem_start = reinterpret_cast<uintptr_t>(malloc(size)); + CHECK(mem_start); + byte* raw = raw_mem_start<byte>(); + memset(raw, 0, size); + mem_end = mem_start + size; + mem_size = size; + return raw_mem_start<byte>(); + } + + template <typename T> + T* AddMemoryElems(size_t count) { + AddMemory(count * sizeof(T)); + return raw_mem_start<T>(); + } + + template <typename T> + T* AddGlobal(MachineType mem_type) { + WasmGlobal* global = AddGlobal(mem_type); + return reinterpret_cast<T*>(globals_area + global->offset); + } + + byte AddSignature(FunctionSig* sig) { + AllocModule(); + if (!module->signatures) { + module->signatures = new std::vector<FunctionSig*>(); + } + module->signatures->push_back(sig); + size_t size = module->signatures->size(); + CHECK(size < 127); + return static_cast<byte>(size - 1); + } + + template <typename T> + T* raw_mem_start() { + DCHECK(mem_start); + return reinterpret_cast<T*>(mem_start); + } + + template <typename T> + T* raw_mem_end() { + DCHECK(mem_end); + return reinterpret_cast<T*>(mem_end); + } + + template <typename T> + T raw_mem_at(int i) { + DCHECK(mem_start); + return reinterpret_cast<T*>(mem_start)[i]; + } + + template <typename T> + T raw_val_at(int i) { + T val; + memcpy(&val, reinterpret_cast<void*>(mem_start + i), sizeof(T)); + return val; + } + + // Zero-initialize the memory. + void BlankMemory() { + byte* raw = raw_mem_start<byte>(); + memset(raw, 0, mem_size); + } + + // Pseudo-randomly intialize the memory. + void RandomizeMemory(unsigned int seed = 88) { + byte* raw = raw_mem_start<byte>(); + byte* end = raw_mem_end<byte>(); + v8::base::RandomNumberGenerator rng; + rng.SetSeed(seed); + rng.NextBytes(raw, end - raw); + } + + WasmFunction* AddFunction(FunctionSig* sig, Handle<Code> code) { + AllocModule(); + if (module->functions == nullptr) { + module->functions = new std::vector<WasmFunction>(); + function_code = new std::vector<Handle<Code>>(); + } + module->functions->push_back({sig, 0, 0, 0, 0, 0, 0, 0, false, false}); + function_code->push_back(code); + return &module->functions->back(); + } + + private: + size_t mem_size; + uint32_t global_offset; + byte global_data[kMaxGlobalsSize]; + + WasmGlobal* AddGlobal(MachineType mem_type) { + AllocModule(); + if (globals_area == 0) { + globals_area = reinterpret_cast<uintptr_t>(global_data); + module->globals = new std::vector<WasmGlobal>(); + } + byte size = WasmOpcodes::MemSize(mem_type); + global_offset = (global_offset + size - 1) & ~(size - 1); // align + module->globals->push_back({0, mem_type, global_offset, false}); + global_offset += size; + // limit number of globals. + CHECK_LT(global_offset, kMaxGlobalsSize); + return &module->globals->back(); + } + void AllocModule() { + if (module == nullptr) { + module = new WasmModule(); + module->shared_isolate = CcTest::InitIsolateOnce(); + module->globals = nullptr; + module->functions = nullptr; + module->data_segments = nullptr; + } + } +}; + + +inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, FunctionEnv* env, + const byte* start, const byte* end) { + compiler::WasmGraphBuilder builder(zone, jsgraph, env->sig); + TreeResult result = BuildTFGraph(&builder, env, start, end); + if (result.failed()) { + ptrdiff_t pc = result.error_pc - result.start; + ptrdiff_t pt = result.error_pt - result.start; + std::ostringstream str; + str << "Verification failed: " << result.error_code << " pc = +" << pc; + if (result.error_pt) str << ", pt = +" << pt; + str << ", msg = " << result.error_msg.get(); + FATAL(str.str().c_str()); + } + if (FLAG_trace_turbo_graph) { + OFStream os(stdout); + os << AsRPO(*jsgraph->graph()); + } +} + + +// A helper for compiling functions that are only internally callable WASM code. +class WasmFunctionCompiler : public HandleAndZoneScope, + private GraphAndBuilders { + public: + explicit WasmFunctionCompiler(FunctionSig* sig, ModuleEnv* module = nullptr) + : GraphAndBuilders(main_zone()), + jsgraph(this->isolate(), this->graph(), this->common(), nullptr, + nullptr, this->machine()), + descriptor_(nullptr) { + init_env(&env, sig); + env.module = module; + } + + JSGraph jsgraph; + FunctionEnv env; + // The call descriptor is initialized when the function is compiled. + CallDescriptor* descriptor_; + + Isolate* isolate() { return main_isolate(); } + Graph* graph() const { return main_graph_; } + Zone* zone() const { return graph()->zone(); } + CommonOperatorBuilder* common() { return &main_common_; } + MachineOperatorBuilder* machine() { return &main_machine_; } + CallDescriptor* descriptor() { return descriptor_; } + + void Build(const byte* start, const byte* end) { + TestBuildingGraph(main_zone(), &jsgraph, &env, start, end); + } + + byte AllocateLocal(LocalType type) { + int result = static_cast<int>(env.total_locals); + env.AddLocals(type, 1); + byte b = static_cast<byte>(result); + CHECK_EQ(result, b); + return b; + } + + Handle<Code> Compile(ModuleEnv* module) { + descriptor_ = module->GetWasmCallDescriptor(this->zone(), env.sig); + CompilationInfo info("wasm compile", this->isolate(), this->zone()); + Handle<Code> result = + Pipeline::GenerateCodeForTesting(&info, descriptor_, this->graph()); +#ifdef ENABLE_DISASSEMBLER + if (!result.is_null() && FLAG_print_opt_code) { + OFStream os(stdout); + result->Disassemble("wasm code", os); + } +#endif + + return result; + } + + uint32_t CompileAndAdd(TestingModule* module) { + uint32_t index = 0; + if (module->module && module->module->functions) { + index = static_cast<uint32_t>(module->module->functions->size()); + } + module->AddFunction(env.sig, Compile(module)); + return index; + } +}; + + +// A helper class to build graphs from Wasm bytecode, generate machine +// code, and run that code. +template <typename ReturnType> +class WasmRunner { + public: + WasmRunner(MachineType p0 = MachineType::None(), + MachineType p1 = MachineType::None(), + MachineType p2 = MachineType::None(), + MachineType p3 = MachineType::None()) + : signature_(MachineTypeForC<ReturnType>() == MachineType::None() ? 0 : 1, + GetParameterCount(p0, p1, p2, p3), storage_), + compiler_(&signature_), + call_wrapper_(p0, p1, p2, p3), + compilation_done_(false) { + int index = 0; + MachineType ret = MachineTypeForC<ReturnType>(); + if (ret != MachineType::None()) { + storage_[index++] = WasmOpcodes::LocalTypeFor(ret); + } + if (p0 != MachineType::None()) + storage_[index++] = WasmOpcodes::LocalTypeFor(p0); + if (p1 != MachineType::None()) + storage_[index++] = WasmOpcodes::LocalTypeFor(p1); + if (p2 != MachineType::None()) + storage_[index++] = WasmOpcodes::LocalTypeFor(p2); + if (p3 != MachineType::None()) + storage_[index++] = WasmOpcodes::LocalTypeFor(p3); + } + + + FunctionEnv* env() { return &compiler_.env; } + + + // Builds a graph from the given Wasm code, and generates the machine + // code and call wrapper for that graph. This method must not be called + // more than once. + void Build(const byte* start, const byte* end) { + DCHECK(!compilation_done_); + compilation_done_ = true; + // Build the TF graph. + compiler_.Build(start, end); + // Generate code. + Handle<Code> code = compiler_.Compile(env()->module); + + // Construct the call wrapper. + Node* inputs[5]; + int input_count = 0; + inputs[input_count++] = call_wrapper_.HeapConstant(code); + for (size_t i = 0; i < signature_.parameter_count(); i++) { + inputs[input_count++] = call_wrapper_.Parameter(i); + } + + call_wrapper_.Return(call_wrapper_.AddNode( + call_wrapper_.common()->Call(compiler_.descriptor()), input_count, + inputs)); + } + + ReturnType Call() { return call_wrapper_.Call(); } + + template <typename P0> + ReturnType Call(P0 p0) { + return call_wrapper_.Call(p0); + } + + template <typename P0, typename P1> + ReturnType Call(P0 p0, P1 p1) { + return call_wrapper_.Call(p0, p1); + } + + template <typename P0, typename P1, typename P2> + ReturnType Call(P0 p0, P1 p1, P2 p2) { + return call_wrapper_.Call(p0, p1, p2); + } + + template <typename P0, typename P1, typename P2, typename P3> + ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) { + return call_wrapper_.Call(p0, p1, p2, p3); + } + + byte AllocateLocal(LocalType type) { + int result = static_cast<int>(env()->total_locals); + env()->AddLocals(type, 1); + byte b = static_cast<byte>(result); + CHECK_EQ(result, b); + return b; + } + + private: + LocalType storage_[5]; + FunctionSig signature_; + WasmFunctionCompiler compiler_; + BufferedRawMachineAssemblerTester<ReturnType> call_wrapper_; + bool compilation_done_; + + static size_t GetParameterCount(MachineType p0, MachineType p1, + MachineType p2, MachineType p3) { + if (p0 == MachineType::None()) return 0; + if (p1 == MachineType::None()) return 1; + if (p2 == MachineType::None()) return 2; + if (p3 == MachineType::None()) return 3; + return 4; + } +}; + +} // namespace + +#endif |