diff --git a/deps/chakrashim/include/v8-version.h b/deps/chakrashim/include/v8-version.h index 6cc98294ec5..ee6ccec7cec 100644 --- a/deps/chakrashim/include/v8-version.h +++ b/deps/chakrashim/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 6 #define V8_MINOR_VERSION 5 #define V8_BUILD_NUMBER 254 -#define V8_PATCH_LEVEL 31 +#define V8_PATCH_LEVEL 38 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS index b2b01df8882..dfd3eef878c 100644 --- a/deps/v8/AUTHORS +++ b/deps/v8/AUTHORS @@ -136,7 +136,6 @@ Sanjoy Das Seo Sanghyeon Stefan Penner Sylvestre Ledru -Taketoshi Aono Tiancheng "Timothy" Gu Tobias Burnus Victor Costan diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index 6cc98294ec5..ee6ccec7cec 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 6 #define V8_MINOR_VERSION 5 #define V8_BUILD_NUMBER 254 -#define V8_PATCH_LEVEL 31 +#define V8_PATCH_LEVEL 38 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc index 399b705f008..2bc833fe296 100644 --- a/deps/v8/src/bootstrapper.cc +++ b/deps/v8/src/bootstrapper.cc @@ -1508,9 +1508,9 @@ void Genesis::InitializeGlobal(Handle global_object, object_function, "keys", Builtins::kObjectKeys, 1, true); native_context()->set_object_keys(*object_keys); SimpleInstallFunction(object_function, factory->entries_string(), - Builtins::kObjectEntries, 1, true); + Builtins::kObjectEntries, 1, false); SimpleInstallFunction(object_function, factory->values_string(), - Builtins::kObjectValues, 1, true); + Builtins::kObjectValues, 1, false); SimpleInstallFunction(isolate->initial_object_prototype(), "__defineGetter__", Builtins::kObjectDefineGetter, 2, diff --git a/deps/v8/src/builtins/builtins-definitions.h b/deps/v8/src/builtins/builtins-definitions.h index 0ffd15df7c0..a4a0bb9e2cb 100644 --- a/deps/v8/src/builtins/builtins-definitions.h +++ b/deps/v8/src/builtins/builtins-definitions.h @@ -755,7 +755,7 @@ namespace internal { CPP(ObjectDefineProperties) \ CPP(ObjectDefineProperty) \ CPP(ObjectDefineSetter) \ - TFJ(ObjectEntries, 1, kObject) \ + CPP(ObjectEntries) \ CPP(ObjectFreeze) \ TFJ(ObjectGetOwnPropertyDescriptor, \ SharedFunctionInfo::kDontAdaptArgumentsSentinel) \ @@ -785,7 +785,7 @@ namespace internal { /* ES #sec-object.prototype.tolocalestring */ \ TFJ(ObjectPrototypeToLocaleString, 0) \ CPP(ObjectSeal) \ - TFJ(ObjectValues, 1, kObject) \ + CPP(ObjectValues) \ \ /* instanceof */ \ TFC(OrdinaryHasInstance, Compare, 1) \ diff --git a/deps/v8/src/builtins/builtins-object-gen.cc b/deps/v8/src/builtins/builtins-object-gen.cc index 9e344820dcc..4cd012e6f01 100644 --- a/deps/v8/src/builtins/builtins-object-gen.cc +++ b/deps/v8/src/builtins/builtins-object-gen.cc @@ -16,8 +16,6 @@ namespace internal { // ES6 section 19.1 Object Objects typedef compiler::Node Node; -template -using TNode = CodeStubAssembler::TNode; class ObjectBuiltinsAssembler : public CodeStubAssembler { public: @@ -36,46 +34,6 @@ class ObjectBuiltinsAssembler : public CodeStubAssembler { Node* ConstructDataDescriptor(Node* context, Node* value, Node* writable, Node* enumerable, Node* configurable); Node* GetAccessorOrUndefined(Node* accessor, Label* if_bailout); - - Node* IsSpecialReceiverMap(SloppyTNode map); -}; - -class ObjectEntriesValuesBuiltinsAssembler : public ObjectBuiltinsAssembler { - public: - explicit ObjectEntriesValuesBuiltinsAssembler( - compiler::CodeAssemblerState* state) - : ObjectBuiltinsAssembler(state) {} - - protected: - enum CollectType { kEntries, kValues }; - - TNode IsStringWrapperElementsKind(TNode map); - - TNode IsPropertyEnumerable(TNode details); - - TNode IsPropertyKindAccessor(TNode kind); - - TNode IsPropertyKindData(TNode kind); - - TNode HasHiddenPrototype(TNode map); - - TNode LoadPropertyKind(TNode details) { - return DecodeWord32(details); - } - - void GetOwnValuesOrEntries(TNode context, TNode maybe_object, - CollectType collect_type); - - void GotoIfMapHasSlowProperties(TNode map, Label* if_slow); - - TNode FastGetOwnValuesOrEntries( - TNode context, TNode object, - Label* if_call_runtime_with_fast_path, Label* if_no_properties, - CollectType collect_type); - - TNode FinalizeValuesOrEntriesJSArray( - TNode context, TNode values_or_entries, - TNode size, TNode array_map, Label* if_empty); }; void ObjectBuiltinsAssembler::ReturnToStringFormat(Node* context, @@ -139,249 +97,6 @@ Node* ObjectBuiltinsAssembler::ConstructDataDescriptor(Node* context, return js_desc; } -Node* ObjectBuiltinsAssembler::IsSpecialReceiverMap(SloppyTNode map) { - CSA_SLOW_ASSERT(this, IsMap(map)); - Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); - uint32_t mask = - Map::HasNamedInterceptorBit::kMask | Map::IsAccessCheckNeededBit::kMask; - USE(mask); - // Interceptors or access checks imply special receiver. - CSA_ASSERT(this, - SelectConstant(IsSetWord32(LoadMapBitField(map), mask), is_special, - Int32Constant(1), MachineRepresentation::kWord32)); - return is_special; -} - -TNode -ObjectEntriesValuesBuiltinsAssembler::IsStringWrapperElementsKind( - TNode map) { - Node* kind = LoadMapElementsKind(map); - return Word32Or( - Word32Equal(kind, Int32Constant(FAST_STRING_WRAPPER_ELEMENTS)), - Word32Equal(kind, Int32Constant(SLOW_STRING_WRAPPER_ELEMENTS))); -} - -TNode ObjectEntriesValuesBuiltinsAssembler::IsPropertyEnumerable( - TNode details) { - TNode attributes = - DecodeWord32(details); - return IsNotSetWord32(attributes, PropertyAttributes::DONT_ENUM); -} - -TNode ObjectEntriesValuesBuiltinsAssembler::IsPropertyKindAccessor( - TNode kind) { - return Word32Equal(kind, Int32Constant(PropertyKind::kAccessor)); -} - -TNode ObjectEntriesValuesBuiltinsAssembler::IsPropertyKindData( - TNode kind) { - return Word32Equal(kind, Int32Constant(PropertyKind::kData)); -} - -TNode ObjectEntriesValuesBuiltinsAssembler::HasHiddenPrototype( - TNode map) { - TNode bit_field3 = LoadMapBitField3(map); - return DecodeWord32(bit_field3); -} - -void ObjectEntriesValuesBuiltinsAssembler::GetOwnValuesOrEntries( - TNode context, TNode maybe_object, - CollectType collect_type) { - TNode object = TNode::UncheckedCast( - CallBuiltin(Builtins::kToObject, context, maybe_object)); - - Label if_call_runtime_with_fast_path(this, Label::kDeferred), - if_call_runtime(this, Label::kDeferred), - if_no_properties(this, Label::kDeferred); - - TNode map = LoadMap(object); - GotoIfNot(IsJSObjectMap(map), &if_call_runtime); - GotoIfMapHasSlowProperties(map, &if_call_runtime); - - TNode elements = LoadElements(object); - // If the object has elements, we treat it as slow case. - // So, we go to runtime call. - GotoIfNot(IsEmptyFixedArray(elements), &if_call_runtime_with_fast_path); - - TNode result = FastGetOwnValuesOrEntries( - context, object, &if_call_runtime_with_fast_path, &if_no_properties, - collect_type); - Return(result); - - BIND(&if_no_properties); - { - Node* native_context = LoadNativeContext(context); - Node* array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context); - Node* empty_array = AllocateJSArray(PACKED_ELEMENTS, array_map, - IntPtrConstant(0), SmiConstant(0)); - Return(empty_array); - } - - BIND(&if_call_runtime_with_fast_path); - { - // In slow case, we simply call runtime. - if (collect_type == CollectType::kEntries) { - Return(CallRuntime(Runtime::kObjectEntries, context, object)); - } else { - DCHECK(collect_type == CollectType::kValues); - Return(CallRuntime(Runtime::kObjectValues, context, object)); - } - } - - BIND(&if_call_runtime); - { - // In slow case, we simply call runtime. - if (collect_type == CollectType::kEntries) { - Return(CallRuntime(Runtime::kObjectEntriesSkipFastPath, context, object)); - } else { - DCHECK(collect_type == CollectType::kValues); - Return(CallRuntime(Runtime::kObjectValuesSkipFastPath, context, object)); - } - } -} - -void ObjectEntriesValuesBuiltinsAssembler::GotoIfMapHasSlowProperties( - TNode map, Label* if_slow) { - GotoIf(IsStringWrapperElementsKind(map), if_slow); - GotoIf(IsSpecialReceiverMap(map), if_slow); - GotoIf(HasHiddenPrototype(map), if_slow); - GotoIf(IsDictionaryMap(map), if_slow); -} - -TNode ObjectEntriesValuesBuiltinsAssembler::FastGetOwnValuesOrEntries( - TNode context, TNode object, - Label* if_call_runtime_with_fast_path, Label* if_no_properties, - CollectType collect_type) { - Node* native_context = LoadNativeContext(context); - TNode array_map = - LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context); - TNode map = LoadMap(object); - TNode bit_field3 = LoadMapBitField3(map); - - Label if_has_enum_cache(this), if_not_has_enum_cache(this), - collect_entries(this); - Node* object_enum_length = - DecodeWordFromWord32(bit_field3); - Node* has_enum_cache = WordNotEqual( - object_enum_length, IntPtrConstant(kInvalidEnumCacheSentinel)); - - // In case, we found enum_cache in object, - // we use it as array_length becuase it has same size for - // Object.(entries/values) result array object length. - // So object_enum_length use less memory space than - // NumberOfOwnDescriptorsBits value. - // And in case, if enum_cache_not_found, - // we call runtime and initialize enum_cache for subsequent call of - // CSA fast path. - Branch(has_enum_cache, &if_has_enum_cache, if_call_runtime_with_fast_path); - - BIND(&if_has_enum_cache); - { - GotoIf(WordEqual(object_enum_length, IntPtrConstant(0)), if_no_properties); - TNode values_or_entries = TNode::UncheckedCast( - AllocateFixedArray(PACKED_ELEMENTS, object_enum_length, - INTPTR_PARAMETERS, kAllowLargeObjectAllocation)); - - // If in case we have enum_cache, - // we can't detect accessor of object until loop through descritpros. - // So if object might have accessor, - // we will remain invalid addresses of FixedArray. - // Because in that case, we need to jump to runtime call. - // So the array filled by the-hole even if enum_cache exists. - FillFixedArrayWithValue(PACKED_ELEMENTS, values_or_entries, - IntPtrConstant(0), object_enum_length, - Heap::kTheHoleValueRootIndex); - - TVARIABLE(IntPtrT, var_result_index, IntPtrConstant(0)); - TVARIABLE(IntPtrT, var_descriptor_index, IntPtrConstant(0)); - Variable* vars[] = {&var_descriptor_index, &var_result_index}; - // Let desc be ? O.[[GetOwnProperty]](key). - TNode descriptors = LoadMapDescriptors(map); - Label loop(this, 2, vars), after_loop(this), loop_condition(this); - Branch(IntPtrEqual(var_descriptor_index, object_enum_length), &after_loop, - &loop); - - // We dont use BuildFastLoop. - // Instead, we use hand-written loop - // because of we need to use 'continue' functionality. - BIND(&loop); - { - // Currently, we will not invoke getters, - // so, map will not be changed. - CSA_ASSERT(this, WordEqual(map, LoadMap(object))); - TNode descriptor_index = TNode::UncheckedCast( - TruncateWordToWord32(var_descriptor_index)); - Node* next_key = DescriptorArrayGetKey(descriptors, descriptor_index); - - // Skip Symbols. - GotoIf(IsSymbol(next_key), &loop_condition); - - TNode details = TNode::UncheckedCast( - DescriptorArrayGetDetails(descriptors, descriptor_index)); - TNode kind = LoadPropertyKind(details); - - // If property is accessor, we escape fast path and call runtime. - GotoIf(IsPropertyKindAccessor(kind), if_call_runtime_with_fast_path); - CSA_ASSERT(this, IsPropertyKindData(kind)); - - // If desc is not undefined and desc.[[Enumerable]] is true, then - GotoIfNot(IsPropertyEnumerable(details), &loop_condition); - - VARIABLE(var_property_value, MachineRepresentation::kTagged, - UndefinedConstant()); - Node* descriptor_name_index = DescriptorNumberToIndex(descriptor_index); - - // Let value be ? Get(O, key). - LoadPropertyFromFastObject(object, map, descriptors, - descriptor_name_index, details, - &var_property_value); - - // If kind is "value", append value to properties. - Node* value = var_property_value.value(); - - if (collect_type == CollectType::kEntries) { - // Let entry be CreateArrayFromList(« key, value »). - Node* array = nullptr; - Node* elements = nullptr; - std::tie(array, elements) = AllocateUninitializedJSArrayWithElements( - PACKED_ELEMENTS, array_map, SmiConstant(2), nullptr, - IntPtrConstant(2)); - StoreFixedArrayElement(elements, 0, next_key, SKIP_WRITE_BARRIER); - StoreFixedArrayElement(elements, 1, value, SKIP_WRITE_BARRIER); - value = array; - } - - StoreFixedArrayElement(values_or_entries, var_result_index, value); - Increment(&var_result_index, 1); - Goto(&loop_condition); - - BIND(&loop_condition); - { - Increment(&var_descriptor_index, 1); - Branch(IntPtrEqual(var_descriptor_index, object_enum_length), - &after_loop, &loop); - } - } - BIND(&after_loop); - return FinalizeValuesOrEntriesJSArray(context, values_or_entries, - var_result_index, array_map, - if_no_properties); - } -} - -TNode -ObjectEntriesValuesBuiltinsAssembler::FinalizeValuesOrEntriesJSArray( - TNode context, TNode result, TNode size, - TNode array_map, Label* if_empty) { - CSA_ASSERT(this, IsJSArrayMap(array_map)); - - GotoIf(IntPtrEqual(size, IntPtrConstant(0)), if_empty); - Node* array = AllocateUninitializedJSArrayWithoutElements( - array_map, SmiTag(size), nullptr); - StoreObjectField(array, JSArray::kElementsOffset, result); - return TNode::UncheckedCast(array); -} - TF_BUILTIN(ObjectPrototypeToLocaleString, CodeStubAssembler) { TNode context = CAST(Parameter(Descriptor::kContext)); TNode receiver = CAST(Parameter(Descriptor::kReceiver)); @@ -551,22 +266,6 @@ TF_BUILTIN(ObjectKeys, ObjectBuiltinsAssembler) { } } -TF_BUILTIN(ObjectValues, ObjectEntriesValuesBuiltinsAssembler) { - TNode object = - TNode::UncheckedCast(Parameter(Descriptor::kObject)); - TNode context = - TNode::UncheckedCast(Parameter(Descriptor::kContext)); - GetOwnValuesOrEntries(context, object, CollectType::kValues); -} - -TF_BUILTIN(ObjectEntries, ObjectEntriesValuesBuiltinsAssembler) { - TNode object = - TNode::UncheckedCast(Parameter(Descriptor::kObject)); - TNode context = - TNode::UncheckedCast(Parameter(Descriptor::kContext)); - GetOwnValuesOrEntries(context, object, CollectType::kEntries); -} - // ES #sec-object.prototype.isprototypeof TF_BUILTIN(ObjectPrototypeIsPrototypeOf, ObjectBuiltinsAssembler) { Node* receiver = Parameter(Descriptor::kReceiver); diff --git a/deps/v8/src/builtins/builtins-object.cc b/deps/v8/src/builtins/builtins-object.cc index 4e353b92600..36f7ebfc0a8 100644 --- a/deps/v8/src/builtins/builtins-object.cc +++ b/deps/v8/src/builtins/builtins-object.cc @@ -395,6 +395,31 @@ BUILTIN(ObjectIsSealed) { return isolate->heap()->ToBoolean(result.FromJust()); } +BUILTIN(ObjectValues) { + HandleScope scope(isolate); + Handle object = args.atOrUndefined(isolate, 1); + Handle receiver; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, + Object::ToObject(isolate, object)); + Handle values; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, values, JSReceiver::GetOwnValues(receiver, ENUMERABLE_STRINGS)); + return *isolate->factory()->NewJSArrayWithElements(values); +} + +BUILTIN(ObjectEntries) { + HandleScope scope(isolate); + Handle object = args.atOrUndefined(isolate, 1); + Handle receiver; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, + Object::ToObject(isolate, object)); + Handle entries; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, entries, + JSReceiver::GetOwnEntries(receiver, ENUMERABLE_STRINGS)); + return *isolate->factory()->NewJSArrayWithElements(entries); +} + BUILTIN(ObjectGetOwnPropertyDescriptors) { HandleScope scope(isolate); Handle object = args.atOrUndefined(isolate, 1); diff --git a/deps/v8/src/code-stub-assembler.cc b/deps/v8/src/code-stub-assembler.cc index f98e7fe5192..2027d208abc 100644 --- a/deps/v8/src/code-stub-assembler.cc +++ b/deps/v8/src/code-stub-assembler.cc @@ -4019,6 +4019,19 @@ Node* CodeStubAssembler::InstanceTypeEqual(Node* instance_type, int type) { return Word32Equal(instance_type, Int32Constant(type)); } +Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { + CSA_SLOW_ASSERT(this, IsMap(map)); + Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); + uint32_t mask = + Map::HasNamedInterceptorBit::kMask | Map::IsAccessCheckNeededBit::kMask; + USE(mask); + // Interceptors or access checks imply special receiver. + CSA_ASSERT(this, + SelectConstant(IsSetWord32(LoadMapBitField(map), mask), is_special, + Int32Constant(1), MachineRepresentation::kWord32)); + return is_special; +} + TNode CodeStubAssembler::IsDictionaryMap(SloppyTNode map) { CSA_SLOW_ASSERT(this, IsMap(map)); Node* bit_field3 = LoadMapBitField3(map); @@ -6369,38 +6382,36 @@ Node* CodeStubAssembler::DescriptorArrayNumberOfEntries(Node* descriptors) { descriptors, IntPtrConstant(DescriptorArray::kDescriptorLengthIndex)); } -Node* CodeStubAssembler::DescriptorNumberToIndex( - SloppyTNode descriptor_number) { - Node* descriptor_size = Int32Constant(DescriptorArray::kEntrySize); - Node* index = Int32Mul(descriptor_number, descriptor_size); - return ChangeInt32ToIntPtr(index); +namespace { + +Node* DescriptorNumberToIndex(CodeStubAssembler* a, Node* descriptor_number) { + Node* descriptor_size = a->Int32Constant(DescriptorArray::kEntrySize); + Node* index = a->Int32Mul(descriptor_number, descriptor_size); + return a->ChangeInt32ToIntPtr(index); } +} // namespace + Node* CodeStubAssembler::DescriptorArrayToKeyIndex(Node* descriptor_number) { return IntPtrAdd(IntPtrConstant(DescriptorArray::ToKeyIndex(0)), - DescriptorNumberToIndex(descriptor_number)); + DescriptorNumberToIndex(this, descriptor_number)); } Node* CodeStubAssembler::DescriptorArrayGetSortedKeyIndex( Node* descriptors, Node* descriptor_number) { - Node* details = DescriptorArrayGetDetails( - TNode::UncheckedCast(descriptors), - TNode::UncheckedCast(descriptor_number)); + const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize; + Node* details = LoadAndUntagToWord32FixedArrayElement( + descriptors, DescriptorNumberToIndex(this, descriptor_number), + details_offset); return DecodeWord32(details); } Node* CodeStubAssembler::DescriptorArrayGetKey(Node* descriptors, Node* descriptor_number) { const int key_offset = DescriptorArray::ToKeyIndex(0) * kPointerSize; - return LoadFixedArrayElement( - descriptors, DescriptorNumberToIndex(descriptor_number), key_offset); -} - -TNode CodeStubAssembler::DescriptorArrayGetDetails( - TNode descriptors, TNode descriptor_number) { - const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize; - return TNode::UncheckedCast(LoadAndUntagToWord32FixedArrayElement( - descriptors, DescriptorNumberToIndex(descriptor_number), details_offset)); + return LoadFixedArrayElement(descriptors, + DescriptorNumberToIndex(this, descriptor_number), + key_offset); } void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name, @@ -6599,22 +6610,12 @@ void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map, Variable* var_value) { DCHECK_EQ(MachineRepresentation::kWord32, var_details->rep()); DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep()); + Comment("[ LoadPropertyFromFastObject"); Node* details = LoadDetailsByKeyIndex(descriptors, name_index); var_details->Bind(details); - LoadPropertyFromFastObject(object, map, descriptors, name_index, details, - var_value); -} - -void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map, - Node* descriptors, - Node* name_index, - Node* details, - Variable* var_value) { - Comment("[ LoadPropertyFromFastObject"); - Node* location = DecodeWord32(details); Label if_in_field(this), if_in_descriptor(this), done(this); diff --git a/deps/v8/src/code-stub-assembler.h b/deps/v8/src/code-stub-assembler.h index 4a72b203a78..0dd7a35c4a0 100644 --- a/deps/v8/src/code-stub-assembler.h +++ b/deps/v8/src/code-stub-assembler.h @@ -1125,6 +1125,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { Node* IsSequentialStringInstanceType(Node* instance_type); Node* IsShortExternalStringInstanceType(Node* instance_type); Node* IsSpecialReceiverInstanceType(Node* instance_type); + Node* IsSpecialReceiverMap(Node* map); Node* IsSpeciesProtectorCellInvalid(); Node* IsStringInstanceType(Node* instance_type); Node* IsString(Node* object); @@ -1583,10 +1584,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { Node* name_index, Variable* var_details, Variable* var_value); - void LoadPropertyFromFastObject(Node* object, Node* map, Node* descriptors, - Node* name_index, Node* details, - Variable* var_value); - void LoadPropertyFromNameDictionary(Node* dictionary, Node* entry, Variable* var_details, Variable* var_value); @@ -1909,15 +1906,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { void DescriptorLookupBinary(Node* unique_name, Node* descriptors, Node* nof, Label* if_found, Variable* var_name_index, Label* if_not_found); - Node* DescriptorNumberToIndex(SloppyTNode descriptor_number); // Implements DescriptorArray::ToKeyIndex. // Returns an untagged IntPtr. Node* DescriptorArrayToKeyIndex(Node* descriptor_number); // Implements DescriptorArray::GetKey. Node* DescriptorArrayGetKey(Node* descriptors, Node* descriptor_number); - // Implements DescriptorArray::GetKey. - TNode DescriptorArrayGetDetails(TNode descriptors, - TNode descriptor_number); Node* CallGetterIfAccessor(Node* value, Node* details, Node* context, Node* receiver, Label* if_bailout, diff --git a/deps/v8/src/debug/debug-evaluate.cc b/deps/v8/src/debug/debug-evaluate.cc index 33bc81e5f74..e5865e639c3 100644 --- a/deps/v8/src/debug/debug-evaluate.cc +++ b/deps/v8/src/debug/debug-evaluate.cc @@ -343,11 +343,7 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) { V(AllocateSeqOneByteString) \ V(AllocateSeqTwoByteString) \ V(ObjectCreate) \ - V(ObjectEntries) \ - V(ObjectEntriesSkipFastPath) \ V(ObjectHasOwnProperty) \ - V(ObjectValues) \ - V(ObjectValuesSkipFastPath) \ V(ArrayIndexOf) \ V(ArrayIncludes_Slow) \ V(ArrayIsArray) \ diff --git a/deps/v8/src/field-index.h b/deps/v8/src/field-index.h index 428ad52cc2d..9e390e3d465 100644 --- a/deps/v8/src/field-index.h +++ b/deps/v8/src/field-index.h @@ -123,7 +123,8 @@ class FieldIndex final { }; // Offset of first inobject property from beginning of object. class FirstInobjectPropertyOffsetBits - : public BitField64 {}; + : public BitField64 {}; class IsHiddenField : public BitField64 {}; STATIC_ASSERT(IsHiddenField::kNext <= 64); diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h index c3841aa63e7..1cbc2ca418e 100644 --- a/deps/v8/src/objects-inl.h +++ b/deps/v8/src/objects-inl.h @@ -2431,6 +2431,7 @@ int ObjectTemplateInfo::embedder_field_count() const { } void ObjectTemplateInfo::set_embedder_field_count(int count) { + DCHECK_LE(count, JSObject::kMaxEmbedderFields); return set_data( Smi::FromInt(EmbedderFieldCount::update(Smi::ToInt(data()), count))); } diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc index f8c55e57a63..af2e3eccb37 100644 --- a/deps/v8/src/objects.cc +++ b/deps/v8/src/objects.cc @@ -8791,10 +8791,9 @@ MUST_USE_RESULT Maybe FastGetOwnValuesOrEntries( MaybeHandle GetOwnValuesOrEntries(Isolate* isolate, Handle object, PropertyFilter filter, - bool try_fast_path, bool get_entries) { Handle values_or_entries; - if (try_fast_path && filter == ENUMERABLE_STRINGS) { + if (filter == ENUMERABLE_STRINGS) { Maybe fast_values_or_entries = FastGetOwnValuesOrEntries( isolate, object, get_entries, &values_or_entries); if (fast_values_or_entries.IsNothing()) return MaybeHandle(); @@ -8847,17 +8846,13 @@ MaybeHandle GetOwnValuesOrEntries(Isolate* isolate, } MaybeHandle JSReceiver::GetOwnValues(Handle object, - PropertyFilter filter, - bool try_fast_path) { - return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, - try_fast_path, false); + PropertyFilter filter) { + return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, false); } MaybeHandle JSReceiver::GetOwnEntries(Handle object, - PropertyFilter filter, - bool try_fast_path) { - return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, - try_fast_path, true); + PropertyFilter filter) { + return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, true); } bool Map::DictionaryElementsInPrototypeChainOnly() { @@ -13783,18 +13778,24 @@ void JSFunction::CalculateInstanceSizeHelper(InstanceType instance_type, int requested_in_object_properties, int* instance_size, int* in_object_properties) { + DCHECK_LE(static_cast(requested_embedder_fields), + JSObject::kMaxEmbedderFields); int header_size = JSObject::GetHeaderSize(instance_type, has_prototype_slot); int max_nof_fields = (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2; CHECK_LE(max_nof_fields, JSObject::kMaxInObjectProperties); - *in_object_properties = Min(requested_in_object_properties, max_nof_fields); - CHECK_LE(requested_embedder_fields, max_nof_fields - *in_object_properties); + CHECK_LE(static_cast(requested_embedder_fields), + static_cast(max_nof_fields)); + *in_object_properties = Min(requested_in_object_properties, + max_nof_fields - requested_embedder_fields); *instance_size = header_size + ((requested_embedder_fields + *in_object_properties) << kPointerSizeLog2); CHECK_EQ(*in_object_properties, ((*instance_size - header_size) >> kPointerSizeLog2) - requested_embedder_fields); + CHECK_LE(static_cast(*instance_size), + static_cast(JSObject::kMaxInstanceSize)); } // static diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h index 93f4a4eb95b..c4e3d972e11 100644 --- a/deps/v8/src/objects.h +++ b/deps/v8/src/objects.h @@ -2182,12 +2182,10 @@ class JSReceiver: public HeapObject { Handle object); MUST_USE_RESULT static MaybeHandle GetOwnValues( - Handle object, PropertyFilter filter, - bool try_fast_path = true); + Handle object, PropertyFilter filter); MUST_USE_RESULT static MaybeHandle GetOwnEntries( - Handle object, PropertyFilter filter, - bool try_fast_path = true); + Handle object, PropertyFilter filter); static const int kHashMask = PropertyArray::HashField::kMask; @@ -2673,6 +2671,11 @@ class JSObject: public JSReceiver { static const int kMaxInObjectProperties = (kMaxInstanceSize - kHeaderSize) >> kPointerSizeLog2; STATIC_ASSERT(kMaxInObjectProperties <= kMaxNumberOfDescriptors); + // TODO(cbruni): Revisit calculation of the max supported embedder fields. + static const int kMaxEmbedderFields = + ((1 << kFirstInobjectPropertyOffsetBitCount) - 1 - kHeaderSize) >> + kPointerSizeLog2; + STATIC_ASSERT(kMaxEmbedderFields <= kMaxInObjectProperties); class BodyDescriptor; // No weak fields. diff --git a/deps/v8/src/profiler/cpu-profiler.cc b/deps/v8/src/profiler/cpu-profiler.cc index ac8f55a89b5..a915ebd5119 100644 --- a/deps/v8/src/profiler/cpu-profiler.cc +++ b/deps/v8/src/profiler/cpu-profiler.cc @@ -165,13 +165,16 @@ void ProfilerEventsProcessor::Run() { if (nextSampleTime > now) { #if V8_OS_WIN - // Do not use Sleep on Windows as it is very imprecise. - // Could be up to 16ms jitter, which is unacceptable for the purpose. - while (base::TimeTicks::HighResolutionNow() < nextSampleTime) { - } -#else - base::OS::Sleep(nextSampleTime - now); + if (nextSampleTime - now < base::TimeDelta::FromMilliseconds(100)) { + // Do not use Sleep on Windows as it is very imprecise, with up to 16ms + // jitter, which is unacceptable for short profile intervals. + while (base::TimeTicks::HighResolutionNow() < nextSampleTime) { + } + } else // NOLINT #endif + { + base::OS::Sleep(nextSampleTime - now); + } } // Schedule next sample. sampler_ is nullptr in tests. diff --git a/deps/v8/src/property-details.h b/deps/v8/src/property-details.h index 34c43047f84..dbd4f93acd2 100644 --- a/deps/v8/src/property-details.h +++ b/deps/v8/src/property-details.h @@ -197,6 +197,7 @@ class Representation { static const int kDescriptorIndexBitCount = 10; +static const int kFirstInobjectPropertyOffsetBitCount = 7; // The maximum number of descriptors we want in a descriptor array. It should // fit in a page and also the following should hold: // kMaxNumberOfDescriptors + kFieldsAdded <= PropertyArray::kMaxLength. diff --git a/deps/v8/src/runtime/runtime-object.cc b/deps/v8/src/runtime/runtime-object.cc index 379472bdbea..057ead94078 100644 --- a/deps/v8/src/runtime/runtime-object.cc +++ b/deps/v8/src/runtime/runtime-object.cc @@ -439,61 +439,6 @@ RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) { return *object; } -RUNTIME_FUNCTION(Runtime_ObjectValues) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - - Handle values; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, values, - JSReceiver::GetOwnValues(receiver, PropertyFilter::ENUMERABLE_STRINGS, - true)); - return *isolate->factory()->NewJSArrayWithElements(values); -} - -RUNTIME_FUNCTION(Runtime_ObjectValuesSkipFastPath) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - - Handle value; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, value, - JSReceiver::GetOwnValues(receiver, PropertyFilter::ENUMERABLE_STRINGS, - false)); - return *isolate->factory()->NewJSArrayWithElements(value); -} - -RUNTIME_FUNCTION(Runtime_ObjectEntries) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - - Handle entries; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, entries, - JSReceiver::GetOwnEntries(receiver, PropertyFilter::ENUMERABLE_STRINGS, - true)); - return *isolate->factory()->NewJSArrayWithElements(entries); -} - -RUNTIME_FUNCTION(Runtime_ObjectEntriesSkipFastPath) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - - Handle entries; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, entries, - JSReceiver::GetOwnEntries(receiver, PropertyFilter::ENUMERABLE_STRINGS, - false)); - return *isolate->factory()->NewJSArrayWithElements(entries); -} RUNTIME_FUNCTION(Runtime_GetProperty) { HandleScope scope(isolate); diff --git a/deps/v8/src/runtime/runtime.h b/deps/v8/src/runtime/runtime.h index 487ee675ad3..d05f4984c6a 100644 --- a/deps/v8/src/runtime/runtime.h +++ b/deps/v8/src/runtime/runtime.h @@ -391,10 +391,6 @@ namespace internal { F(ObjectCreate, 2, 1) \ F(InternalSetPrototype, 2, 1) \ F(OptimizeObjectForAddingMultipleProperties, 2, 1) \ - F(ObjectValues, 1, 1) \ - F(ObjectValuesSkipFastPath, 1, 1) \ - F(ObjectEntries, 1, 1) \ - F(ObjectEntriesSkipFastPath, 1, 1) \ F(GetProperty, 2, 1) \ F(KeyedGetProperty, 2, 1) \ F(AddNamedProperty, 4, 1) \ diff --git a/deps/v8/src/simulator-base.h b/deps/v8/src/simulator-base.h index 27dc87d0503..84c1f2fd5b8 100644 --- a/deps/v8/src/simulator-base.h +++ b/deps/v8/src/simulator-base.h @@ -43,6 +43,26 @@ class SimulatorBase { return ConvertReturn(ret); } + // Convert back integral return types. + template + static typename std::enable_if::value, T>::type + ConvertReturn(intptr_t ret) { + static_assert(sizeof(T) <= sizeof(intptr_t), "type bigger than ptrsize"); + return static_cast(ret); + } + + // Convert back pointer-typed return types. + template + static typename std::enable_if::value, T>::type + ConvertReturn(intptr_t ret) { + return reinterpret_cast(ret); + } + + // Convert back void return type (i.e. no return). + template + static typename std::enable_if::value, T>::type ConvertReturn( + intptr_t ret) {} + private: // Runtime call support. Uses the isolate in a thread-safe way. static void* RedirectExternalReference(Isolate* isolate, @@ -69,26 +89,6 @@ class SimulatorBase { ConvertArg(T arg) { return reinterpret_cast(arg); } - - // Convert back integral return types. - template - static typename std::enable_if::value, T>::type - ConvertReturn(intptr_t ret) { - static_assert(sizeof(T) <= sizeof(intptr_t), "type bigger than ptrsize"); - return static_cast(ret); - } - - // Convert back pointer-typed return types. - template - static typename std::enable_if::value, T>::type - ConvertReturn(intptr_t ret) { - return reinterpret_cast(ret); - } - - // Convert back void return type (i.e. no return). - template - static typename std::enable_if::value, T>::type ConvertReturn( - intptr_t ret) {} }; // When the generated code calls an external reference we need to catch that in diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index 73dc19aa66a..b3937382da0 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -2699,6 +2699,110 @@ THREADED_TEST(InternalFields) { CHECK_EQ(17, obj->GetInternalField(0)->Int32Value(env.local()).FromJust()); } +TEST(InternalFieldsSubclassing) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + for (int nof_embedder_fields = 0; + nof_embedder_fields < i::JSObject::kMaxEmbedderFields; + nof_embedder_fields++) { + Local templ = v8::FunctionTemplate::New(isolate); + Local instance_templ = templ->InstanceTemplate(); + instance_templ->SetInternalFieldCount(nof_embedder_fields); + Local constructor = + templ->GetFunction(env.local()).ToLocalChecked(); + // Check that instances have the correct NOF properties. + Local obj = + constructor->NewInstance(env.local()).ToLocalChecked(); + + i::Handle i_obj = + i::Handle::cast(v8::Utils::OpenHandle(*obj)); + CHECK_EQ(nof_embedder_fields, obj->InternalFieldCount()); + CHECK_EQ(0, i_obj->map()->GetInObjectProperties()); + // Check writing and reading internal fields. + for (int j = 0; j < nof_embedder_fields; j++) { + CHECK(obj->GetInternalField(j)->IsUndefined()); + int value = 17 + j; + obj->SetInternalField(j, v8_num(value)); + } + for (int j = 0; j < nof_embedder_fields; j++) { + int value = 17 + j; + CHECK_EQ(value, + obj->GetInternalField(j)->Int32Value(env.local()).FromJust()); + } + CHECK(env->Global() + ->Set(env.local(), v8_str("BaseClass"), constructor) + .FromJust()); + // Create various levels of subclasses to stress instance size calculation. + const int kMaxNofProperties = + i::JSObject::kMaxInObjectProperties - nof_embedder_fields; + // Select only a few values to speed up the test. + int sizes[] = {0, + 1, + 2, + 3, + 4, + 5, + 6, + kMaxNofProperties / 4, + kMaxNofProperties / 2, + kMaxNofProperties - 2, + kMaxNofProperties - 1, + kMaxNofProperties + 1, + kMaxNofProperties + 2, + kMaxNofProperties * 2, + kMaxNofProperties * 2}; + for (size_t i = 0; i < arraysize(sizes); i++) { + int nof_properties = sizes[i]; + bool in_object_only = nof_properties <= kMaxNofProperties; + std::ostringstream src; + // Assembler source string for a subclass with {nof_properties} + // in-object properties. + src << "(function() {\n" + << " class SubClass extends BaseClass {\n" + << " constructor() {\n" + << " super();\n"; + // Set {nof_properties} instance properties in the constructor. + for (int j = 0; j < nof_properties; j++) { + src << " this.property" << j << " = " << j << ";\n"; + } + src << " }\n" + << " };\n" + << " let instance;\n" + << " for (let i = 0; i < 3; i++) {\n" + << " instance = new SubClass();\n" + << " }" + << " return instance;\n" + << "})();"; + Local value = CompileRun(src.str().c_str()).As(); + + i::Handle i_value = + i::Handle::cast(v8::Utils::OpenHandle(*value)); +#ifdef VERIFY_HEAP + i_value->HeapObjectVerify(); + i_value->map()->HeapObjectVerify(); + i_value->map()->FindRootMap()->HeapObjectVerify(); +#endif + CHECK_EQ(nof_embedder_fields, value->InternalFieldCount()); + if (in_object_only) { + CHECK_LE(nof_properties, i_value->map()->GetInObjectProperties()); + } else { + CHECK_LE(kMaxNofProperties, i_value->map()->GetInObjectProperties()); + } + + // Make Sure we get the precise property count. + i_value->map()->FindRootMap()->CompleteInobjectSlackTracking(); + // TODO(cbruni): fix accounting to make this condition true. + // CHECK_EQ(0, i_value->map()->UnusedPropertyFields()); + if (in_object_only) { + CHECK_EQ(nof_properties, i_value->map()->GetInObjectProperties()); + } else { + CHECK_LE(kMaxNofProperties, i_value->map()->GetInObjectProperties()); + } + } + } +} + THREADED_TEST(InternalFieldsOfRegularObjects) { LocalContext env; v8::Isolate* isolate = env->GetIsolate(); diff --git a/doc/api/tls.md b/doc/api/tls.md index d3f3fdadff1..cff01013c12 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -1127,9 +1127,9 @@ changes: * `clientCertEngine` {string} Optional name of an OpenSSL engine which can provide the client certificate. * `handshakeTimeout` {number} Abort the connection if the SSL/TLS handshake - does not finish in the specified number of milliseconds. Defaults to `120` - seconds. A `'tlsClientError'` is emitted on the `tls.Server` object whenever - a handshake times out. + does not finish in the specified number of milliseconds. Defaults to + `120000` (120 seconds). A `'tlsClientError'` is emitted on the `tls.Server` + object whenever a handshake times out. * `requestCert` {boolean} If `true` the server will request a certificate from clients that connect and attempt to verify that certificate. Defaults to `false`. diff --git a/lib/path.js b/lib/path.js index 9f33cb87bc5..7a486885269 100644 --- a/lib/path.js +++ b/lib/path.js @@ -50,7 +50,7 @@ function isWindowsDeviceRoot(code) { } // Resolves . and .. elements in a path with directory names -function normalizeStringWin32(path, allowAboveRoot) { +function normalizeString(path, allowAboveRoot, separator) { var res = ''; var lastSegmentLength = 0; var lastSlash = -1; @@ -72,14 +72,14 @@ function normalizeStringWin32(path, allowAboveRoot) { res.charCodeAt(res.length - 1) !== CHAR_DOT || res.charCodeAt(res.length - 2) !== CHAR_DOT) { if (res.length > 2) { - const lastSlashIndex = res.lastIndexOf('\\'); + const lastSlashIndex = res.lastIndexOf(separator); if (lastSlashIndex !== res.length - 1) { if (lastSlashIndex === -1) { res = ''; lastSegmentLength = 0; } else { res = res.slice(0, lastSlashIndex); - lastSegmentLength = res.length - 1 - res.lastIndexOf('\\'); + lastSegmentLength = res.length - 1 - res.lastIndexOf(separator); } lastSlash = i; dots = 0; @@ -95,82 +95,14 @@ function normalizeStringWin32(path, allowAboveRoot) { } if (allowAboveRoot) { if (res.length > 0) - res += '\\..'; + res += `${separator}..`; else res = '..'; lastSegmentLength = 2; } } else { if (res.length > 0) - res += '\\' + path.slice(lastSlash + 1, i); - else - res = path.slice(lastSlash + 1, i); - lastSegmentLength = i - lastSlash - 1; - } - lastSlash = i; - dots = 0; - } else if (code === CHAR_DOT && dots !== -1) { - ++dots; - } else { - dots = -1; - } - } - return res; -} - -// Resolves . and .. elements in a path with directory names -function normalizeStringPosix(path, allowAboveRoot) { - var res = ''; - var lastSegmentLength = 0; - var lastSlash = -1; - var dots = 0; - var code; - for (var i = 0; i <= path.length; ++i) { - if (i < path.length) - code = path.charCodeAt(i); - else if (code === CHAR_FORWARD_SLASH) - break; - else - code = CHAR_FORWARD_SLASH; - if (code === CHAR_FORWARD_SLASH) { - if (lastSlash === i - 1 || dots === 1) { - // NOOP - } else if (lastSlash !== i - 1 && dots === 2) { - if (res.length < 2 || lastSegmentLength !== 2 || - res.charCodeAt(res.length - 1) !== CHAR_DOT || - res.charCodeAt(res.length - 2) !== CHAR_DOT) { - if (res.length > 2) { - const lastSlashIndex = res.lastIndexOf('/'); - if (lastSlashIndex !== res.length - 1) { - if (lastSlashIndex === -1) { - res = ''; - lastSegmentLength = 0; - } else { - res = res.slice(0, lastSlashIndex); - lastSegmentLength = res.length - 1 - res.lastIndexOf('/'); - } - lastSlash = i; - dots = 0; - continue; - } - } else if (res.length === 2 || res.length === 1) { - res = ''; - lastSegmentLength = 0; - lastSlash = i; - dots = 0; - continue; - } - } - if (allowAboveRoot) { - if (res.length > 0) - res += '/..'; - else - res = '..'; - lastSegmentLength = 2; - } - } else { - if (res.length > 0) - res += '/' + path.slice(lastSlash + 1, i); + res += separator + path.slice(lastSlash + 1, i); else res = path.slice(lastSlash + 1, i); lastSegmentLength = i - lastSlash - 1; @@ -340,7 +272,7 @@ const win32 = { // fails) // Normalize the tail path - resolvedTail = normalizeStringWin32(resolvedTail, !resolvedAbsolute); + resolvedTail = normalizeString(resolvedTail, !resolvedAbsolute, '\\'); return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) || '.'; @@ -432,7 +364,7 @@ const win32 = { var tail; if (rootEnd < len) - tail = normalizeStringWin32(path.slice(rootEnd), !isAbsolute); + tail = normalizeString(path.slice(rootEnd), !isAbsolute, '\\'); else tail = ''; if (tail.length === 0 && !isAbsolute) @@ -1163,7 +1095,7 @@ const posix = { // handle relative paths to be safe (might happen when process.cwd() fails) // Normalize the path - resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute); + resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute, '/'); if (resolvedAbsolute) { if (resolvedPath.length > 0) @@ -1189,7 +1121,7 @@ const posix = { path.charCodeAt(path.length - 1) === CHAR_FORWARD_SLASH; // Normalize the path - path = normalizeStringPosix(path, !isAbsolute); + path = normalizeString(path, !isAbsolute, '/'); if (path.length === 0 && !isAbsolute) path = '.'; diff --git a/src/async_wrap.cc b/src/async_wrap.cc index b6776364a53..83882d9f805 100644 --- a/src/async_wrap.cc +++ b/src/async_wrap.cc @@ -162,19 +162,25 @@ static void DestroyAsyncIdsCallback(void* arg) { } -void AsyncWrap::EmitPromiseResolve(Environment* env, double async_id) { +void Emit(Environment* env, double async_id, AsyncHooks::Fields type, + Local fn) { AsyncHooks* async_hooks = env->async_hooks(); - if (async_hooks->fields()[AsyncHooks::kPromiseResolve] == 0) + if (async_hooks->fields()[type] == 0) return; Local async_id_value = Number::New(env->isolate(), async_id); - Local fn = env->async_hooks_promise_resolve_function(); FatalTryCatch try_catch(env); USE(fn->Call(env->context(), Undefined(env->isolate()), 1, &async_id_value)); } +void AsyncWrap::EmitPromiseResolve(Environment* env, double async_id) { + Emit(env, async_id, AsyncHooks::kPromiseResolve, + env->async_hooks_promise_resolve_function()); +} + + void AsyncWrap::EmitTraceEventBefore() { switch (provider_type()) { #define V(PROVIDER) \ @@ -192,15 +198,8 @@ void AsyncWrap::EmitTraceEventBefore() { void AsyncWrap::EmitBefore(Environment* env, double async_id) { - AsyncHooks* async_hooks = env->async_hooks(); - - if (async_hooks->fields()[AsyncHooks::kBefore] == 0) - return; - - Local async_id_value = Number::New(env->isolate(), async_id); - Local fn = env->async_hooks_before_function(); - FatalTryCatch try_catch(env); - USE(fn->Call(env->context(), Undefined(env->isolate()), 1, &async_id_value)); + Emit(env, async_id, AsyncHooks::kBefore, + env->async_hooks_before_function()); } @@ -221,17 +220,10 @@ void AsyncWrap::EmitTraceEventAfter() { void AsyncWrap::EmitAfter(Environment* env, double async_id) { - AsyncHooks* async_hooks = env->async_hooks(); - - if (async_hooks->fields()[AsyncHooks::kAfter] == 0) - return; - // If the user's callback failed then the after() hooks will be called at the // end of _fatalException(). - Local async_id_value = Number::New(env->isolate(), async_id); - Local fn = env->async_hooks_after_function(); - FatalTryCatch try_catch(env); - USE(fn->Call(env->context(), Undefined(env->isolate()), 1, &async_id_value)); + Emit(env, async_id, AsyncHooks::kAfter, + env->async_hooks_after_function()); } class PromiseWrap : public AsyncWrap { diff --git a/test/parallel/test-regress-GH-9819.js b/test/parallel/test-crypto-tostring-segfault.js similarity index 74% rename from test/parallel/test-regress-GH-9819.js rename to test/parallel/test-crypto-tostring-segfault.js index 7eed1c512f7..b2c95117d3b 100644 --- a/test/parallel/test-regress-GH-9819.js +++ b/test/parallel/test-crypto-tostring-segfault.js @@ -3,6 +3,11 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); +// This test ensures that node doesn't SEGFAULT when either of +// `crypto.createHash` or `crypto.createHmac` are given an object that defines +// a throwing `toString`. +// https://github.com/nodejs/node/issues/9819 + const assert = require('assert'); const execFile = require('child_process').execFile; diff --git a/test/parallel/test-regress-GH-5051.js b/test/parallel/test-http-addrequest-localaddress.js similarity index 85% rename from test/parallel/test-regress-GH-5051.js rename to test/parallel/test-http-addrequest-localaddress.js index 0fef879c6f1..fce53c88af3 100644 --- a/test/parallel/test-regress-GH-5051.js +++ b/test/parallel/test-http-addrequest-localaddress.js @@ -1,5 +1,10 @@ 'use strict'; require('../common'); + +// This test ensures that `addRequest`'s Legacy API accepts `localAddress` +// correctly instead of accepting `path`. +// https://github.com/nodejs/node/issues/5051 + const assert = require('assert'); const agent = require('http').globalAgent; diff --git a/test/parallel/test-regress-GH-5727.js b/test/parallel/test-net-listen-invalid-port.js similarity index 82% rename from test/parallel/test-regress-GH-5727.js rename to test/parallel/test-net-listen-invalid-port.js index fab139ca7c3..d07bc9fafa8 100644 --- a/test/parallel/test-regress-GH-5727.js +++ b/test/parallel/test-net-listen-invalid-port.js @@ -1,5 +1,10 @@ 'use strict'; const common = require('../common'); + +// This test ensures that port numbers are validated in *all* kinds of `listen` +// calls. If an invalid port is supplied, ensures a `RangeError` is thrown. +// https://github.com/nodejs/node/issues/5727 + const assert = require('assert'); const net = require('net'); diff --git a/test/parallel/test-regress-GH-5927.js b/test/parallel/test-tty-stdin-pipe.js similarity index 94% rename from test/parallel/test-regress-GH-5927.js rename to test/parallel/test-tty-stdin-pipe.js index f32dd61c978..9e941532060 100644 --- a/test/parallel/test-regress-GH-5927.js +++ b/test/parallel/test-tty-stdin-pipe.js @@ -21,6 +21,10 @@ 'use strict'; require('../common'); + +// This test ensures piping from `stdin` isn't broken. +// https://github.com/nodejs/node/issues/5927 + const assert = require('assert'); const readline = require('readline'); diff --git a/test/parallel/test-regress-GH-6235.js b/test/parallel/test-v8-global-setter.js similarity index 87% rename from test/parallel/test-regress-GH-6235.js rename to test/parallel/test-v8-global-setter.js index 484138ba2db..1cb0898e61a 100644 --- a/test/parallel/test-regress-GH-6235.js +++ b/test/parallel/test-v8-global-setter.js @@ -22,4 +22,8 @@ 'use strict'; require('../common'); +// This test ensures v8 correctly sets a property on the global object if it +// has a setter interceptor in strict mode. +// https://github.com/nodejs/node-v0.x-archive/issues/6235 + require('vm').runInNewContext('"use strict"; var v = 1; v = 2'); diff --git a/vcbuild.bat b/vcbuild.bat index 4b082f7332c..1b3f80319e2 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -1,7 +1,5 @@ @if not defined DEBUG_HELPER @ECHO OFF -cd %~dp0 - if /i "%1"=="help" goto help if /i "%1"=="--help" goto help if /i "%1"=="-help" goto help @@ -11,6 +9,8 @@ if /i "%1"=="-?" goto help if /i "%1"=="--?" goto help if /i "%1"=="/?" goto help +cd %~dp0 + @rem Process arguments. set config=Release set target=Build