diff options
author | Michaël Zasso <targos@protonmail.com> | 2017-03-21 10:16:54 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2017-03-25 09:44:10 +0100 |
commit | c459d8ea5d402c702948c860d9497b2230ff7e8a (patch) | |
tree | 56c282fc4d40e5cb613b47cf7be3ea0526ed5b6f /deps/v8/src/runtime | |
parent | e0bc5a7361b1d29c3ed034155fd779ce6f44fb13 (diff) | |
download | node-new-c459d8ea5d402c702948c860d9497b2230ff7e8a.tar.gz |
deps: update V8 to 5.7.492.69
PR-URL: https://github.com/nodejs/node/pull/11752
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Diffstat (limited to 'deps/v8/src/runtime')
32 files changed, 1802 insertions, 1475 deletions
diff --git a/deps/v8/src/runtime/runtime-array.cc b/deps/v8/src/runtime/runtime-array.cc index 1a2d957caf..a9cbc208b3 100644 --- a/deps/v8/src/runtime/runtime-array.cc +++ b/deps/v8/src/runtime/runtime-array.cc @@ -19,7 +19,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0); Object* length = prototype->length(); CHECK(length->IsSmi()); @@ -60,17 +60,12 @@ static void InstallBuiltin( RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); Handle<JSObject> holder = isolate->factory()->NewJSObject(isolate->object_function()); InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop); - if (FLAG_minimal) { - InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush); - } else { - FastArrayPushStub stub(isolate); - InstallCode(isolate, holder, "push", stub.GetCode()); - } + InstallBuiltin(isolate, holder, "push", Builtins::kFastArrayPush); InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift); InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift); InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice); @@ -90,7 +85,7 @@ RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) { RUNTIME_FUNCTION(Runtime_FixedArrayGet) { SealHandleScope shs(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_CHECKED(FixedArray, object, 0); CONVERT_SMI_ARG_CHECKED(index, 1); return object->get(index); @@ -99,7 +94,7 @@ RUNTIME_FUNCTION(Runtime_FixedArrayGet) { RUNTIME_FUNCTION(Runtime_FixedArraySet) { SealHandleScope shs(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_CHECKED(FixedArray, object, 0); CONVERT_SMI_ARG_CHECKED(index, 1); CONVERT_ARG_CHECKED(Object, value, 2); @@ -127,7 +122,7 @@ RUNTIME_FUNCTION(Runtime_TransitionElementsKind) { // Returns -1 if hole removal is not supported by this method. RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); if (object->IsJSProxy()) return Smi::FromInt(-1); @@ -139,7 +134,7 @@ RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) { // Move contents of argument 0 (an array) to argument 1 (an array) RUNTIME_FUNCTION(Runtime_MoveArrayContents) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArray, from, 0); CONVERT_ARG_HANDLE_CHECKED(JSArray, to, 1); JSObject::ValidateElements(from); @@ -162,7 +157,7 @@ RUNTIME_FUNCTION(Runtime_MoveArrayContents) { // How many elements does this object/array have? RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); Handle<FixedArrayBase> elements(array->elements(), isolate); SealHandleScope shs(isolate); @@ -205,7 +200,7 @@ RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) { // Intervals can span over some keys that are not in the object. RUNTIME_FUNCTION(Runtime_GetArrayKeys) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); ElementsKind kind = array->GetElementsKind(); @@ -249,8 +244,7 @@ RUNTIME_FUNCTION(Runtime_GetArrayKeys) { } if (j != keys->length()) { - isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( - *keys, keys->length() - j); + isolate->heap()->RightTrimFixedArray(*keys, keys->length() - j); } return *isolate->factory()->NewJSArrayWithElements(keys); @@ -363,7 +357,7 @@ RUNTIME_FUNCTION(Runtime_NewArray) { RUNTIME_FUNCTION(Runtime_NormalizeElements) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); CHECK(!array->HasFixedTypedArrayElements()); CHECK(!array->IsJSGlobalProxy()); @@ -375,7 +369,7 @@ RUNTIME_FUNCTION(Runtime_NormalizeElements) { // GrowArrayElements returns a sentinel Smi if the object was normalized. RUNTIME_FUNCTION(Runtime_GrowArrayElements) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); CONVERT_NUMBER_CHECKED(int, key, Int32, args[1]); @@ -399,7 +393,7 @@ RUNTIME_FUNCTION(Runtime_GrowArrayElements) { RUNTIME_FUNCTION(Runtime_HasComplexElements) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0); for (PrototypeIterator iter(isolate, array, kStartAtReceiver); !iter.IsAtEnd(); iter.Advance()) { @@ -421,7 +415,7 @@ RUNTIME_FUNCTION(Runtime_HasComplexElements) { // ES6 22.1.2.2 Array.isArray RUNTIME_FUNCTION(Runtime_ArrayIsArray) { HandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); Maybe<bool> result = Object::IsArray(object); MAYBE_RETURN(result, isolate->heap()->exception()); @@ -430,14 +424,14 @@ RUNTIME_FUNCTION(Runtime_ArrayIsArray) { RUNTIME_FUNCTION(Runtime_IsArray) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(Object, obj, 0); return isolate->heap()->ToBoolean(obj->IsJSArray()); } RUNTIME_FUNCTION(Runtime_ArraySpeciesConstructor) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, original_array, 0); RETURN_RESULT_OR_FAILURE( isolate, Object::ArraySpeciesConstructor(isolate, original_array)); @@ -446,7 +440,7 @@ RUNTIME_FUNCTION(Runtime_ArraySpeciesConstructor) { // ES7 22.1.3.11 Array.prototype.includes RUNTIME_FUNCTION(Runtime_ArrayIncludes_Slow) { HandleScope shs(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, search_element, 1); CONVERT_ARG_HANDLE_CHECKED(Object, from_index, 2); @@ -502,8 +496,7 @@ RUNTIME_FUNCTION(Runtime_ArrayIncludes_Slow) { // If the receiver is not a special receiver type, and the length is a valid // element index, perform fast operation tailored to specific ElementsKinds. - if (object->map()->instance_type() > LAST_SPECIAL_RECEIVER_TYPE && - len < kMaxUInt32 && + if (!object->map()->IsSpecialReceiverMap() && len < kMaxUInt32 && JSObject::PrototypeHasNoElements(isolate, JSObject::cast(*object))) { Handle<JSObject> obj = Handle<JSObject>::cast(object); ElementsAccessor* elements = obj->GetElementsAccessor(); @@ -538,21 +531,21 @@ RUNTIME_FUNCTION(Runtime_ArrayIncludes_Slow) { RUNTIME_FUNCTION(Runtime_ArrayIndexOf) { HandleScope shs(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, search_element, 1); CONVERT_ARG_HANDLE_CHECKED(Object, from_index, 2); // Let O be ? ToObject(this value). - Handle<Object> receiver_obj = args.at<Object>(0); - if (receiver_obj->IsNull(isolate) || receiver_obj->IsUndefined(isolate)) { + Handle<Object> receiver_obj = args.at(0); + if (receiver_obj->IsNullOrUndefined(isolate)) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kCalledOnNullOrUndefined, isolate->factory()->NewStringFromAsciiChecked( "Array.prototype.indexOf"))); } Handle<JSReceiver> object; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, object, Object::ToObject(isolate, args.at<Object>(0))); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, object, + Object::ToObject(isolate, args.at(0))); // Let len be ? ToLength(? Get(O, "length")). int64_t len; @@ -601,8 +594,7 @@ RUNTIME_FUNCTION(Runtime_ArrayIndexOf) { // If the receiver is not a special receiver type, and the length is a valid // element index, perform fast operation tailored to specific ElementsKinds. - if (object->map()->instance_type() > LAST_SPECIAL_RECEIVER_TYPE && - len < kMaxUInt32 && + if (!object->map()->IsSpecialReceiverMap() && len < kMaxUInt32 && JSObject::PrototypeHasNoElements(isolate, JSObject::cast(*object))) { Handle<JSObject> obj = Handle<JSObject>::cast(object); ElementsAccessor* elements = obj->GetElementsAccessor(); @@ -636,47 +628,22 @@ RUNTIME_FUNCTION(Runtime_ArrayIndexOf) { return Smi::FromInt(-1); } + RUNTIME_FUNCTION(Runtime_SpreadIterablePrepare) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, spread, 0); - if (spread->IsJSArray()) { - // Check that the spread arg has fast elements - Handle<JSArray> spread_array = Handle<JSArray>::cast(spread); - ElementsKind array_kind = spread_array->GetElementsKind(); - - // And that it has the orignal ArrayPrototype - JSObject* array_proto = JSObject::cast(spread_array->map()->prototype()); - Map* iterator_map = isolate->initial_array_iterator_prototype()->map(); - - // Check that the iterator acts as expected. - // If IsArrayIteratorLookupChainIntact(), then we know that the initial - // ArrayIterator is being used. If the map of the prototype has changed, - // then take the slow path. - - if (isolate->is_initial_array_prototype(array_proto) && - isolate->IsArrayIteratorLookupChainIntact() && - isolate->is_initial_array_iterator_prototype_map(iterator_map)) { - if (IsFastPackedElementsKind(array_kind)) { - return *spread; - } - if (IsFastHoleyElementsKind(array_kind) && - isolate->IsFastArrayConstructorPrototypeChainIntact()) { - return *spread; - } - } + // Iterate over the spread if we need to. + if (spread->IterationHasObservableEffects()) { + Handle<JSFunction> spread_iterable_function = isolate->spread_iterable(); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, spread, + Execution::Call(isolate, spread_iterable_function, + isolate->factory()->undefined_value(), 1, &spread)); } - Handle<JSFunction> spread_iterable_function = isolate->spread_iterable(); - - Handle<Object> spreaded; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, spreaded, - Execution::Call(isolate, spread_iterable_function, - isolate->factory()->undefined_value(), 1, &spread)); - - return *spreaded; + return *spread; } } // namespace internal diff --git a/deps/v8/src/runtime/runtime-atomics.cc b/deps/v8/src/runtime/runtime-atomics.cc index 3bd0738dd2..ff7ded9b09 100644 --- a/deps/v8/src/runtime/runtime-atomics.cc +++ b/deps/v8/src/runtime/runtime-atomics.cc @@ -349,7 +349,7 @@ RUNTIME_FUNCTION(Runtime_ThrowInvalidAtomicAccessIndexError) { RUNTIME_FUNCTION(Runtime_AtomicsCompareExchange) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); CONVERT_NUMBER_ARG_HANDLE_CHECKED(oldobj, 2); @@ -383,7 +383,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsCompareExchange) { RUNTIME_FUNCTION(Runtime_AtomicsAdd) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); @@ -415,7 +415,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsAdd) { RUNTIME_FUNCTION(Runtime_AtomicsSub) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); @@ -447,7 +447,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsSub) { RUNTIME_FUNCTION(Runtime_AtomicsAnd) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); @@ -479,7 +479,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsAnd) { RUNTIME_FUNCTION(Runtime_AtomicsOr) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); @@ -511,7 +511,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsOr) { RUNTIME_FUNCTION(Runtime_AtomicsXor) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); @@ -543,7 +543,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsXor) { RUNTIME_FUNCTION(Runtime_AtomicsExchange) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2); @@ -575,7 +575,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsExchange) { RUNTIME_FUNCTION(Runtime_AtomicsIsLockFree) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_NUMBER_ARG_HANDLE_CHECKED(size, 0); uint32_t usize = NumberToUint32(*size); return isolate->heap()->ToBoolean(AtomicIsLockFree(usize)); diff --git a/deps/v8/src/runtime/runtime-classes.cc b/deps/v8/src/runtime/runtime-classes.cc index 323604ffde..246079232b 100644 --- a/deps/v8/src/runtime/runtime-classes.cc +++ b/deps/v8/src/runtime/runtime-classes.cc @@ -7,8 +7,10 @@ #include <stdlib.h> #include <limits> +#include "src/accessors.h" #include "src/arguments.h" #include "src/debug/debug.h" +#include "src/elements.h" #include "src/frames-inl.h" #include "src/isolate-inl.h" #include "src/messages.h" @@ -18,17 +20,9 @@ namespace v8 { namespace internal { -RUNTIME_FUNCTION(Runtime_ThrowNonMethodError) { - HandleScope scope(isolate); - DCHECK(args.length() == 0); - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewReferenceError(MessageTemplate::kNonMethod)); -} - - RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewReferenceError(MessageTemplate::kUnsupportedSuper)); } @@ -36,7 +30,7 @@ RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) { RUNTIME_FUNCTION(Runtime_ThrowConstructorNonCallableError) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0); Handle<Object> name(constructor->shared()->name(), isolate); THROW_NEW_ERROR_RETURN_FAILURE( @@ -44,40 +38,63 @@ RUNTIME_FUNCTION(Runtime_ThrowConstructorNonCallableError) { } -RUNTIME_FUNCTION(Runtime_ThrowArrayNotSubclassableError) { +RUNTIME_FUNCTION(Runtime_ThrowStaticPrototypeError) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kArrayNotSubclassable)); + isolate, NewTypeError(MessageTemplate::kStaticPrototype)); } - -static Object* ThrowStaticPrototypeError(Isolate* isolate) { +RUNTIME_FUNCTION(Runtime_ThrowSuperAlreadyCalledError) { + HandleScope scope(isolate); + DCHECK_EQ(0, args.length()); THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kStaticPrototype)); + isolate, NewReferenceError(MessageTemplate::kSuperAlreadyCalled)); } +namespace { -RUNTIME_FUNCTION(Runtime_ThrowStaticPrototypeError) { - HandleScope scope(isolate); - DCHECK(args.length() == 0); - return ThrowStaticPrototypeError(isolate); +Object* ThrowNotSuperConstructor(Isolate* isolate, Handle<Object> constructor, + Handle<JSFunction> function) { + Handle<Object> super_name; + if (constructor->IsJSFunction()) { + super_name = handle(Handle<JSFunction>::cast(constructor)->shared()->name(), + isolate); + } else if (constructor->IsOddball()) { + DCHECK(constructor->IsNull(isolate)); + super_name = isolate->factory()->null_string(); + } else { + super_name = Object::NoSideEffectsToString(isolate, constructor); + } + // null constructor + if (Handle<String>::cast(super_name)->length() == 0) { + super_name = isolate->factory()->null_string(); + } + Handle<Object> function_name(function->shared()->name(), isolate); + // anonymous class + if (Handle<String>::cast(function_name)->length() == 0) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError(MessageTemplate::kNotSuperConstructorAnonymousClass, + super_name)); + } + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kNotSuperConstructor, super_name, + function_name)); } +} // namespace -RUNTIME_FUNCTION(Runtime_ThrowIfStaticPrototype) { +RUNTIME_FUNCTION(Runtime_ThrowNotSuperConstructor) { HandleScope scope(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(Name, name, 0); - if (Name::Equals(name, isolate->factory()->prototype_string())) { - return ThrowStaticPrototypeError(isolate); - } - return *name; + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0); + CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1); + return ThrowNotSuperConstructor(isolate, constructor, function); } - RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) { - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); return isolate->heap()->home_object_symbol(); } @@ -143,13 +160,6 @@ static MaybeHandle<Object> DefineClass(Isolate* isolate, prototype, attribs), Object); - // TODO(arv): Only do this conditionally. - Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol()); - RETURN_ON_EXCEPTION( - isolate, JSObject::SetOwnPropertyIgnoreAttributes( - constructor, home_object_symbol, prototype, DONT_ENUM), - Object); - if (!constructor_parent.is_null()) { MAYBE_RETURN_NULL(JSObject::SetPrototype(constructor, constructor_parent, false, Object::THROW_ON_ERROR)); @@ -171,13 +181,14 @@ static MaybeHandle<Object> DefineClass(Isolate* isolate, handle(Smi::FromInt(end_position), isolate), STRICT), Object); - return constructor; + // Caller already has access to constructor, so return the prototype. + return prototype; } RUNTIME_FUNCTION(Runtime_DefineClass) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 0); CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 1); CONVERT_SMI_ARG_CHECKED(start_position, 2); @@ -189,6 +200,42 @@ RUNTIME_FUNCTION(Runtime_DefineClass) { } namespace { +void InstallClassNameAccessor(Isolate* isolate, Handle<JSObject> object) { + PropertyAttributes attrs = + static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); + // Cannot fail since this should only be called when creating an object + // literal. + CHECK(!JSObject::SetAccessor( + object, Accessors::FunctionNameInfo(object->GetIsolate(), attrs)) + .is_null()); +} +} // anonymous namespace + +RUNTIME_FUNCTION(Runtime_InstallClassNameAccessor) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); + InstallClassNameAccessor(isolate, object); + return *object; +} + +RUNTIME_FUNCTION(Runtime_InstallClassNameAccessorWithCheck) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); + + // If a property named "name" is already defined, exit. + Handle<Name> key = isolate->factory()->name_string(); + if (JSObject::HasRealNamedProperty(object, key).FromMaybe(false)) { + return *object; + } + + // Define the "name" accessor. + InstallClassNameAccessor(isolate, object); + return *object; +} + +namespace { enum class SuperMode { kLoad, kStore }; @@ -326,7 +373,7 @@ MaybeHandle<Object> StoreElementToSuper(Isolate* isolate, RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); CONVERT_ARG_HANDLE_CHECKED(Name, name, 2); @@ -339,7 +386,7 @@ RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) { RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); CONVERT_ARG_HANDLE_CHECKED(Name, name, 2); @@ -373,7 +420,7 @@ static MaybeHandle<Object> StoreKeyedToSuper( RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Strict) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); CONVERT_ARG_HANDLE_CHECKED(Object, key, 2); @@ -387,7 +434,7 @@ RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Strict) { RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Sloppy) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); CONVERT_ARG_HANDLE_CHECKED(Object, key, 2); @@ -403,7 +450,56 @@ RUNTIME_FUNCTION(Runtime_GetSuperConstructor) { SealHandleScope shs(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(JSFunction, active_function, 0); - return active_function->map()->prototype(); + Object* prototype = active_function->map()->prototype(); + if (!prototype->IsConstructor()) { + HandleScope scope(isolate); + return ThrowNotSuperConstructor(isolate, handle(prototype, isolate), + handle(active_function, isolate)); + } + return prototype; +} + +RUNTIME_FUNCTION(Runtime_NewWithSpread) { + HandleScope scope(isolate); + DCHECK_LE(3, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, constructor, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, new_target, 1); + + int constructor_argc = args.length() - 2; + CONVERT_ARG_HANDLE_CHECKED(Object, spread, args.length() - 1); + + // Iterate over the spread if we need to. + if (spread->IterationHasObservableEffects()) { + Handle<JSFunction> spread_iterable_function = isolate->spread_iterable(); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, spread, + Execution::Call(isolate, spread_iterable_function, + isolate->factory()->undefined_value(), 1, &spread)); + } + + uint32_t spread_length; + Handle<JSArray> spread_array = Handle<JSArray>::cast(spread); + CHECK(spread_array->length()->ToArrayIndex(&spread_length)); + int result_length = constructor_argc - 1 + spread_length; + ScopedVector<Handle<Object>> construct_args(result_length); + + // Append each of the individual args to the result. + for (int i = 0; i < constructor_argc - 1; i++) { + construct_args[i] = args.at<Object>(2 + i); + } + + // Append element of the spread to the result. + ElementsAccessor* accessor = spread_array->GetElementsAccessor(); + for (uint32_t i = 0; i < spread_length; i++) { + DCHECK(accessor->HasElement(spread_array, i)); + Handle<Object> element = accessor->Get(spread_array, i); + construct_args[constructor_argc - 1 + i] = element; + } + + // Call the constructor. + RETURN_RESULT_OR_FAILURE( + isolate, Execution::New(isolate, constructor, new_target, result_length, + construct_args.start())); } } // namespace internal diff --git a/deps/v8/src/runtime/runtime-collections.cc b/deps/v8/src/runtime/runtime-collections.cc index 57e5d98532..15c1fab76f 100644 --- a/deps/v8/src/runtime/runtime-collections.cc +++ b/deps/v8/src/runtime/runtime-collections.cc @@ -14,7 +14,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_StringGetRawHashField) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, string, 0); return *isolate->factory()->NewNumberFromUint(string->hash_field()); } @@ -22,14 +22,14 @@ RUNTIME_FUNCTION(Runtime_StringGetRawHashField) { RUNTIME_FUNCTION(Runtime_TheHole) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); return isolate->heap()->the_hole_value(); } RUNTIME_FUNCTION(Runtime_JSCollectionGetTable) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(JSObject, object, 0); CHECK(object->IsJSSet() || object->IsJSMap()); return static_cast<JSCollection*>(object)->table(); @@ -38,7 +38,7 @@ RUNTIME_FUNCTION(Runtime_JSCollectionGetTable) { RUNTIME_FUNCTION(Runtime_GenericHash) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); Smi* hash = Object::GetOrCreateHash(isolate, object); return hash; @@ -47,7 +47,7 @@ RUNTIME_FUNCTION(Runtime_GenericHash) { RUNTIME_FUNCTION(Runtime_SetInitialize) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); JSSet::Initialize(holder, isolate); return *holder; @@ -56,7 +56,7 @@ RUNTIME_FUNCTION(Runtime_SetInitialize) { RUNTIME_FUNCTION(Runtime_SetGrow) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table())); table = OrderedHashSet::EnsureGrowable(table); @@ -67,7 +67,7 @@ RUNTIME_FUNCTION(Runtime_SetGrow) { RUNTIME_FUNCTION(Runtime_SetShrink) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table())); table = OrderedHashSet::Shrink(table); @@ -78,7 +78,7 @@ RUNTIME_FUNCTION(Runtime_SetShrink) { RUNTIME_FUNCTION(Runtime_SetClear) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); JSSet::Clear(holder); return isolate->heap()->undefined_value(); @@ -87,7 +87,7 @@ RUNTIME_FUNCTION(Runtime_SetClear) { RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0); CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1); CONVERT_SMI_ARG_CHECKED(kind, 2) @@ -103,7 +103,7 @@ RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) { RUNTIME_FUNCTION(Runtime_SetIteratorClone) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0); Handle<JSSetIterator> result = isolate->factory()->NewJSSetIterator(); @@ -117,7 +117,7 @@ RUNTIME_FUNCTION(Runtime_SetIteratorClone) { RUNTIME_FUNCTION(Runtime_SetIteratorNext) { SealHandleScope shs(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_CHECKED(JSSetIterator, holder, 0); CONVERT_ARG_CHECKED(JSArray, value_array, 1); return holder->Next(value_array); @@ -130,7 +130,7 @@ RUNTIME_FUNCTION(Runtime_SetIteratorNext) { // 2: Iteration kind RUNTIME_FUNCTION(Runtime_SetIteratorDetails) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0); Handle<FixedArray> details = isolate->factory()->NewFixedArray(4); details->set(0, isolate->heap()->ToBoolean(holder->HasMore())); @@ -142,7 +142,7 @@ RUNTIME_FUNCTION(Runtime_SetIteratorDetails) { RUNTIME_FUNCTION(Runtime_MapInitialize) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); JSMap::Initialize(holder, isolate); return *holder; @@ -151,7 +151,7 @@ RUNTIME_FUNCTION(Runtime_MapInitialize) { RUNTIME_FUNCTION(Runtime_MapShrink) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table())); table = OrderedHashMap::Shrink(table); @@ -162,7 +162,7 @@ RUNTIME_FUNCTION(Runtime_MapShrink) { RUNTIME_FUNCTION(Runtime_MapClear) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); JSMap::Clear(holder); return isolate->heap()->undefined_value(); @@ -171,7 +171,7 @@ RUNTIME_FUNCTION(Runtime_MapClear) { RUNTIME_FUNCTION(Runtime_MapGrow) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table())); table = OrderedHashMap::EnsureGrowable(table); @@ -182,7 +182,7 @@ RUNTIME_FUNCTION(Runtime_MapGrow) { RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1); CONVERT_SMI_ARG_CHECKED(kind, 2) @@ -199,7 +199,7 @@ RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) { RUNTIME_FUNCTION(Runtime_MapIteratorClone) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); Handle<JSMapIterator> result = isolate->factory()->NewJSMapIterator(); @@ -217,7 +217,7 @@ RUNTIME_FUNCTION(Runtime_MapIteratorClone) { // 2: Iteration kind RUNTIME_FUNCTION(Runtime_MapIteratorDetails) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); Handle<FixedArray> details = isolate->factory()->NewFixedArray(4); details->set(0, isolate->heap()->ToBoolean(holder->HasMore())); @@ -229,7 +229,7 @@ RUNTIME_FUNCTION(Runtime_MapIteratorDetails) { RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); CONVERT_NUMBER_CHECKED(int, max_entries, Int32, args[1]); CHECK(max_entries >= 0); @@ -264,7 +264,7 @@ RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { RUNTIME_FUNCTION(Runtime_MapIteratorNext) { SealHandleScope shs(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_CHECKED(JSMapIterator, holder, 0); CONVERT_ARG_CHECKED(JSArray, value_array, 1); return holder->Next(value_array); @@ -273,7 +273,7 @@ RUNTIME_FUNCTION(Runtime_MapIteratorNext) { RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); JSWeakCollection::Initialize(weak_collection, isolate); return *weak_collection; @@ -282,7 +282,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) { RUNTIME_FUNCTION(Runtime_WeakCollectionGet) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); CONVERT_SMI_ARG_CHECKED(hash, 2) @@ -298,7 +298,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionGet) { RUNTIME_FUNCTION(Runtime_WeakCollectionHas) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); CONVERT_SMI_ARG_CHECKED(hash, 2) @@ -313,7 +313,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionHas) { RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); CONVERT_SMI_ARG_CHECKED(hash, 2) @@ -328,7 +328,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) { RUNTIME_FUNCTION(Runtime_WeakCollectionSet) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); CHECK(key->IsJSReceiver() || key->IsSymbol()); @@ -344,7 +344,7 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionSet) { RUNTIME_FUNCTION(Runtime_GetWeakSetValues) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); CONVERT_NUMBER_CHECKED(int, max_values, Int32, args[1]); CHECK(max_values >= 0); diff --git a/deps/v8/src/runtime/runtime-compiler.cc b/deps/v8/src/runtime/runtime-compiler.cc index 472e076de4..f1c76bb2ac 100644 --- a/deps/v8/src/runtime/runtime-compiler.cc +++ b/deps/v8/src/runtime/runtime-compiler.cc @@ -11,7 +11,6 @@ #include "src/deoptimizer.h" #include "src/frames-inl.h" #include "src/full-codegen/full-codegen.h" -#include "src/interpreter/bytecode-array-iterator.h" #include "src/isolate-inl.h" #include "src/messages.h" #include "src/v8threads.h" @@ -93,11 +92,11 @@ RUNTIME_FUNCTION(Runtime_InstantiateAsmJs) { } Handle<JSObject> foreign; if (args[2]->IsJSObject()) { - foreign = args.at<i::JSObject>(2); + foreign = args.at<JSObject>(2); } Handle<JSArrayBuffer> memory; if (args[3]->IsJSArrayBuffer()) { - memory = args.at<i::JSArrayBuffer>(3); + memory = args.at<JSArrayBuffer>(3); } if (function->shared()->HasAsmWasmData() && AsmJs::IsStdlibValid(isolate, handle(function->shared()->asm_wasm_data()), @@ -128,7 +127,7 @@ RUNTIME_FUNCTION(Runtime_InstantiateAsmJs) { RUNTIME_FUNCTION(Runtime_NotifyStubFailure) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); DCHECK(AllowHeapAllocation::IsAllowed()); delete deoptimizer; @@ -159,7 +158,7 @@ class ActivationsFinder : public ThreadVisitor { RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_SMI_ARG_CHECKED(type_arg, 0); Deoptimizer::BailoutType type = static_cast<Deoptimizer::BailoutType>(type_arg); @@ -270,9 +269,9 @@ BailoutId DetermineEntryAndDisarmOSRForBaseline(JavaScriptFrame* frame) { // Revert the patched back edge table, regardless of whether OSR succeeds. BackEdgeTable::Revert(frame->isolate(), *caller_code); + // Return a BailoutId representing an AST id of the {IterationStatement}. uint32_t pc_offset = static_cast<uint32_t>(frame->pc() - caller_code->instruction_start()); - return caller_code->TranslatePcOffsetToAstId(pc_offset); } @@ -293,27 +292,15 @@ BailoutId DetermineEntryAndDisarmOSRForInterpreter(JavaScriptFrame* frame) { // Reset the OSR loop nesting depth to disarm back edges. bytecode->set_osr_loop_nesting_level(0); - // Translate the offset of the jump instruction to the jump target offset of - // that instruction so that the derived BailoutId points to the loop header. - // TODO(mstarzinger): This can be merged with {BytecodeBranchAnalysis} which - // already performs a pre-pass over the bytecode stream anyways. - int jump_offset = iframe->GetBytecodeOffset(); - interpreter::BytecodeArrayIterator iterator(bytecode); - while (iterator.current_offset() + iterator.current_prefix_offset() < - jump_offset) { - iterator.Advance(); - } - DCHECK(interpreter::Bytecodes::IsJump(iterator.current_bytecode())); - int jump_target_offset = iterator.GetJumpTargetOffset(); - - return BailoutId(jump_target_offset); + // Return a BailoutId representing the bytecode offset of the back branch. + return BailoutId(iframe->GetBytecodeOffset()); } } // namespace RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); // We're not prepared to handle a function with arguments object. @@ -398,7 +385,7 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); // First check if this is a real stack overflow. @@ -465,9 +452,9 @@ static Object* CompileGlobalEval(Isolate* isolate, Handle<String> source, RUNTIME_FUNCTION(Runtime_ResolvePossiblyDirectEval) { HandleScope scope(isolate); - DCHECK(args.length() == 6); + DCHECK_EQ(6, args.length()); - Handle<Object> callee = args.at<Object>(0); + Handle<Object> callee = args.at(0); // If "eval" didn't refer to the original GlobalEval, it's not a // direct call to eval. diff --git a/deps/v8/src/runtime/runtime-debug.cc b/deps/v8/src/runtime/runtime-debug.cc index 824ea92a0f..d24a450cbf 100644 --- a/deps/v8/src/runtime/runtime-debug.cc +++ b/deps/v8/src/runtime/runtime-debug.cc @@ -5,6 +5,7 @@ #include "src/runtime/runtime-utils.h" #include "src/arguments.h" +#include "src/compiler.h" #include "src/debug/debug-evaluate.h" #include "src/debug/debug-frames.h" #include "src/debug/debug-scopes.h" @@ -24,7 +25,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_DebugBreak) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); isolate->debug()->set_return_value(value); @@ -38,7 +39,7 @@ RUNTIME_FUNCTION(Runtime_DebugBreak) { RUNTIME_FUNCTION(Runtime_DebugBreakOnBytecode) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); isolate->debug()->set_return_value(value); @@ -65,7 +66,7 @@ RUNTIME_FUNCTION(Runtime_DebugBreakOnBytecode) { RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); if (isolate->debug()->break_points_active()) { isolate->debug()->HandleDebugBreak(); } @@ -79,9 +80,8 @@ RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) { // args[1]: object supplied during callback RUNTIME_FUNCTION(Runtime_SetDebugEventListener) { SealHandleScope shs(isolate); - DCHECK(args.length() == 2); - CHECK(args[0]->IsJSFunction() || args[0]->IsUndefined(isolate) || - args[0]->IsNull(isolate)); + DCHECK_EQ(2, args.length()); + CHECK(args[0]->IsJSFunction() || args[0]->IsNullOrUndefined(isolate)); CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0); CONVERT_ARG_HANDLE_CHECKED(Object, data, 1); isolate->debug()->SetEventListener(callback, data); @@ -92,7 +92,7 @@ RUNTIME_FUNCTION(Runtime_SetDebugEventListener) { RUNTIME_FUNCTION(Runtime_ScheduleBreak) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); isolate->stack_guard()->RequestDebugBreak(); return isolate->heap()->undefined_value(); } @@ -136,14 +136,6 @@ static Handle<Object> DebugGetProperty(LookupIterator* it, return it->isolate()->factory()->undefined_value(); } - -static Handle<Object> DebugGetProperty(Handle<Object> object, - Handle<Name> name) { - LookupIterator it(object, name); - return DebugGetProperty(&it); -} - - template <class IteratorType> static MaybeHandle<JSArray> GetIteratorInternalProperties( Isolate* isolate, Handle<IteratorType> object) { @@ -248,24 +240,8 @@ MaybeHandle<JSArray> Runtime::GetInternalProperties(Isolate* isolate, result->set(5, generator->receiver()); return factory->NewJSArrayWithElements(result); } else if (object->IsJSPromise()) { - Handle<JSObject> promise = Handle<JSObject>::cast(object); - - Handle<Object> status_obj = - DebugGetProperty(promise, isolate->factory()->promise_state_symbol()); - CHECK(status_obj->IsSmi()); - const char* status = "rejected"; - int status_val = Handle<Smi>::cast(status_obj)->value(); - switch (status_val) { - case kPromiseFulfilled: - status = "resolved"; - break; - case kPromisePending: - status = "pending"; - break; - default: - DCHECK_EQ(kPromiseRejected, status_val); - } - + Handle<JSPromise> promise = Handle<JSPromise>::cast(object); + const char* status = JSPromise::Status(promise->status()); Handle<FixedArray> result = factory->NewFixedArray(2 * 2); Handle<String> promise_status = factory->NewStringFromAsciiChecked("[[PromiseStatus]]"); @@ -273,8 +249,7 @@ MaybeHandle<JSArray> Runtime::GetInternalProperties(Isolate* isolate, Handle<String> status_str = factory->NewStringFromAsciiChecked(status); result->set(1, *status_str); - Handle<Object> value_obj = - DebugGetProperty(promise, isolate->factory()->promise_result_symbol()); + Handle<Object> value_obj(promise->result(), isolate); Handle<String> promise_value = factory->NewStringFromAsciiChecked("[[PromiseValue]]"); result->set(2, *promise_value); @@ -315,7 +290,7 @@ MaybeHandle<JSArray> Runtime::GetInternalProperties(Isolate* isolate, RUNTIME_FUNCTION(Runtime_DebugGetInternalProperties) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); RETURN_RESULT_OR_FAILURE(isolate, Runtime::GetInternalProperties(isolate, obj)); @@ -407,7 +382,7 @@ RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) { RUNTIME_FUNCTION(Runtime_DebugGetProperty) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); @@ -416,14 +391,13 @@ RUNTIME_FUNCTION(Runtime_DebugGetProperty) { return *DebugGetProperty(&it); } - -// Return the property type calculated from the property details. +// Return the property kind calculated from the property details. // args[0]: smi with property details. -RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) { +RUNTIME_FUNCTION(Runtime_DebugPropertyKindFromDetails) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_PROPERTY_DETAILS_CHECKED(details, 0); - return Smi::FromInt(static_cast<int>(details.type())); + return Smi::FromInt(static_cast<int>(details.kind())); } @@ -431,7 +405,7 @@ RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) { // args[0]: smi with property details. RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_PROPERTY_DETAILS_CHECKED(details, 0); return Smi::FromInt(static_cast<int>(details.attributes())); } @@ -439,7 +413,7 @@ RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) { RUNTIME_FUNCTION(Runtime_CheckExecutionState) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); CHECK(isolate->debug()->CheckExecutionState(break_id)); return isolate->heap()->true_value(); @@ -448,7 +422,7 @@ RUNTIME_FUNCTION(Runtime_CheckExecutionState) { RUNTIME_FUNCTION(Runtime_GetFrameCount) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); CHECK(isolate->debug()->CheckExecutionState(break_id)); @@ -460,22 +434,18 @@ RUNTIME_FUNCTION(Runtime_GetFrameCount) { return Smi::kZero; } + List<FrameSummary> frames(FLAG_max_inlining_levels + 1); for (StackTraceFrameIterator it(isolate, id); !it.done(); it.Advance()) { - List<FrameSummary> frames(FLAG_max_inlining_levels + 1); - if (it.is_wasm()) { - n++; - } else { - it.javascript_frame()->Summarize(&frames); - for (int i = frames.length() - 1; i >= 0; i--) { - // Omit functions from native and extension scripts. - if (frames[i].function()->shared()->IsSubjectToDebugging()) n++; - } + frames.Clear(); + it.frame()->Summarize(&frames); + for (int i = frames.length() - 1; i >= 0; i--) { + // Omit functions from native and extension scripts. + if (frames[i].is_subject_to_debugging()) n++; } } return Smi::FromInt(n); } - static const int kFrameDetailsFrameIdIndex = 0; static const int kFrameDetailsReceiverIndex = 1; static const int kFrameDetailsFunctionIndex = 2; @@ -508,7 +478,7 @@ static const int kFrameDetailsFirstDynamicIndex = 10; // Return value if any RUNTIME_FUNCTION(Runtime_GetFrameDetails) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); CHECK(isolate->debug()->CheckExecutionState(break_id)); @@ -524,11 +494,11 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { StackTraceFrameIterator it(isolate, id); // Inlined frame index in optimized frame, starting from outer function. - int inlined_jsframe_index = + int inlined_frame_index = DebugFrameHelper::FindIndexedNonNativeFrame(&it, index); - if (inlined_jsframe_index == -1) return heap->undefined_value(); + if (inlined_frame_index == -1) return heap->undefined_value(); - FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate); + FrameInspector frame_inspector(it.frame(), inlined_frame_index, isolate); // Traverse the saved contexts chain to find the active context for the // selected frame. @@ -539,10 +509,7 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { Handle<Object> frame_id(DebugFrameHelper::WrapFrameId(it.frame()->id()), isolate); - // Find source position in unoptimized code. - int position = frame_inspector.GetSourcePosition(); - - if (it.is_wasm()) { + if (frame_inspector.summary().IsWasm()) { // Create the details array (no dynamic information for wasm). Handle<FixedArray> details = isolate->factory()->NewFixedArray(kFrameDetailsFirstDynamicIndex); @@ -551,10 +518,7 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { details->set(kFrameDetailsFrameIdIndex, *frame_id); // Add the function name. - Handle<Object> wasm_instance(it.wasm_frame()->wasm_instance(), isolate); - int func_index = it.wasm_frame()->function_index(); - Handle<String> func_name = - wasm::GetWasmFunctionName(isolate, wasm_instance, func_index); + Handle<String> func_name = frame_inspector.summary().FunctionName(); details->set(kFrameDetailsFunctionIndex, *func_name); // Add the script wrapper @@ -569,21 +533,8 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { details->set(kFrameDetailsLocalCountIndex, Smi::kZero); // Add the source position. - // For wasm, it is function-local, so translate it to a module-relative - // position, such that together with the script it uniquely identifies the - // position. - Handle<Object> positionValue; - if (position != kNoSourcePosition) { - int translated_position = position; - if (!wasm::WasmIsAsmJs(*wasm_instance, isolate)) { - Handle<WasmCompiledModule> compiled_module( - wasm::GetCompiledModule(JSObject::cast(*wasm_instance)), isolate); - translated_position += - wasm::GetFunctionCodeOffset(compiled_module, func_index); - } - details->set(kFrameDetailsSourcePositionIndex, - Smi::FromInt(translated_position)); - } + int position = frame_inspector.summary().SourcePosition(); + details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position)); // Add the constructor information. details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(false)); @@ -604,6 +555,9 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { return *isolate->factory()->NewJSArrayWithElements(details); } + // Find source position in unoptimized code. + int position = frame_inspector.GetSourcePosition(); + // Handle JavaScript frames. bool is_optimized = it.frame()->is_optimized(); @@ -685,7 +639,7 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { // the provided parameters whereas the function frame always have the number // of arguments matching the functions parameters. The rest of the // information (except for what is collected above) is the same. - if ((inlined_jsframe_index == 0) && + if ((inlined_frame_index == 0) && it.javascript_frame()->has_adapted_arguments()) { it.AdvanceToArgumentsFrame(); frame_inspector.SetArgumentsFrame(it.frame()); @@ -743,7 +697,7 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { } if (is_optimized) { flags |= 1 << 1; - flags |= inlined_jsframe_index << 2; + flags |= inlined_frame_index << 2; } details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags)); @@ -778,7 +732,7 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { // Add the receiver (same as in function frame). Handle<Object> receiver(it.frame()->receiver(), isolate); - DCHECK(!function->shared()->IsBuiltin()); + DCHECK(function->shared()->IsUserJavaScript()); DCHECK_IMPLIES(is_sloppy(shared->language_mode()), receiver->IsJSReceiver()); details->set(kFrameDetailsReceiverIndex, *receiver); @@ -789,7 +743,7 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { RUNTIME_FUNCTION(Runtime_GetScopeCount) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); CHECK(isolate->debug()->CheckExecutionState(break_id)); @@ -822,7 +776,7 @@ RUNTIME_FUNCTION(Runtime_GetScopeCount) { // 1: Scope object RUNTIME_FUNCTION(Runtime_GetScopeDetails) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); CHECK(isolate->debug()->CheckExecutionState(break_id)); @@ -918,7 +872,7 @@ RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) { RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); // Check arguments. CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); @@ -957,7 +911,7 @@ RUNTIME_FUNCTION(Runtime_GetGeneratorScopeCount) { RUNTIME_FUNCTION(Runtime_GetGeneratorScopeDetails) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); if (!args[0]->IsJSGeneratorObject()) { return isolate->heap()->undefined_value(); @@ -1004,7 +958,7 @@ static bool SetScopeVariableValue(ScopeIterator* it, int index, // Return true if success and false otherwise RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) { HandleScope scope(isolate); - DCHECK(args.length() == 6); + DCHECK_EQ(6, args.length()); // Check arguments. CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]); @@ -1043,7 +997,7 @@ RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) { RUNTIME_FUNCTION(Runtime_DebugPrintScopes) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); #ifdef DEBUG // Print the scopes for the top frame. @@ -1063,7 +1017,7 @@ RUNTIME_FUNCTION(Runtime_DebugPrintScopes) { // args[0]: disable break state RUNTIME_FUNCTION(Runtime_SetBreakPointsActive) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_BOOLEAN_ARG_CHECKED(active, 0); isolate->debug()->set_break_points_active(active); return isolate->heap()->undefined_value(); @@ -1077,7 +1031,7 @@ static bool IsPositionAlignmentCodeCorrect(int alignment) { RUNTIME_FUNCTION(Runtime_GetBreakLocations) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CHECK(isolate->debug()->is_active()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]); @@ -1107,7 +1061,7 @@ RUNTIME_FUNCTION(Runtime_GetBreakLocations) { // args[2]: number: break point object RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CHECK(isolate->debug()->is_active()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); @@ -1132,7 +1086,7 @@ RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) { // args[3]: number: break point object RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CHECK(isolate->debug()->is_active()); CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0); CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); @@ -1164,7 +1118,7 @@ RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) { // args[0]: number: break point object RUNTIME_FUNCTION(Runtime_ClearBreakPoint) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CHECK(isolate->debug()->is_active()); CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0); @@ -1180,7 +1134,7 @@ RUNTIME_FUNCTION(Runtime_ClearBreakPoint) { // args[1]: Boolean indicating on/off. RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]); CONVERT_BOOLEAN_ARG_CHECKED(enable, 1); @@ -1197,7 +1151,7 @@ RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) { // args[0]: boolean indicating uncaught exceptions RUNTIME_FUNCTION(Runtime_IsBreakOnException) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]); ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg); @@ -1213,7 +1167,7 @@ RUNTIME_FUNCTION(Runtime_IsBreakOnException) { // of frames to step down. RUNTIME_FUNCTION(Runtime_PrepareStep) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); CHECK(isolate->debug()->CheckExecutionState(break_id)); @@ -1236,11 +1190,23 @@ RUNTIME_FUNCTION(Runtime_PrepareStep) { return isolate->heap()->undefined_value(); } +RUNTIME_FUNCTION(Runtime_PrepareStepFrame) { + HandleScope scope(isolate); + DCHECK_EQ(0, args.length()); + CHECK(isolate->debug()->CheckExecutionState()); + + // Clear all current stepping setup. + isolate->debug()->ClearStepping(); + + // Prepare step. + isolate->debug()->PrepareStep(StepFrame); + return isolate->heap()->undefined_value(); +} // Clear all stepping set by PrepareStep. RUNTIME_FUNCTION(Runtime_ClearStepping) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); CHECK(isolate->debug()->is_active()); isolate->debug()->ClearStepping(); return isolate->heap()->undefined_value(); @@ -1252,21 +1218,19 @@ RUNTIME_FUNCTION(Runtime_DebugEvaluate) { // Check the execution state and decode arguments frame and source to be // evaluated. - DCHECK(args.length() == 6); + DCHECK_EQ(4, args.length()); CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); CHECK(isolate->debug()->CheckExecutionState(break_id)); CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]); CONVERT_ARG_HANDLE_CHECKED(String, source, 3); - CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4); - CONVERT_ARG_HANDLE_CHECKED(HeapObject, context_extension, 5); StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id); RETURN_RESULT_OR_FAILURE( - isolate, DebugEvaluate::Local(isolate, id, inlined_jsframe_index, source, - disable_break, context_extension)); + isolate, + DebugEvaluate::Local(isolate, id, inlined_jsframe_index, source)); } @@ -1275,23 +1239,19 @@ RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) { // Check the execution state and decode arguments frame and source to be // evaluated. - DCHECK(args.length() == 4); + DCHECK_EQ(2, args.length()); CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); CHECK(isolate->debug()->CheckExecutionState(break_id)); CONVERT_ARG_HANDLE_CHECKED(String, source, 1); - CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2); - CONVERT_ARG_HANDLE_CHECKED(HeapObject, context_extension, 3); - RETURN_RESULT_OR_FAILURE( - isolate, - DebugEvaluate::Global(isolate, source, disable_break, context_extension)); + RETURN_RESULT_OR_FAILURE(isolate, DebugEvaluate::Global(isolate, source)); } RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); // This runtime function is used by the debugger to determine whether the // debugger is active or not. Hence we fail gracefully here and don't crash. @@ -1342,7 +1302,7 @@ static bool HasInPrototypeChainIgnoringProxies(Isolate* isolate, // args[2]: the the maximum number of objects to return RUNTIME_FUNCTION(Runtime_DebugReferencedBy) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0); CONVERT_ARG_HANDLE_CHECKED(Object, filter, 1); CHECK(filter->IsUndefined(isolate) || filter->IsJSObject()); @@ -1399,7 +1359,7 @@ RUNTIME_FUNCTION(Runtime_DebugReferencedBy) { // args[1]: the the maximum number of objects to return RUNTIME_FUNCTION(Runtime_DebugConstructedBy) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0); CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); CHECK(max_references >= 0); @@ -1432,7 +1392,7 @@ RUNTIME_FUNCTION(Runtime_DebugConstructedBy) { // args[0]: the object to find the prototype for. RUNTIME_FUNCTION(Runtime_DebugGetPrototype) { HandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); // TODO(1543): Come up with a solution for clients to handle potential errors // thrown by an intermediate proxy. @@ -1444,7 +1404,7 @@ RUNTIME_FUNCTION(Runtime_DebugGetPrototype) { // TODO(5530): Remove once uses in debug.js are gone. RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0); CONVERT_ARG_HANDLE_CHECKED(String, source, 1); @@ -1497,7 +1457,7 @@ RUNTIME_FUNCTION(Runtime_FunctionGetDebugName) { // to have a stack with C++ frame in the middle. RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); DebugScope debug_scope(isolate->debug()); @@ -1514,7 +1474,7 @@ RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) { RUNTIME_FUNCTION(Runtime_GetDebugContext) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); Handle<Context> context; { DebugScope debug_scope(isolate->debug()); @@ -1534,7 +1494,7 @@ RUNTIME_FUNCTION(Runtime_GetDebugContext) { // Presently, it only does a full GC. RUNTIME_FUNCTION(Runtime_CollectGarbage) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, GarbageCollectionReason::kRuntime); return isolate->heap()->undefined_value(); @@ -1544,7 +1504,7 @@ RUNTIME_FUNCTION(Runtime_CollectGarbage) { // Gets the current heap usage. RUNTIME_FUNCTION(Runtime_GetHeapUsage) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); int usage = static_cast<int>(isolate->heap()->SizeOfObjects()); if (!Smi::IsValid(usage)) { return *isolate->factory()->NewNumberFromInt(usage); @@ -1561,7 +1521,7 @@ RUNTIME_FUNCTION(Runtime_GetHeapUsage) { // some kind of user interaction the performance is not crucial. RUNTIME_FUNCTION(Runtime_GetScript) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, script_name, 0); Handle<Script> found; @@ -1585,55 +1545,75 @@ RUNTIME_FUNCTION(Runtime_GetScript) { // TODO(5530): Remove once uses in debug.js are gone. RUNTIME_FUNCTION(Runtime_ScriptLineCount) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(JSValue, script, 0); CHECK(script->value()->IsScript()); Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); + if (script_handle->type() == Script::TYPE_WASM) { + // Return 0 for now; this function will disappear soon anyway. + return Smi::FromInt(0); + } + Script::InitLineEnds(script_handle); FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); return Smi::FromInt(line_ends_array->length()); } +namespace { + +int ScriptLinePosition(Handle<Script> script, int line) { + if (line < 0) return -1; + + if (script->type() == Script::TYPE_WASM) { + return WasmCompiledModule::cast(script->wasm_compiled_module()) + ->GetFunctionOffset(line); + } + + Script::InitLineEnds(script); + + FixedArray* line_ends_array = FixedArray::cast(script->line_ends()); + const int line_count = line_ends_array->length(); + DCHECK_LT(0, line_count); + + if (line == 0) return 0; + // If line == line_count, we return the first position beyond the last line. + if (line > line_count) return -1; + return Smi::cast(line_ends_array->get(line - 1))->value() + 1; +} + +} // namespace + // TODO(5530): Remove once uses in debug.js are gone. RUNTIME_FUNCTION(Runtime_ScriptLineStartPosition) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_CHECKED(JSValue, script, 0); CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]); CHECK(script->value()->IsScript()); Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); - Script::InitLineEnds(script_handle); - - FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); - const int line_count = line_ends_array->length(); - - // If line == line_count, we return the first position beyond the last line. - if (line < 0 || line > line_count) { - return Smi::FromInt(-1); - } else if (line == 0) { - return Smi::kZero; - } else { - DCHECK(0 < line && line <= line_count); - const int pos = Smi::cast(line_ends_array->get(line - 1))->value() + 1; - return Smi::FromInt(pos); - } + return Smi::FromInt(ScriptLinePosition(script_handle, line)); } // TODO(5530): Remove once uses in debug.js are gone. RUNTIME_FUNCTION(Runtime_ScriptLineEndPosition) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_CHECKED(JSValue, script, 0); CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]); CHECK(script->value()->IsScript()); Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); + if (script_handle->type() == Script::TYPE_WASM) { + // Return zero for now; this function will disappear soon anyway. + return Smi::FromInt(0); + } + Script::InitLineEnds(script_handle); FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); @@ -1679,6 +1659,20 @@ static Handle<Object> GetJSPositionInfo(Handle<Script> script, int position, namespace { +int ScriptLinePositionWithOffset(Handle<Script> script, int line, int offset) { + if (line < 0 || offset < 0) return -1; + + if (line == 0) return ScriptLinePosition(script, line) + offset; + + Script::PositionInfo info; + if (!Script::GetPositionInfo(script, offset, &info, Script::NO_OFFSET)) { + return -1; + } + + const int total_line = info.line + line; + return ScriptLinePosition(script, total_line); +} + Handle<Object> ScriptLocationFromLine(Isolate* isolate, Handle<Script> script, Handle<Object> opt_line, Handle<Object> opt_column, @@ -1686,51 +1680,24 @@ Handle<Object> ScriptLocationFromLine(Isolate* isolate, Handle<Script> script, // Line and column are possibly undefined and we need to handle these cases, // additionally subtracting corresponding offsets. - int32_t line; - if (opt_line->IsNull(isolate) || opt_line->IsUndefined(isolate)) { - line = 0; - } else { + int32_t line = 0; + if (!opt_line->IsNullOrUndefined(isolate)) { CHECK(opt_line->IsNumber()); line = NumberToInt32(*opt_line) - script->line_offset(); } - int32_t column; - if (opt_column->IsNull(isolate) || opt_column->IsUndefined(isolate)) { - column = 0; - } else { + int32_t column = 0; + if (!opt_column->IsNullOrUndefined(isolate)) { CHECK(opt_column->IsNumber()); column = NumberToInt32(*opt_column); if (line == 0) column -= script->column_offset(); } - if (line < 0 || column < 0 || offset < 0) { - return isolate->factory()->null_value(); - } - - Script::InitLineEnds(script); - - FixedArray* line_ends_array = FixedArray::cast(script->line_ends()); - const int line_count = line_ends_array->length(); - - int position; - if (line == 0) { - position = offset + column; - } else { - Script::PositionInfo info; - if (!Script::GetPositionInfo(script, offset, &info, Script::NO_OFFSET) || - info.line + line >= line_count) { - return isolate->factory()->null_value(); - } + int line_position = ScriptLinePositionWithOffset(script, line, offset); + if (line_position < 0 || column < 0) return isolate->factory()->null_value(); - const int offset_line = info.line + line; - const int offset_line_position = - (offset_line == 0) - ? 0 - : Smi::cast(line_ends_array->get(offset_line - 1))->value() + 1; - position = offset_line_position + column; - } - - return GetJSPositionInfo(script, position, Script::NO_OFFSET, isolate); + return GetJSPositionInfo(script, line_position + column, Script::NO_OFFSET, + isolate); } // Slow traversal over all scripts on the heap. @@ -1760,7 +1727,7 @@ bool GetScriptById(Isolate* isolate, int needle, Handle<Script>* result) { // TODO(5530): Remove once uses in debug.js are gone. RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSValue, script, 0); CONVERT_ARG_HANDLE_CHECKED(Object, opt_line, 1); CONVERT_ARG_HANDLE_CHECKED(Object, opt_column, 2); @@ -1776,7 +1743,7 @@ RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine) { // TODO(5530): Rename once conflicting function has been deleted. RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine2) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_NUMBER_CHECKED(int32_t, scriptid, Int32, args[0]); CONVERT_ARG_HANDLE_CHECKED(Object, opt_line, 1); CONVERT_ARG_HANDLE_CHECKED(Object, opt_column, 2); @@ -1791,7 +1758,7 @@ RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine2) { // TODO(5530): Remove once uses in debug.js are gone. RUNTIME_FUNCTION(Runtime_ScriptPositionInfo) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_CHECKED(JSValue, script, 0); CONVERT_NUMBER_CHECKED(int32_t, position, Int32, args[1]); CONVERT_BOOLEAN_ARG_CHECKED(with_offset, 2); @@ -1804,18 +1771,39 @@ RUNTIME_FUNCTION(Runtime_ScriptPositionInfo) { return *GetJSPositionInfo(script_handle, position, offset_flag, isolate); } +// TODO(5530): Rename once conflicting function has been deleted. +RUNTIME_FUNCTION(Runtime_ScriptPositionInfo2) { + HandleScope scope(isolate); + DCHECK_EQ(3, args.length()); + CONVERT_NUMBER_CHECKED(int32_t, scriptid, Int32, args[0]); + CONVERT_NUMBER_CHECKED(int32_t, position, Int32, args[1]); + CONVERT_BOOLEAN_ARG_CHECKED(with_offset, 2); + + Handle<Script> script; + CHECK(GetScriptById(isolate, scriptid, &script)); + + const Script::OffsetFlag offset_flag = + with_offset ? Script::WITH_OFFSET : Script::NO_OFFSET; + return *GetJSPositionInfo(script, position, offset_flag, isolate); +} + // Returns the given line as a string, or null if line is out of bounds. // The parameter line is expected to include the script's line offset. // TODO(5530): Remove once uses in debug.js are gone. RUNTIME_FUNCTION(Runtime_ScriptSourceLine) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_CHECKED(JSValue, script, 0); CONVERT_NUMBER_CHECKED(int32_t, line, Int32, args[1]); CHECK(script->value()->IsScript()); Handle<Script> script_handle = Handle<Script>(Script::cast(script->value())); + if (script_handle->type() == Script::TYPE_WASM) { + // Return null for now; this function will disappear soon anyway. + return isolate->heap()->null_value(); + } + Script::InitLineEnds(script_handle); FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends()); @@ -1837,14 +1825,19 @@ RUNTIME_FUNCTION(Runtime_ScriptSourceLine) { return *str; } -// Set one shot breakpoints for the callback function that is passed to a -// built-in function such as Array.forEach to enable stepping into the callback, -// if we are indeed stepping and the callback is subject to debugging. -RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) { +// On function call, depending on circumstances, prepare for stepping in, +// or perform a side effect check. +RUNTIME_FUNCTION(Runtime_DebugOnFunctionCall) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); - isolate->debug()->PrepareStepIn(fun); + if (isolate->debug()->last_step_action() >= StepIn) { + isolate->debug()->PrepareStepIn(fun); + } + if (isolate->needs_side_effect_check() && + !isolate->debug()->PerformSideEffectCheck(fun)) { + return isolate->heap()->exception(); + } return isolate->heap()->undefined_value(); } @@ -1856,17 +1849,17 @@ RUNTIME_FUNCTION(Runtime_DebugPrepareStepInSuspendedGenerator) { return isolate->heap()->undefined_value(); } -RUNTIME_FUNCTION(Runtime_DebugRecordAsyncFunction) { +RUNTIME_FUNCTION(Runtime_DebugRecordGenerator) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); CHECK(isolate->debug()->last_step_action() >= StepNext); - isolate->debug()->RecordAsyncFunction(generator); + isolate->debug()->RecordGenerator(generator); return isolate->heap()->undefined_value(); } RUNTIME_FUNCTION(Runtime_DebugPushPromise) { - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); HandleScope scope(isolate); CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); isolate->PushPromise(promise); @@ -1875,28 +1868,57 @@ RUNTIME_FUNCTION(Runtime_DebugPushPromise) { RUNTIME_FUNCTION(Runtime_DebugPopPromise) { - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); SealHandleScope shs(isolate); isolate->PopPromise(); return isolate->heap()->undefined_value(); } -RUNTIME_FUNCTION(Runtime_DebugNextMicrotaskId) { +RUNTIME_FUNCTION(Runtime_DebugNextAsyncTaskId) { HandleScope scope(isolate); - DCHECK(args.length() == 0); - return Smi::FromInt(isolate->GetNextDebugMicrotaskId()); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); + return Smi::FromInt(isolate->debug()->NextAsyncTaskId(promise)); } -RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) { - DCHECK(args.length() == 3); +RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionPromiseCreated) { + DCHECK_EQ(1, args.length()); HandleScope scope(isolate); - CONVERT_ARG_HANDLE_CHECKED(String, type, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, id, 1); - CONVERT_ARG_HANDLE_CHECKED(String, name, 2); - isolate->debug()->OnAsyncTaskEvent(type, id, name); + CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); + isolate->PushPromise(promise); + int id = isolate->debug()->NextAsyncTaskId(promise); + Handle<Symbol> async_stack_id_symbol = + isolate->factory()->promise_async_stack_id_symbol(); + JSObject::SetProperty(promise, async_stack_id_symbol, + handle(Smi::FromInt(id), isolate), STRICT) + .Assert(); + isolate->debug()->OnAsyncTaskEvent(debug::kDebugEnqueueAsyncFunction, id); return isolate->heap()->undefined_value(); } +RUNTIME_FUNCTION(Runtime_DebugPromiseReject) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSPromise, rejected_promise, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); + + isolate->debug()->OnPromiseReject(rejected_promise, value); + return isolate->heap()->undefined_value(); +} + +RUNTIME_FUNCTION(Runtime_DebugAsyncEventEnqueueRecurring) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); + CONVERT_SMI_ARG_CHECKED(status, 1); + if (isolate->debug()->is_active()) { + isolate->debug()->OnAsyncTaskEvent( + status == v8::Promise::kFulfilled ? debug::kDebugEnqueuePromiseResolve + : debug::kDebugEnqueuePromiseReject, + isolate->debug()->NextAsyncTaskId(promise)); + } + return isolate->heap()->undefined_value(); +} RUNTIME_FUNCTION(Runtime_DebugIsActive) { SealHandleScope shs(isolate); diff --git a/deps/v8/src/runtime/runtime-error.cc b/deps/v8/src/runtime/runtime-error.cc index 3a9b192029..6ded550d04 100644 --- a/deps/v8/src/runtime/runtime-error.cc +++ b/deps/v8/src/runtime/runtime-error.cc @@ -15,7 +15,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_ErrorToString) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, recv, 0); RETURN_RESULT_OR_FAILURE(isolate, ErrorUtils::ToString(isolate, recv)); } diff --git a/deps/v8/src/runtime/runtime-function.cc b/deps/v8/src/runtime/runtime-function.cc index a91ab28cc6..31da4a4535 100644 --- a/deps/v8/src/runtime/runtime-function.cc +++ b/deps/v8/src/runtime/runtime-function.cc @@ -17,7 +17,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_FunctionGetName) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0); if (function->IsJSBoundFunction()) { @@ -32,7 +32,7 @@ RUNTIME_FUNCTION(Runtime_FunctionGetName) { RUNTIME_FUNCTION(Runtime_FunctionSetName) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0); CONVERT_ARG_HANDLE_CHECKED(String, name, 1); @@ -45,7 +45,7 @@ RUNTIME_FUNCTION(Runtime_FunctionSetName) { RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(JSFunction, f, 0); CHECK(f->RemovePrototype()); @@ -99,7 +99,7 @@ RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) { RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(JSFunction, fun, 0); int pos = fun->shared()->start_position(); @@ -108,7 +108,7 @@ RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) { RUNTIME_FUNCTION(Runtime_FunctionGetContextData) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(JSFunction, fun, 0); FixedArray* array = fun->native_context()->embedder_data(); @@ -117,7 +117,7 @@ RUNTIME_FUNCTION(Runtime_FunctionGetContextData) { RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) { SealHandleScope shs(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_CHECKED(JSFunction, fun, 0); CONVERT_ARG_CHECKED(String, name, 1); @@ -128,7 +128,7 @@ RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) { RUNTIME_FUNCTION(Runtime_FunctionSetLength) { SealHandleScope shs(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_CHECKED(JSFunction, fun, 0); CONVERT_SMI_ARG_CHECKED(length, 1); @@ -140,7 +140,7 @@ RUNTIME_FUNCTION(Runtime_FunctionSetLength) { RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); @@ -153,7 +153,7 @@ RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) { RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(JSFunction, f, 0); return isolate->heap()->ToBoolean(f->shared()->IsApiFunction()); @@ -162,7 +162,7 @@ RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) { RUNTIME_FUNCTION(Runtime_SetCode) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0); CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1); @@ -203,8 +203,14 @@ RUNTIME_FUNCTION(Runtime_SetCode) { source_shared->opt_count_and_bailout_reason()); target_shared->set_native(was_native); target_shared->set_profiler_ticks(source_shared->profiler_ticks()); - SharedFunctionInfo::SetScript( - target_shared, Handle<Object>(source_shared->script(), isolate)); + target_shared->set_function_literal_id(source_shared->function_literal_id()); + + Handle<Object> source_script(source_shared->script(), isolate); + if (source_script->IsScript()) { + SharedFunctionInfo::SetScript(source_shared, + isolate->factory()->undefined_value()); + } + SharedFunctionInfo::SetScript(target_shared, source_script); // Set the code of the target function. target->ReplaceCode(source_shared->code()); @@ -254,10 +260,10 @@ RUNTIME_FUNCTION(Runtime_IsConstructor) { RUNTIME_FUNCTION(Runtime_SetForceInlineFlag) { SealHandleScope shs(isolate); DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); + CONVERT_ARG_CHECKED(Object, object, 0); if (object->IsJSFunction()) { - JSFunction* func = JSFunction::cast(*object); + JSFunction* func = JSFunction::cast(object); func->shared()->set_force_inline(true); } return isolate->heap()->undefined_value(); @@ -272,7 +278,7 @@ RUNTIME_FUNCTION(Runtime_Call) { CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1); ScopedVector<Handle<Object>> argv(argc); for (int i = 0; i < argc; ++i) { - argv[i] = args.at<Object>(2 + i); + argv[i] = args.at(2 + i); } RETURN_RESULT_OR_FAILURE( isolate, Execution::Call(isolate, target, receiver, argc, argv.start())); @@ -282,7 +288,7 @@ RUNTIME_FUNCTION(Runtime_Call) { // ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee. RUNTIME_FUNCTION(Runtime_ConvertReceiver) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); return *Object::ConvertReceiver(isolate, receiver).ToHandleChecked(); } diff --git a/deps/v8/src/runtime/runtime-futex.cc b/deps/v8/src/runtime/runtime-futex.cc index a93bb23645..4af0831acf 100644 --- a/deps/v8/src/runtime/runtime-futex.cc +++ b/deps/v8/src/runtime/runtime-futex.cc @@ -19,7 +19,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_AtomicsWait) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); CONVERT_INT32_ARG_CHECKED(value, 2); @@ -37,7 +37,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsWait) { RUNTIME_FUNCTION(Runtime_AtomicsWake) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); CONVERT_INT32_ARG_CHECKED(count, 2); @@ -53,7 +53,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsWake) { RUNTIME_FUNCTION(Runtime_AtomicsNumWaitersForTesting) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); CHECK(sta->GetBuffer()->is_shared()); diff --git a/deps/v8/src/runtime/runtime-generator.cc b/deps/v8/src/runtime/runtime-generator.cc index bb63a3d0d0..96486736e1 100644 --- a/deps/v8/src/runtime/runtime-generator.cc +++ b/deps/v8/src/runtime/runtime-generator.cc @@ -5,7 +5,6 @@ #include "src/runtime/runtime-utils.h" #include "src/arguments.h" -#include "src/debug/debug.h" #include "src/factory.h" #include "src/frames-inl.h" #include "src/objects-inl.h" @@ -15,76 +14,30 @@ namespace internal { RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1); CHECK(IsResumableFunction(function->shared()->kind())); - Handle<FixedArray> operand_stack; - if (function->shared()->HasBytecodeArray()) { - // New-style generators. - DCHECK(!function->shared()->HasBaselineCode()); - int size = function->shared()->bytecode_array()->register_count(); - operand_stack = isolate->factory()->NewFixedArray(size); - } else { - // Old-style generators. - DCHECK(function->shared()->HasBaselineCode()); - operand_stack = isolate->factory()->empty_fixed_array(); - } + // Underlying function needs to have bytecode available. + DCHECK(function->shared()->HasBytecodeArray()); + DCHECK(!function->shared()->HasBaselineCode()); + int size = function->shared()->bytecode_array()->register_count(); + Handle<FixedArray> register_file = isolate->factory()->NewFixedArray(size); Handle<JSGeneratorObject> generator = isolate->factory()->NewJSGeneratorObject(function); generator->set_function(*function); generator->set_context(isolate->context()); generator->set_receiver(*receiver); - generator->set_operand_stack(*operand_stack); + generator->set_register_file(*register_file); generator->set_continuation(JSGeneratorObject::kGeneratorExecuting); return *generator; } -RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) { - HandleScope handle_scope(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0); - - JavaScriptFrameIterator stack_iterator(isolate); - JavaScriptFrame* frame = stack_iterator.frame(); - CHECK(IsResumableFunction(frame->function()->shared()->kind())); - DCHECK_EQ(frame->function(), generator_object->function()); - DCHECK(frame->function()->shared()->is_compiled()); - DCHECK(!frame->function()->IsOptimized()); - - isolate->debug()->RecordAsyncFunction(generator_object); - - // The caller should have saved the context and continuation already. - DCHECK_EQ(generator_object->context(), Context::cast(frame->context())); - DCHECK_LT(0, generator_object->continuation()); - - // We expect there to be at least two values on the operand stack: the return - // value of the yield expression, and the arguments to this runtime call. - // Neither of those should be saved. - int operands_count = frame->ComputeOperandsCount(); - DCHECK_GE(operands_count, 1 + args.length()); - operands_count -= 1 + args.length(); - - if (operands_count == 0) { - // Although it's semantically harmless to call this function with an - // operands_count of zero, it is also unnecessary. - DCHECK_EQ(generator_object->operand_stack(), - isolate->heap()->empty_fixed_array()); - } else { - Handle<FixedArray> operand_stack = - isolate->factory()->NewFixedArray(operands_count); - frame->SaveOperandStack(*operand_stack); - generator_object->set_operand_stack(*operand_stack); - } - - return isolate->heap()->undefined_value(); -} - RUNTIME_FUNCTION(Runtime_GeneratorClose) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); generator->set_continuation(JSGeneratorObject::kGeneratorClosed); @@ -94,7 +47,7 @@ RUNTIME_FUNCTION(Runtime_GeneratorClose) { RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); return generator->function(); @@ -102,15 +55,23 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) { RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); return generator->receiver(); } +RUNTIME_FUNCTION(Runtime_GeneratorGetContext) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); + + return generator->context(); +} + RUNTIME_FUNCTION(Runtime_GeneratorGetInputOrDebugPos) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); return generator->input_or_debug_pos(); @@ -118,7 +79,7 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetInputOrDebugPos) { RUNTIME_FUNCTION(Runtime_GeneratorGetResumeMode) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); return Smi::FromInt(generator->resume_mode()); @@ -126,7 +87,7 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetResumeMode) { RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); return Smi::FromInt(generator->continuation()); @@ -134,7 +95,7 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) { RUNTIME_FUNCTION(Runtime_GeneratorGetSourcePosition) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); if (!generator->is_suspended()) return isolate->heap()->undefined_value(); diff --git a/deps/v8/src/runtime/runtime-i18n.cc b/deps/v8/src/runtime/runtime-i18n.cc index 75e0952581..6630fadc10 100644 --- a/deps/v8/src/runtime/runtime-i18n.cc +++ b/deps/v8/src/runtime/runtime-i18n.cc @@ -8,13 +8,15 @@ #include <memory> -#include "src/api.h" #include "src/api-natives.h" +#include "src/api.h" #include "src/arguments.h" #include "src/factory.h" #include "src/i18n.h" #include "src/isolate-inl.h" #include "src/messages.h" +#include "src/string-case.h" +#include "src/utils.h" #include "unicode/brkiter.h" #include "unicode/calendar.h" @@ -70,7 +72,7 @@ RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) { HandleScope scope(isolate); Factory* factory = isolate->factory(); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0); v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str)); @@ -107,7 +109,7 @@ RUNTIME_FUNCTION(Runtime_AvailableLocalesOf) { HandleScope scope(isolate); Factory* factory = isolate->factory(); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, service, 0); const icu::Locale* available_locales = NULL; @@ -152,7 +154,7 @@ RUNTIME_FUNCTION(Runtime_GetDefaultICULocale) { HandleScope scope(isolate); Factory* factory = isolate->factory(); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); icu::Locale default_locale; @@ -173,7 +175,7 @@ RUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) { HandleScope scope(isolate); Factory* factory = isolate->factory(); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0); @@ -257,7 +259,7 @@ RUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) { RUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, input, 0); @@ -273,7 +275,7 @@ RUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) { RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, input, 0); CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1); @@ -291,63 +293,33 @@ RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) { RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0); CONVERT_ARG_HANDLE_CHECKED(String, type, 1); - CONVERT_ARG_HANDLE_CHECKED(JSObject, impl, 2); Handle<Symbol> marker = isolate->factory()->intl_initialized_marker_symbol(); JSObject::SetProperty(input, marker, type, STRICT).Assert(); - marker = isolate->factory()->intl_impl_object_symbol(); - JSObject::SetProperty(input, marker, impl, STRICT).Assert(); - return isolate->heap()->undefined_value(); } -RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) { - HandleScope scope(isolate); - - DCHECK(args.length() == 1); - - CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0); - - if (!input->IsJSObject()) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kNotIntlObject, input)); - } - - Handle<JSObject> obj = Handle<JSObject>::cast(input); - - Handle<Symbol> marker = isolate->factory()->intl_impl_object_symbol(); - - Handle<Object> impl = JSReceiver::GetDataProperty(obj, marker); - if (!impl->IsJSObject()) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kNotIntlObject, obj)); - } - return *impl; -} - - RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); - Handle<ObjectTemplateInfo> date_format_template = I18N::GetTemplate(isolate); + Handle<JSFunction> constructor( + isolate->native_context()->intl_date_time_format_function()); - // Create an empty object wrapper. Handle<JSObject> local_object; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, local_object, - ApiNatives::InstantiateObject(date_format_template)); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, local_object, + JSObject::New(constructor, constructor)); // Set date time formatter as internal field of the resulting JS object. icu::SimpleDateFormat* date_format = @@ -357,11 +329,6 @@ RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) { local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format)); - Factory* factory = isolate->factory(); - Handle<String> key = factory->NewStringFromStaticChars("dateFormat"); - Handle<String> value = factory->NewStringFromStaticChars("valid"); - JSObject::AddProperty(local_object, key, value, NONE); - // Make object handle weak so we can delete the data format once GC kicks in. Handle<Object> wrapper = isolate->global_handles()->Create(*local_object); GlobalHandles::MakeWeak(wrapper.location(), wrapper.location(), @@ -374,7 +341,7 @@ RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) { RUNTIME_FUNCTION(Runtime_InternalDateFormat) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1); @@ -384,7 +351,7 @@ RUNTIME_FUNCTION(Runtime_InternalDateFormat) { icu::SimpleDateFormat* date_format = DateFormat::UnpackDateFormat(isolate, date_format_holder); - if (!date_format) return isolate->ThrowIllegalOperation(); + CHECK_NOT_NULL(date_format); icu::UnicodeString result; date_format->format(value->Number(), result); @@ -475,7 +442,7 @@ RUNTIME_FUNCTION(Runtime_InternalDateFormatToParts) { HandleScope scope(isolate); Factory* factory = isolate->factory(); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1); @@ -485,7 +452,7 @@ RUNTIME_FUNCTION(Runtime_InternalDateFormatToParts) { icu::SimpleDateFormat* date_format = DateFormat::UnpackDateFormat(isolate, date_format_holder); - if (!date_format) return isolate->ThrowIllegalOperation(); + CHECK_NOT_NULL(date_format); icu::UnicodeString formatted; icu::FieldPositionIterator fp_iter; @@ -528,47 +495,21 @@ RUNTIME_FUNCTION(Runtime_InternalDateFormatToParts) { return *result; } -RUNTIME_FUNCTION(Runtime_InternalDateParse) { - HandleScope scope(isolate); - - DCHECK(args.length() == 2); - - CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); - CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1); - - v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string)); - icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date)); - icu::SimpleDateFormat* date_format = - DateFormat::UnpackDateFormat(isolate, date_format_holder); - if (!date_format) return isolate->ThrowIllegalOperation(); - - UErrorCode status = U_ZERO_ERROR; - UDate date = date_format->parse(u_date, status); - if (U_FAILURE(status)) return isolate->heap()->undefined_value(); - - RETURN_RESULT_OR_FAILURE( - isolate, JSDate::New(isolate->date_function(), isolate->date_function(), - static_cast<double>(date))); -} - - RUNTIME_FUNCTION(Runtime_CreateNumberFormat) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); - Handle<ObjectTemplateInfo> number_format_template = - I18N::GetTemplate(isolate); + Handle<JSFunction> constructor( + isolate->native_context()->intl_number_format_function()); - // Create an empty object wrapper. Handle<JSObject> local_object; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, local_object, - ApiNatives::InstantiateObject(number_format_template)); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, local_object, + JSObject::New(constructor, constructor)); // Set number formatter as internal field of the resulting JS object. icu::DecimalFormat* number_format = @@ -578,11 +519,6 @@ RUNTIME_FUNCTION(Runtime_CreateNumberFormat) { local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format)); - Factory* factory = isolate->factory(); - Handle<String> key = factory->NewStringFromStaticChars("numberFormat"); - Handle<String> value = factory->NewStringFromStaticChars("valid"); - JSObject::AddProperty(local_object, key, value, NONE); - Handle<Object> wrapper = isolate->global_handles()->Create(*local_object); GlobalHandles::MakeWeak(wrapper.location(), wrapper.location(), NumberFormat::DeleteNumberFormat, @@ -594,7 +530,7 @@ RUNTIME_FUNCTION(Runtime_CreateNumberFormat) { RUNTIME_FUNCTION(Runtime_InternalNumberFormat) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0); CONVERT_ARG_HANDLE_CHECKED(Object, number, 1); @@ -604,7 +540,7 @@ RUNTIME_FUNCTION(Runtime_InternalNumberFormat) { icu::DecimalFormat* number_format = NumberFormat::UnpackNumberFormat(isolate, number_format_holder); - if (!number_format) return isolate->ThrowIllegalOperation(); + CHECK_NOT_NULL(number_format); icu::UnicodeString result; number_format->format(value->Number(), result); @@ -616,62 +552,21 @@ RUNTIME_FUNCTION(Runtime_InternalNumberFormat) { } -RUNTIME_FUNCTION(Runtime_InternalNumberParse) { - HandleScope scope(isolate); - - DCHECK(args.length() == 2); - - CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0); - CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1); - - isolate->CountUsage(v8::Isolate::UseCounterFeature::kIntlV8Parse); - - v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string)); - icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number)); - icu::DecimalFormat* number_format = - NumberFormat::UnpackNumberFormat(isolate, number_format_holder); - if (!number_format) return isolate->ThrowIllegalOperation(); - - UErrorCode status = U_ZERO_ERROR; - icu::Formattable result; - // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49 - // to be part of Chrome. - // TODO(cira): Include currency parsing code using parseCurrency call. - // We need to check if the formatter parses all currencies or only the - // one it was constructed with (it will impact the API - how to return ISO - // code and the value). - number_format->parse(u_number, result, status); - if (U_FAILURE(status)) return isolate->heap()->undefined_value(); - - switch (result.getType()) { - case icu::Formattable::kDouble: - return *isolate->factory()->NewNumber(result.getDouble()); - case icu::Formattable::kLong: - return *isolate->factory()->NewNumberFromInt(result.getLong()); - case icu::Formattable::kInt64: - return *isolate->factory()->NewNumber( - static_cast<double>(result.getInt64())); - default: - return isolate->heap()->undefined_value(); - } -} - - RUNTIME_FUNCTION(Runtime_CreateCollator) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); - Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate); + Handle<JSFunction> constructor( + isolate->native_context()->intl_collator_function()); - // Create an empty object wrapper. Handle<JSObject> local_object; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, local_object, ApiNatives::InstantiateObject(collator_template)); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, local_object, + JSObject::New(constructor, constructor)); // Set collator as internal field of the resulting JS object. icu::Collator* collator = @@ -681,11 +576,6 @@ RUNTIME_FUNCTION(Runtime_CreateCollator) { local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator)); - Factory* factory = isolate->factory(); - Handle<String> key = factory->NewStringFromStaticChars("collator"); - Handle<String> value = factory->NewStringFromStaticChars("valid"); - JSObject::AddProperty(local_object, key, value, NONE); - Handle<Object> wrapper = isolate->global_handles()->Create(*local_object); GlobalHandles::MakeWeak(wrapper.location(), wrapper.location(), Collator::DeleteCollator, @@ -697,14 +587,14 @@ RUNTIME_FUNCTION(Runtime_CreateCollator) { RUNTIME_FUNCTION(Runtime_InternalCompare) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0); CONVERT_ARG_HANDLE_CHECKED(String, string1, 1); CONVERT_ARG_HANDLE_CHECKED(String, string2, 2); icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder); - if (!collator) return isolate->ThrowIllegalOperation(); + CHECK_NOT_NULL(collator); string1 = String::Flatten(string1); string2 = String::Flatten(string2); @@ -742,7 +632,7 @@ RUNTIME_FUNCTION(Runtime_StringNormalize) { {"nfkc", UNORM2_DECOMPOSE}, }; - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, s, 0); CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]); @@ -791,23 +681,21 @@ RUNTIME_FUNCTION(Runtime_StringNormalize) { RUNTIME_FUNCTION(Runtime_CreateBreakIterator) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); - Handle<ObjectTemplateInfo> break_iterator_template = - I18N::GetTemplate2(isolate); + Handle<JSFunction> constructor( + isolate->native_context()->intl_v8_break_iterator_function()); - // Create an empty object wrapper. Handle<JSObject> local_object; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, local_object, - ApiNatives::InstantiateObject(break_iterator_template)); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, local_object, + JSObject::New(constructor, constructor)); // Set break iterator as internal field of the resulting JS object. - icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator( + icu::BreakIterator* break_iterator = V8BreakIterator::InitializeBreakIterator( isolate, locale, options, resolved); if (!break_iterator) return isolate->ThrowIllegalOperation(); @@ -816,16 +704,11 @@ RUNTIME_FUNCTION(Runtime_CreateBreakIterator) { // Make sure that the pointer to adopted text is NULL. local_object->SetInternalField(1, static_cast<Smi*>(nullptr)); - Factory* factory = isolate->factory(); - Handle<String> key = factory->NewStringFromStaticChars("breakIterator"); - Handle<String> value = factory->NewStringFromStaticChars("valid"); - JSObject::AddProperty(local_object, key, value, NONE); - // Make object handle weak so we can delete the break iterator once GC kicks // in. Handle<Object> wrapper = isolate->global_handles()->Create(*local_object); GlobalHandles::MakeWeak(wrapper.location(), wrapper.location(), - BreakIterator::DeleteBreakIterator, + V8BreakIterator::DeleteBreakIterator, WeakCallbackType::kInternalFields); return *local_object; } @@ -834,14 +717,14 @@ RUNTIME_FUNCTION(Runtime_CreateBreakIterator) { RUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); CONVERT_ARG_HANDLE_CHECKED(String, text, 1); icu::BreakIterator* break_iterator = - BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); - if (!break_iterator) return isolate->ThrowIllegalOperation(); + V8BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); + CHECK_NOT_NULL(break_iterator); icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>( break_iterator_holder->GetInternalField(1)); @@ -865,13 +748,13 @@ RUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) { RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); icu::BreakIterator* break_iterator = - BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); - if (!break_iterator) return isolate->ThrowIllegalOperation(); + V8BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); + CHECK_NOT_NULL(break_iterator); return *isolate->factory()->NewNumberFromInt(break_iterator->first()); } @@ -880,13 +763,13 @@ RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) { RUNTIME_FUNCTION(Runtime_BreakIteratorNext) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); icu::BreakIterator* break_iterator = - BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); - if (!break_iterator) return isolate->ThrowIllegalOperation(); + V8BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); + CHECK_NOT_NULL(break_iterator); return *isolate->factory()->NewNumberFromInt(break_iterator->next()); } @@ -895,13 +778,13 @@ RUNTIME_FUNCTION(Runtime_BreakIteratorNext) { RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); icu::BreakIterator* break_iterator = - BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); - if (!break_iterator) return isolate->ThrowIllegalOperation(); + V8BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); + CHECK_NOT_NULL(break_iterator); return *isolate->factory()->NewNumberFromInt(break_iterator->current()); } @@ -910,13 +793,13 @@ RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) { RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0); icu::BreakIterator* break_iterator = - BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); - if (!break_iterator) return isolate->ThrowIllegalOperation(); + V8BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder); + CHECK_NOT_NULL(break_iterator); // TODO(cira): Remove cast once ICU fixes base BreakIterator class. icu::RuleBasedBreakIterator* rule_based_iterator = @@ -956,6 +839,7 @@ MUST_USE_RESULT Object* LocaleConvertCase(Handle<String> s, Isolate* isolate, ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, result, isolate->factory()->NewRawTwoByteString(dest_length)); DisallowHeapAllocation no_gc; + DCHECK(s->IsFlat()); String::FlatContent flat = s->GetFlatContent(); const UChar* src = GetUCharBufferFromFlat(flat, &sap, src_length); status = U_ZERO_ERROR; @@ -1041,15 +925,14 @@ bool ToUpperFastASCII(const Vector<const Char>& src, const uint16_t sharp_s = 0xDF; template <typename Char> -bool ToUpperOneByte(const Vector<const Char>& src, - Handle<SeqOneByteString> result, int* sharp_s_count) { +bool ToUpperOneByte(const Vector<const Char>& src, uint8_t* dest, + int* sharp_s_count) { // Still pretty-fast path for the input with non-ASCII Latin-1 characters. // There are two special cases. // 1. U+00B5 and U+00FF are mapped to a character beyond U+00FF. // 2. Lower case sharp-S converts to "SS" (two characters) *sharp_s_count = 0; - int32_t index = 0; for (auto it = src.begin(); it != src.end(); ++it) { uint16_t ch = static_cast<uint16_t>(*it); if (V8_UNLIKELY(ch == sharp_s)) { @@ -1061,7 +944,7 @@ bool ToUpperOneByte(const Vector<const Char>& src, // need to take the 16-bit path. return false; } - result->SeqOneByteStringSet(index++, ToLatin1Upper(ch)); + *dest++ = ToLatin1Upper(ch); } return true; @@ -1082,105 +965,112 @@ void ToUpperWithSharpS(const Vector<const Char>& src, } } -} // namespace +inline int FindFirstUpperOrNonAscii(Handle<String> s, int length) { + for (int index = 0; index < length; ++index) { + uint16_t ch = s->Get(index); + if (V8_UNLIKELY(IsASCIIUpper(ch) || ch & ~0x7F)) { + return index; + } + } + return length; +} -RUNTIME_FUNCTION(Runtime_StringToLowerCaseI18N) { - HandleScope scope(isolate); - DCHECK_EQ(args.length(), 1); - CONVERT_ARG_HANDLE_CHECKED(String, s, 0); +MUST_USE_RESULT Object* ConvertToLower(Handle<String> s, Isolate* isolate) { + if (!s->HasOnlyOneByteChars()) { + // Use a slower implementation for strings with characters beyond U+00FF. + return LocaleConvertCase(s, isolate, false, ""); + } int length = s->length(); - s = String::Flatten(s); - // First scan the string for uppercase and non-ASCII characters: - if (s->HasOnlyOneByteChars()) { - int first_index_to_lower = length; - for (int index = 0; index < length; ++index) { - // Blink specializes this path for one-byte strings, so it - // does not need to do a generic get, but can do the equivalent - // of SeqOneByteStringGet. - uint16_t ch = s->Get(index); - if (V8_UNLIKELY(IsASCIIUpper(ch) || ch & ~0x7F)) { - first_index_to_lower = index; - break; - } - } + // We depend here on the invariant that the length of a Latin1 + // string is invariant under ToLowerCase, and the result always + // fits in the Latin1 range in the *root locale*. It does not hold + // for ToUpperCase even in the root locale. + + // Scan the string for uppercase and non-ASCII characters for strings + // shorter than a machine-word without any memory allocation overhead. + // TODO(jshin): Apply this to a longer input by breaking FastAsciiConvert() + // to two parts, one for scanning the prefix with no change and the other for + // handling ASCII-only characters. + int index_to_first_unprocessed = length; + const bool is_short = length < static_cast<int>(sizeof(uintptr_t)); + if (is_short) { + index_to_first_unprocessed = FindFirstUpperOrNonAscii(s, length); // Nothing to do if the string is all ASCII with no uppercase. - if (first_index_to_lower == length) return *s; + if (index_to_first_unprocessed == length) return *s; + } - // We depend here on the invariant that the length of a Latin1 - // string is invariant under ToLowerCase, and the result always - // fits in the Latin1 range in the *root locale*. It does not hold - // for ToUpperCase even in the root locale. - Handle<SeqOneByteString> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, isolate->factory()->NewRawOneByteString(length)); + Handle<SeqOneByteString> result = + isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); - DisallowHeapAllocation no_gc; - String::FlatContent flat = s->GetFlatContent(); - if (flat.IsOneByte()) { - const uint8_t* src = flat.ToOneByteVector().start(); - CopyChars(result->GetChars(), src, - static_cast<size_t>(first_index_to_lower)); - for (int index = first_index_to_lower; index < length; ++index) { - uint16_t ch = static_cast<uint16_t>(src[index]); - result->SeqOneByteStringSet(index, ToLatin1Lower(ch)); - } - } else { - const uint16_t* src = flat.ToUC16Vector().start(); - CopyChars(result->GetChars(), src, - static_cast<size_t>(first_index_to_lower)); - for (int index = first_index_to_lower; index < length; ++index) { - uint16_t ch = src[index]; - result->SeqOneByteStringSet(index, ToLatin1Lower(ch)); - } + DisallowHeapAllocation no_gc; + DCHECK(s->IsFlat()); + String::FlatContent flat = s->GetFlatContent(); + uint8_t* dest = result->GetChars(); + if (flat.IsOneByte()) { + const uint8_t* src = flat.ToOneByteVector().start(); + bool has_changed_character = false; + index_to_first_unprocessed = FastAsciiConvert<true>( + reinterpret_cast<char*>(dest), reinterpret_cast<const char*>(src), + length, &has_changed_character); + // If not ASCII, we keep the result up to index_to_first_unprocessed and + // process the rest. + if (index_to_first_unprocessed == length) + return has_changed_character ? *result : *s; + + for (int index = index_to_first_unprocessed; index < length; ++index) { + dest[index] = ToLatin1Lower(static_cast<uint16_t>(src[index])); + } + } else { + if (index_to_first_unprocessed == length) { + DCHECK(!is_short); + index_to_first_unprocessed = FindFirstUpperOrNonAscii(s, length); + } + // Nothing to do if the string is all ASCII with no uppercase. + if (index_to_first_unprocessed == length) return *s; + const uint16_t* src = flat.ToUC16Vector().start(); + CopyChars(dest, src, index_to_first_unprocessed); + for (int index = index_to_first_unprocessed; index < length; ++index) { + dest[index] = ToLatin1Lower(static_cast<uint16_t>(src[index])); } - - return *result; } - // Blink had an additional case here for ASCII 2-byte strings, but - // that is subsumed by the above code (assuming there isn't a false - // negative for HasOnlyOneByteChars). - - // Do a slower implementation for cases that include non-ASCII characters. - return LocaleConvertCase(s, isolate, false, ""); + return *result; } -RUNTIME_FUNCTION(Runtime_StringToUpperCaseI18N) { - HandleScope scope(isolate); - DCHECK_EQ(args.length(), 1); - CONVERT_ARG_HANDLE_CHECKED(String, s, 0); - - // This function could be optimized for no-op cases the way lowercase - // counterpart is, but in empirical testing, few actual calls to upper() - // are no-ops. So, it wouldn't be worth the extra time for pre-scanning. - +MUST_USE_RESULT Object* ConvertToUpper(Handle<String> s, Isolate* isolate) { int32_t length = s->length(); - s = String::Flatten(s); - if (s->HasOnlyOneByteChars()) { - Handle<SeqOneByteString> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, isolate->factory()->NewRawOneByteString(length)); + Handle<SeqOneByteString> result = + isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); + DCHECK(s->IsFlat()); int sharp_s_count; bool is_result_single_byte; { DisallowHeapAllocation no_gc; String::FlatContent flat = s->GetFlatContent(); - // If it was ok to slow down ASCII-only input slightly, ToUpperFastASCII - // could be removed because ToUpperOneByte is pretty fast now (it - // does not call ICU API any more.). + uint8_t* dest = result->GetChars(); if (flat.IsOneByte()) { Vector<const uint8_t> src = flat.ToOneByteVector(); - if (ToUpperFastASCII(src, result)) return *result; - is_result_single_byte = ToUpperOneByte(src, result, &sharp_s_count); + bool has_changed_character = false; + int index_to_first_unprocessed = + FastAsciiConvert<false>(reinterpret_cast<char*>(result->GetChars()), + reinterpret_cast<const char*>(src.start()), + length, &has_changed_character); + if (index_to_first_unprocessed == length) + return has_changed_character ? *result : *s; + // If not ASCII, we keep the result up to index_to_first_unprocessed and + // process the rest. + is_result_single_byte = + ToUpperOneByte(src.SubVector(index_to_first_unprocessed, length), + dest + index_to_first_unprocessed, &sharp_s_count); } else { DCHECK(flat.IsTwoByte()); Vector<const uint16_t> src = flat.ToUC16Vector(); if (ToUpperFastASCII(src, result)) return *result; - is_result_single_byte = ToUpperOneByte(src, result, &sharp_s_count); + is_result_single_byte = ToUpperOneByte(src, dest, &sharp_s_count); } } @@ -1211,26 +1101,67 @@ RUNTIME_FUNCTION(Runtime_StringToUpperCaseI18N) { return LocaleConvertCase(s, isolate, true, ""); } +MUST_USE_RESULT Object* ConvertCase(Handle<String> s, bool is_upper, + Isolate* isolate) { + return is_upper ? ConvertToUpper(s, isolate) : ConvertToLower(s, isolate); +} + +} // namespace + +RUNTIME_FUNCTION(Runtime_StringToLowerCaseI18N) { + HandleScope scope(isolate); + DCHECK_EQ(args.length(), 1); + CONVERT_ARG_HANDLE_CHECKED(String, s, 0); + s = String::Flatten(s); + return ConvertToLower(s, isolate); +} + +RUNTIME_FUNCTION(Runtime_StringToUpperCaseI18N) { + HandleScope scope(isolate); + DCHECK_EQ(args.length(), 1); + CONVERT_ARG_HANDLE_CHECKED(String, s, 0); + s = String::Flatten(s); + return ConvertToUpper(s, isolate); +} + RUNTIME_FUNCTION(Runtime_StringLocaleConvertCase) { HandleScope scope(isolate); DCHECK_EQ(args.length(), 3); CONVERT_ARG_HANDLE_CHECKED(String, s, 0); CONVERT_BOOLEAN_ARG_CHECKED(is_upper, 1); - CONVERT_ARG_HANDLE_CHECKED(SeqOneByteString, lang, 2); - - // All the languages requiring special handling ("az", "el", "lt", "tr") - // have a 2-letter language code. - DCHECK(lang->length() == 2); - uint8_t lang_str[3]; - memcpy(lang_str, lang->GetChars(), 2); - lang_str[2] = 0; + CONVERT_ARG_HANDLE_CHECKED(String, lang_arg, 2); + + // Primary language tag can be up to 8 characters long in theory. + // https://tools.ietf.org/html/bcp47#section-2.2.1 + DCHECK(lang_arg->length() <= 8); + lang_arg = String::Flatten(lang_arg); s = String::Flatten(s); + + // All the languages requiring special-handling have two-letter codes. + if (V8_UNLIKELY(lang_arg->length() > 2)) + return ConvertCase(s, is_upper, isolate); + + char c1, c2; + { + DisallowHeapAllocation no_gc; + String::FlatContent lang = lang_arg->GetFlatContent(); + c1 = lang.Get(0); + c2 = lang.Get(1); + } // TODO(jshin): Consider adding a fast path for ASCII or Latin-1. The fastpath // in the root locale needs to be adjusted for az, lt and tr because even case // mapping of ASCII range characters are different in those locales. - // Greek (el) does not require any adjustment, though. - return LocaleConvertCase(s, isolate, is_upper, - reinterpret_cast<const char*>(lang_str)); + // Greek (el) does not require any adjustment. + if (V8_UNLIKELY(c1 == 't' && c2 == 'r')) + return LocaleConvertCase(s, isolate, is_upper, "tr"); + if (V8_UNLIKELY(c1 == 'e' && c2 == 'l')) + return LocaleConvertCase(s, isolate, is_upper, "el"); + if (V8_UNLIKELY(c1 == 'l' && c2 == 't')) + return LocaleConvertCase(s, isolate, is_upper, "lt"); + if (V8_UNLIKELY(c1 == 'a' && c2 == 'z')) + return LocaleConvertCase(s, isolate, is_upper, "az"); + + return ConvertCase(s, is_upper, isolate); } RUNTIME_FUNCTION(Runtime_DateCacheVersion) { diff --git a/deps/v8/src/runtime/runtime-internal.cc b/deps/v8/src/runtime/runtime-internal.cc index 621f33547e..6ff0a09b61 100644 --- a/deps/v8/src/runtime/runtime-internal.cc +++ b/deps/v8/src/runtime/runtime-internal.cc @@ -9,13 +9,14 @@ #include "src/arguments.h" #include "src/ast/prettyprinter.h" #include "src/bootstrapper.h" +#include "src/builtins/builtins.h" #include "src/conversions.h" #include "src/debug/debug.h" #include "src/frames-inl.h" #include "src/isolate-inl.h" #include "src/messages.h" #include "src/parsing/parse-info.h" -#include "src/parsing/parser.h" +#include "src/parsing/parsing.h" #include "src/wasm/wasm-module.h" namespace v8 { @@ -23,7 +24,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); CHECK(isolate->bootstrapper()->IsActive()); return isolate->heap()->undefined_value(); } @@ -31,7 +32,7 @@ RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) { RUNTIME_FUNCTION(Runtime_ExportFromRuntime) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, container, 0); CHECK(isolate->bootstrapper()->IsActive()); JSObject::NormalizeProperties(container, KEEP_INOBJECT_PROPERTIES, 10, @@ -44,7 +45,7 @@ RUNTIME_FUNCTION(Runtime_ExportFromRuntime) { RUNTIME_FUNCTION(Runtime_ExportExperimentalFromRuntime) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, container, 0); CHECK(isolate->bootstrapper()->IsActive()); JSObject::NormalizeProperties(container, KEEP_INOBJECT_PROPERTIES, 10, @@ -57,7 +58,7 @@ RUNTIME_FUNCTION(Runtime_ExportExperimentalFromRuntime) { RUNTIME_FUNCTION(Runtime_InstallToContext) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); CHECK(array->HasFastElements()); CHECK(isolate->bootstrapper()->IsActive()); @@ -82,14 +83,14 @@ RUNTIME_FUNCTION(Runtime_InstallToContext) { RUNTIME_FUNCTION(Runtime_Throw) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); return isolate->Throw(args[0]); } RUNTIME_FUNCTION(Runtime_ReThrow) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); return isolate->ReThrow(args[0]); } @@ -106,9 +107,9 @@ RUNTIME_FUNCTION(Runtime_ThrowTypeError) { CONVERT_SMI_ARG_CHECKED(message_id_smi, 0); Handle<Object> undefined = isolate->factory()->undefined_value(); - Handle<Object> arg0 = (args.length() > 1) ? args.at<Object>(1) : undefined; - Handle<Object> arg1 = (args.length() > 2) ? args.at<Object>(2) : undefined; - Handle<Object> arg2 = (args.length() > 3) ? args.at<Object>(3) : undefined; + Handle<Object> arg0 = (args.length() > 1) ? args.at(1) : undefined; + Handle<Object> arg1 = (args.length() > 2) ? args.at(2) : undefined; + Handle<Object> arg2 = (args.length() > 3) ? args.at(3) : undefined; MessageTemplate::Template message_id = static_cast<MessageTemplate::Template>(message_id_smi); @@ -117,77 +118,23 @@ RUNTIME_FUNCTION(Runtime_ThrowTypeError) { NewTypeError(message_id, arg0, arg1, arg2)); } -RUNTIME_FUNCTION(Runtime_ThrowWasmError) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - CONVERT_SMI_ARG_CHECKED(message_id, 0); - CONVERT_SMI_ARG_CHECKED(byte_offset, 1); - Handle<Object> error_obj = isolate->factory()->NewWasmRuntimeError( - static_cast<MessageTemplate::Template>(message_id)); - - // For wasm traps, the byte offset (a.k.a source position) can not be - // determined from relocation info, since the explicit checks for traps - // converge in one singe block which calls this runtime function. - // We hence pass the byte offset explicitely, and patch it into the top-most - // frame (a wasm frame) on the collected stack trace. - // TODO(wasm): This implementation is temporary, see bug #5007: - // https://bugs.chromium.org/p/v8/issues/detail?id=5007 - Handle<JSObject> error = Handle<JSObject>::cast(error_obj); - Handle<Object> stack_trace_obj = JSReceiver::GetDataProperty( - error, isolate->factory()->stack_trace_symbol()); - // Patch the stack trace (array of <receiver, function, code, position>). - if (stack_trace_obj->IsJSArray()) { - Handle<FrameArray> stack_elements( - FrameArray::cast(JSArray::cast(*stack_trace_obj)->elements())); - DCHECK(stack_elements->Code(0)->kind() == AbstractCode::WASM_FUNCTION); - DCHECK(stack_elements->Offset(0)->value() >= 0); - stack_elements->SetOffset(0, Smi::FromInt(-1 - byte_offset)); - } - - // Patch the detailed stack trace (array of JSObjects with various - // properties). - Handle<Object> detailed_stack_trace_obj = JSReceiver::GetDataProperty( - error, isolate->factory()->detailed_stack_trace_symbol()); - if (detailed_stack_trace_obj->IsJSArray()) { - Handle<FixedArray> stack_elements( - FixedArray::cast(JSArray::cast(*detailed_stack_trace_obj)->elements())); - DCHECK_GE(stack_elements->length(), 1); - Handle<JSObject> top_frame(JSObject::cast(stack_elements->get(0))); - Handle<String> wasm_offset_key = - isolate->factory()->InternalizeOneByteString( - STATIC_CHAR_VECTOR("column")); - LookupIterator it(top_frame, wasm_offset_key, top_frame, - LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); - if (it.IsFound()) { - DCHECK(JSReceiver::GetDataProperty(&it)->IsSmi()); - // Make column number 1-based here. - Maybe<bool> data_set = JSReceiver::SetDataProperty( - &it, handle(Smi::FromInt(byte_offset + 1), isolate)); - DCHECK(data_set.IsJust() && data_set.FromJust() == true); - USE(data_set); - } - } - - return isolate->Throw(*error_obj); -} - RUNTIME_FUNCTION(Runtime_UnwindAndFindExceptionHandler) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); return isolate->UnwindAndFindHandler(); } RUNTIME_FUNCTION(Runtime_PromoteScheduledException) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); return isolate->PromoteScheduledException(); } RUNTIME_FUNCTION(Runtime_ThrowReferenceError) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewReferenceError(MessageTemplate::kNotDefined, name)); @@ -196,7 +143,7 @@ RUNTIME_FUNCTION(Runtime_ThrowReferenceError) { RUNTIME_FUNCTION(Runtime_NewTypeError) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_INT32_ARG_CHECKED(template_index, 0); CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1); auto message_template = @@ -207,7 +154,7 @@ RUNTIME_FUNCTION(Runtime_NewTypeError) { RUNTIME_FUNCTION(Runtime_NewReferenceError) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_INT32_ARG_CHECKED(template_index, 0); CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1); auto message_template = @@ -218,7 +165,7 @@ RUNTIME_FUNCTION(Runtime_NewReferenceError) { RUNTIME_FUNCTION(Runtime_NewSyntaxError) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_INT32_ARG_CHECKED(template_index, 0); CONVERT_ARG_HANDLE_CHECKED(Object, arg0, 1); auto message_template = @@ -234,7 +181,7 @@ RUNTIME_FUNCTION(Runtime_ThrowCannotConvertToPrimitive) { RUNTIME_FUNCTION(Runtime_ThrowIllegalInvocation) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kIllegalInvocation)); } @@ -249,6 +196,14 @@ RUNTIME_FUNCTION(Runtime_ThrowIncompatibleMethodReceiver) { NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, arg0, arg1)); } +RUNTIME_FUNCTION(Runtime_ThrowInvalidHint) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, hint, 0); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kInvalidHint, hint)); +} + RUNTIME_FUNCTION(Runtime_ThrowInvalidStringLength) { HandleScope scope(isolate); THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); @@ -256,13 +211,20 @@ RUNTIME_FUNCTION(Runtime_ThrowInvalidStringLength) { RUNTIME_FUNCTION(Runtime_ThrowIteratorResultNotAnObject) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kIteratorResultNotAnObject, value)); } +RUNTIME_FUNCTION(Runtime_ThrowSymbolIteratorInvalid) { + HandleScope scope(isolate); + DCHECK_EQ(0, args.length()); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kSymbolIteratorInvalid)); +} + RUNTIME_FUNCTION(Runtime_ThrowNotGeneric) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -290,7 +252,7 @@ RUNTIME_FUNCTION(Runtime_ThrowApplyNonFunction) { RUNTIME_FUNCTION(Runtime_StackGuard) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); // First check if this is a real stack overflow. StackLimitCheck check(isolate); @@ -304,14 +266,14 @@ RUNTIME_FUNCTION(Runtime_StackGuard) { RUNTIME_FUNCTION(Runtime_Interrupt) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); return isolate->stack_guard()->HandleInterrupts(); } RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_SMI_ARG_CHECKED(size, 0); CHECK(IsAligned(size, kPointerSize)); CHECK(size > 0); @@ -322,14 +284,14 @@ RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) { RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_SMI_ARG_CHECKED(size, 0); CONVERT_SMI_ARG_CHECKED(flags, 1); CHECK(IsAligned(size, kPointerSize)); CHECK(size > 0); - CHECK(size <= kMaxRegularHeapObjectSize); bool double_align = AllocateDoubleAlignFlag::decode(flags); AllocationSpace space = AllocateTargetSpace::decode(flags); + CHECK(size <= kMaxRegularHeapObjectSize || space == LO_SPACE); return *isolate->factory()->NewFillerObject(size, double_align, space); } @@ -365,20 +327,19 @@ namespace { bool ComputeLocation(Isolate* isolate, MessageLocation* target) { JavaScriptFrameIterator it(isolate); if (!it.done()) { - JavaScriptFrame* frame = it.frame(); - JSFunction* fun = frame->function(); - Object* script = fun->shared()->script(); + // Compute the location from the function and the relocation info of the + // baseline code. For optimized code this will use the deoptimization + // information to get canonical location information. + List<FrameSummary> frames(FLAG_max_inlining_levels + 1); + it.frame()->Summarize(&frames); + auto& summary = frames.last().AsJavaScript(); + Handle<SharedFunctionInfo> shared(summary.function()->shared()); + Handle<Object> script(shared->script(), isolate); + int pos = summary.abstract_code()->SourcePosition(summary.code_offset()); if (script->IsScript() && - !(Script::cast(script)->source()->IsUndefined(isolate))) { - Handle<Script> casted_script(Script::cast(script), isolate); - // Compute the location from the function and the relocation info of the - // baseline code. For optimized code this will use the deoptimization - // information to get canonical location information. - List<FrameSummary> frames(FLAG_max_inlining_levels + 1); - it.frame()->Summarize(&frames); - FrameSummary& summary = frames.last(); - int pos = summary.abstract_code()->SourcePosition(summary.code_offset()); - *target = MessageLocation(casted_script, pos, pos + 1, handle(fun)); + !(Handle<Script>::cast(script)->source()->IsUndefined(isolate))) { + Handle<Script> casted_script = Handle<Script>::cast(script); + *target = MessageLocation(casted_script, pos, pos + 1, shared); return true; } } @@ -390,12 +351,9 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object) { MessageLocation location; if (ComputeLocation(isolate, &location)) { Zone zone(isolate->allocator(), ZONE_NAME); - std::unique_ptr<ParseInfo> info( - location.function()->shared()->is_function() - ? new ParseInfo(&zone, handle(location.function()->shared())) - : new ParseInfo(&zone, location.script())); - if (Parser::ParseStatic(info.get())) { - CallPrinter printer(isolate, location.function()->shared()->IsBuiltin()); + std::unique_ptr<ParseInfo> info(new ParseInfo(&zone, location.shared())); + if (parsing::ParseAny(info.get())) { + CallPrinter printer(isolate, location.shared()->IsUserJavaScript()); Handle<String> str = printer.Print(info->literal(), location.start_pos()); if (str->length() > 0) return str; } else { @@ -522,20 +480,20 @@ RUNTIME_FUNCTION(Runtime_OrdinaryHasInstance) { isolate, Object::OrdinaryHasInstance(isolate, callable, object)); } -RUNTIME_FUNCTION(Runtime_IsWasmInstance) { +RUNTIME_FUNCTION(Runtime_Typeof) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); - CONVERT_ARG_CHECKED(Object, object, 0); - bool is_wasm_instance = - object->IsJSObject() && wasm::IsWasmInstance(JSObject::cast(object)); - return *isolate->factory()->ToBoolean(is_wasm_instance); + CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); + return *Object::TypeOf(isolate, object); } -RUNTIME_FUNCTION(Runtime_Typeof) { +RUNTIME_FUNCTION(Runtime_AllowDynamicFunction) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); - return *Object::TypeOf(isolate, object); + CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0); + Handle<JSObject> global_proxy(target->global_proxy(), isolate); + return *isolate->factory()->ToBoolean( + Builtins::AllowDynamicFunction(isolate, target, global_proxy)); } } // namespace internal diff --git a/deps/v8/src/runtime/runtime-interpreter.cc b/deps/v8/src/runtime/runtime-interpreter.cc index 62eee1744f..2201b4c337 100644 --- a/deps/v8/src/runtime/runtime-interpreter.cc +++ b/deps/v8/src/runtime/runtime-interpreter.cc @@ -21,9 +21,9 @@ namespace internal { RUNTIME_FUNCTION(Runtime_InterpreterNewClosure) { HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); - CONVERT_SMI_ARG_CHECKED(pretenured_flag, 1); + CONVERT_SMI_ARG_CHECKED(pretenured_flag, 3); Handle<Context> context(isolate->context(), isolate); return *isolate->factory()->NewFunctionFromSharedFunctionInfo( shared, context, static_cast<PretenureFlag>(pretenured_flag)); @@ -155,22 +155,6 @@ RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) { return isolate->heap()->undefined_value(); } -RUNTIME_FUNCTION(Runtime_InterpreterClearPendingMessage) { - SealHandleScope shs(isolate); - DCHECK_EQ(0, args.length()); - Object* message = isolate->thread_local_top()->pending_message_obj_; - isolate->clear_pending_message(); - return message; -} - -RUNTIME_FUNCTION(Runtime_InterpreterSetPendingMessage) { - SealHandleScope shs(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, message, 0); - isolate->thread_local_top()->pending_message_obj_ = *message; - return isolate->heap()->undefined_value(); -} - RUNTIME_FUNCTION(Runtime_InterpreterAdvanceBytecodeOffset) { SealHandleScope shs(isolate); DCHECK_EQ(2, args.length()); diff --git a/deps/v8/src/runtime/runtime-literals.cc b/deps/v8/src/runtime/runtime-literals.cc index 8bb4522a98..45b83293b6 100644 --- a/deps/v8/src/runtime/runtime-literals.cc +++ b/deps/v8/src/runtime/runtime-literals.cc @@ -113,7 +113,7 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( static MaybeHandle<Object> CreateArrayLiteralBoilerplate( Isolate* isolate, Handle<LiteralsArray> literals, - Handle<FixedArray> elements) { + Handle<ConstantElementsPair> elements) { // Create the JSArray. Handle<JSFunction> constructor = isolate->array_function(); @@ -124,9 +124,8 @@ static MaybeHandle<Object> CreateArrayLiteralBoilerplate( isolate->factory()->NewJSObject(constructor, pretenure_flag)); ElementsKind constant_elements_kind = - static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); - Handle<FixedArrayBase> constant_elements_values( - FixedArrayBase::cast(elements->get(1))); + static_cast<ElementsKind>(elements->elements_kind()); + Handle<FixedArrayBase> constant_elements_values(elements->constant_values()); { DisallowHeapAllocation no_gc; @@ -186,14 +185,21 @@ static MaybeHandle<Object> CreateArrayLiteralBoilerplate( MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( Isolate* isolate, Handle<LiteralsArray> literals, Handle<FixedArray> array) { - Handle<FixedArray> elements = CompileTimeValue::GetElements(array); + Handle<HeapObject> elements = CompileTimeValue::GetElements(array); switch (CompileTimeValue::GetLiteralType(array)) { - case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: - return CreateObjectLiteralBoilerplate(isolate, literals, elements, true); - case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: - return CreateObjectLiteralBoilerplate(isolate, literals, elements, false); - case CompileTimeValue::ARRAY_LITERAL: - return CreateArrayLiteralBoilerplate(isolate, literals, elements); + case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: { + Handle<FixedArray> props = Handle<FixedArray>::cast(elements); + return CreateObjectLiteralBoilerplate(isolate, literals, props, true); + } + case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: { + Handle<FixedArray> props = Handle<FixedArray>::cast(elements); + return CreateObjectLiteralBoilerplate(isolate, literals, props, false); + } + case CompileTimeValue::ARRAY_LITERAL: { + Handle<ConstantElementsPair> elems = + Handle<ConstantElementsPair>::cast(elements); + return CreateArrayLiteralBoilerplate(isolate, literals, elems); + } default: UNREACHABLE(); return MaybeHandle<Object>(); @@ -270,12 +276,11 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite( Isolate* isolate, Handle<LiteralsArray> literals, int literals_index, - Handle<FixedArray> elements) { + Handle<ConstantElementsPair> elements) { // Check if boilerplate exists. If not, create it first. Handle<Object> literal_site(literals->literal(literals_index), isolate); Handle<AllocationSite> site; if (literal_site->IsUndefined(isolate)) { - DCHECK(*elements != isolate->heap()->empty_fixed_array()); Handle<Object> boilerplate; ASSIGN_RETURN_ON_EXCEPTION( isolate, boilerplate, @@ -298,10 +303,9 @@ MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite( return site; } - static MaybeHandle<JSObject> CreateArrayLiteralImpl( Isolate* isolate, Handle<LiteralsArray> literals, int literals_index, - Handle<FixedArray> elements, int flags) { + Handle<ConstantElementsPair> elements, int flags) { CHECK(literals_index >= 0 && literals_index < literals->literals_count()); Handle<AllocationSite> site; ASSIGN_RETURN_ON_EXCEPTION( @@ -328,7 +332,7 @@ RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); CONVERT_SMI_ARG_CHECKED(literals_index, 1); - CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); + CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2); CONVERT_SMI_ARG_CHECKED(flags, 3); Handle<LiteralsArray> literals(closure->literals(), isolate); @@ -343,7 +347,7 @@ RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) { DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); CONVERT_SMI_ARG_CHECKED(literals_index, 1); - CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); + CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2); Handle<LiteralsArray> literals(closure->literals(), isolate); RETURN_RESULT_OR_FAILURE( diff --git a/deps/v8/src/runtime/runtime-liveedit.cc b/deps/v8/src/runtime/runtime-liveedit.cc index a19ccaa584..56493252c8 100644 --- a/deps/v8/src/runtime/runtime-liveedit.cc +++ b/deps/v8/src/runtime/runtime-liveedit.cc @@ -21,7 +21,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) { HandleScope scope(isolate); CHECK(isolate->debug()->live_edit_enabled()); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(JSValue, script_value, 0); CHECK(script_value->value()->IsScript()); @@ -63,7 +63,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) { RUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) { HandleScope scope(isolate); CHECK(isolate->debug()->live_edit_enabled()); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_CHECKED(JSValue, script, 0); CONVERT_ARG_HANDLE_CHECKED(String, source, 1); @@ -81,7 +81,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) { RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) { HandleScope scope(isolate); CHECK(isolate->debug()->live_edit_enabled()); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_CHECKED(JSValue, original_script_value, 0); CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1); CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2); @@ -100,15 +100,31 @@ RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) { } } +// Recreate the shared function infos array after changing the IDs of all +// SharedFunctionInfos. +RUNTIME_FUNCTION(Runtime_LiveEditFixupScript) { + HandleScope scope(isolate); + CHECK(isolate->debug()->live_edit_enabled()); + DCHECK_EQ(args.length(), 2); + CONVERT_ARG_CHECKED(JSValue, script_value, 0); + CONVERT_INT32_ARG_CHECKED(max_function_literal_id, 1); + + CHECK(script_value->value()->IsScript()); + Handle<Script> script(Script::cast(script_value->value())); + + LiveEdit::FixupScript(script, max_function_literal_id); + return isolate->heap()->undefined_value(); +} RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) { HandleScope scope(isolate); CHECK(isolate->debug()->live_edit_enabled()); - DCHECK(args.length() == 1); + DCHECK_EQ(args.length(), 2); CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0); + CONVERT_INT32_ARG_CHECKED(new_function_literal_id, 1); CHECK(SharedInfoWrapper::IsInstance(shared_info)); - LiveEdit::FunctionSourceUpdated(shared_info); + LiveEdit::FunctionSourceUpdated(shared_info, new_function_literal_id); return isolate->heap()->undefined_value(); } @@ -117,7 +133,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) { RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) { HandleScope scope(isolate); CHECK(isolate->debug()->live_edit_enabled()); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0); CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1); CHECK(SharedInfoWrapper::IsInstance(shared_info)); @@ -131,7 +147,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) { RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) { HandleScope scope(isolate); CHECK(isolate->debug()->live_edit_enabled()); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0); CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1); @@ -158,7 +174,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) { RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) { HandleScope scope(isolate); CHECK(isolate->debug()->live_edit_enabled()); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0); CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1); @@ -181,7 +197,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) { RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) { HandleScope scope(isolate); CHECK(isolate->debug()->live_edit_enabled()); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0); CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1); CHECK(SharedInfoWrapper::IsInstance(shared_array)); @@ -198,7 +214,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) { RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) { HandleScope scope(isolate); CHECK(isolate->debug()->live_edit_enabled()); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArray, old_shared_array, 0); CONVERT_ARG_HANDLE_CHECKED(JSArray, new_shared_array, 1); CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 2); @@ -236,7 +252,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) { RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) { HandleScope scope(isolate); CHECK(isolate->debug()->live_edit_enabled()); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, s1, 0); CONVERT_ARG_HANDLE_CHECKED(String, s2, 1); @@ -256,7 +272,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) { RUNTIME_FUNCTION(Runtime_LiveEditRestartFrame) { HandleScope scope(isolate); CHECK(isolate->debug()->live_edit_enabled()); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); CHECK(isolate->debug()->CheckExecutionState(break_id)); diff --git a/deps/v8/src/runtime/runtime-maths.cc b/deps/v8/src/runtime/runtime-maths.cc index 404305a150..5bd7bde1eb 100644 --- a/deps/v8/src/runtime/runtime-maths.cc +++ b/deps/v8/src/runtime/runtime-maths.cc @@ -15,7 +15,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_GenerateRandomNumbers) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); Handle<Context> native_context = isolate->native_context(); DCHECK_EQ(0, native_context->math_random_index()->value()); diff --git a/deps/v8/src/runtime/runtime-module.cc b/deps/v8/src/runtime/runtime-module.cc index 2b813430e0..f2a9761203 100644 --- a/deps/v8/src/runtime/runtime-module.cc +++ b/deps/v8/src/runtime/runtime-module.cc @@ -11,7 +11,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_GetModuleNamespace) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_SMI_ARG_CHECKED(module_request, 0); Handle<Module> module(isolate->context()->module()); return *Module::GetModuleNamespace(module, module_request); @@ -19,7 +19,7 @@ RUNTIME_FUNCTION(Runtime_GetModuleNamespace) { RUNTIME_FUNCTION(Runtime_LoadModuleVariable) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_SMI_ARG_CHECKED(index, 0); Handle<Module> module(isolate->context()->module()); return *Module::LoadVariable(module, index); @@ -27,7 +27,7 @@ RUNTIME_FUNCTION(Runtime_LoadModuleVariable) { RUNTIME_FUNCTION(Runtime_StoreModuleVariable) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_SMI_ARG_CHECKED(index, 0); CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); Handle<Module> module(isolate->context()->module()); diff --git a/deps/v8/src/runtime/runtime-numbers.cc b/deps/v8/src/runtime/runtime-numbers.cc index bfe8763e99..4d8d5d267d 100644 --- a/deps/v8/src/runtime/runtime-numbers.cc +++ b/deps/v8/src/runtime/runtime-numbers.cc @@ -15,7 +15,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_IsValidSmi) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]); return isolate->heap()->ToBoolean(Smi::IsValid(number)); @@ -73,7 +73,7 @@ RUNTIME_FUNCTION(Runtime_StringParseInt) { // ES6 18.2.4 parseFloat(string) RUNTIME_FUNCTION(Runtime_StringParseFloat) { HandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); double value = @@ -86,7 +86,7 @@ RUNTIME_FUNCTION(Runtime_StringParseFloat) { RUNTIME_FUNCTION(Runtime_NumberToString) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0); return *isolate->factory()->NumberToString(number); @@ -95,7 +95,7 @@ RUNTIME_FUNCTION(Runtime_NumberToString) { RUNTIME_FUNCTION(Runtime_NumberToStringSkipCache) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0); return *isolate->factory()->NumberToString(number, false); @@ -106,7 +106,7 @@ RUNTIME_FUNCTION(Runtime_NumberToStringSkipCache) { // a small integer. RUNTIME_FUNCTION(Runtime_NumberToSmi) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(Object, obj, 0); if (obj->IsSmi()) { return obj; @@ -126,7 +126,7 @@ RUNTIME_FUNCTION(Runtime_NumberToSmi) { // compared lexicographically. RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) { SealHandleScope shs(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_SMI_ARG_CHECKED(x_value, 0); CONVERT_SMI_ARG_CHECKED(y_value, 1); @@ -200,14 +200,14 @@ RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) { RUNTIME_FUNCTION(Runtime_MaxSmi) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); return Smi::FromInt(Smi::kMaxValue); } RUNTIME_FUNCTION(Runtime_IsSmi) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(Object, obj, 0); return isolate->heap()->ToBoolean(obj->IsSmi()); } @@ -215,21 +215,21 @@ RUNTIME_FUNCTION(Runtime_IsSmi) { RUNTIME_FUNCTION(Runtime_GetRootNaN) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); return isolate->heap()->nan_value(); } RUNTIME_FUNCTION(Runtime_GetHoleNaNUpper) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); return *isolate->factory()->NewNumberFromUint(kHoleNanUpper32); } RUNTIME_FUNCTION(Runtime_GetHoleNaNLower) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); return *isolate->factory()->NewNumberFromUint(kHoleNanLower32); } diff --git a/deps/v8/src/runtime/runtime-object.cc b/deps/v8/src/runtime/runtime-object.cc index c7e9cf3c92..e3518d3e09 100644 --- a/deps/v8/src/runtime/runtime-object.cc +++ b/deps/v8/src/runtime/runtime-object.cc @@ -19,7 +19,7 @@ MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate, Handle<Object> object, Handle<Object> key, bool* is_found_out) { - if (object->IsUndefined(isolate) || object->IsNull(isolate)) { + if (object->IsNullOrUndefined(isolate)) { THROW_NEW_ERROR( isolate, NewTypeError(MessageTemplate::kNonObjectPropertyLoad, key, object), @@ -63,7 +63,7 @@ static MaybeHandle<Object> KeyedGetObjectProperty(Isolate* isolate, if (entry != GlobalDictionary::kNotFound) { DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry)); - if (cell->property_details().type() == DATA) { + if (cell->property_details().kind() == kData) { Object* value = cell->value(); if (!value->IsTheHole(isolate)) { return Handle<Object>(value, isolate); @@ -76,7 +76,7 @@ static MaybeHandle<Object> KeyedGetObjectProperty(Isolate* isolate, NameDictionary* dictionary = receiver->property_dictionary(); int entry = dictionary->FindEntry(key); if ((entry != NameDictionary::kNotFound) && - (dictionary->DetailsAt(entry).type() == DATA)) { + (dictionary->DetailsAt(entry).kind() == kData)) { Object* value = dictionary->ValueAt(entry); return Handle<Object>(value, isolate); } @@ -133,7 +133,7 @@ Maybe<bool> Runtime::DeleteObjectProperty(Isolate* isolate, // ES6 19.1.3.2 RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) { HandleScope scope(isolate); - Handle<Object> property = args.at<Object>(1); + Handle<Object> property = args.at(1); Handle<Name> key; uint32_t index; @@ -145,7 +145,7 @@ RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) { key_is_array_index = key->AsArrayIndex(&index); } - Handle<Object> object = args.at<Object>(0); + Handle<Object> object = args.at(0); if (object->IsJSObject()) { Handle<JSObject> js_obj = Handle<JSObject>::cast(object); @@ -199,7 +199,7 @@ RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) { key_is_array_index ? index < static_cast<uint32_t>(String::cast(*object)->length()) : key->Equals(isolate->heap()->length_string())); - } else if (object->IsNull(isolate) || object->IsUndefined(isolate)) { + } else if (object->IsNullOrUndefined(isolate)) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kUndefinedOrNullToObject)); } @@ -212,7 +212,7 @@ RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) { // an Object.create stub. RUNTIME_FUNCTION(Runtime_ObjectCreate) { HandleScope scope(isolate); - Handle<Object> prototype = args.at<Object>(0); + Handle<Object> prototype = args.at(0); if (!prototype->IsNull(isolate) && !prototype->IsJSReceiver()) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, prototype)); @@ -222,30 +222,8 @@ RUNTIME_FUNCTION(Runtime_ObjectCreate) { // function's initial map from the current native context. // TODO(bmeurer): Use a dedicated cache for Object.create; think about // slack tracking for Object.create. - Handle<Map> map(isolate->native_context()->object_function()->initial_map(), - isolate); - if (map->prototype() != *prototype) { - if (prototype->IsNull(isolate)) { - map = isolate->slow_object_with_null_prototype_map(); - } else if (prototype->IsJSObject()) { - Handle<JSObject> js_prototype = Handle<JSObject>::cast(prototype); - if (!js_prototype->map()->is_prototype_map()) { - JSObject::OptimizeAsPrototype(js_prototype, FAST_PROTOTYPE); - } - Handle<PrototypeInfo> info = - Map::GetOrCreatePrototypeInfo(js_prototype, isolate); - // TODO(verwaest): Use inobject slack tracking for this map. - if (info->HasObjectCreateMap()) { - map = handle(info->ObjectCreateMap(), isolate); - } else { - map = Map::CopyInitialMap(map); - Map::SetPrototype(map, prototype, FAST_PROTOTYPE); - PrototypeInfo::SetObjectCreateMap(info, map); - } - } else { - map = Map::TransitionToPrototype(map, prototype, REGULAR_PROTOTYPE); - } - } + Handle<Map> map = + Map::GetObjectCreateMap(Handle<HeapObject>::cast(prototype)); bool is_dictionary_map = map->is_dictionary_map(); Handle<FixedArray> object_properties; @@ -262,7 +240,7 @@ RUNTIME_FUNCTION(Runtime_ObjectCreate) { } // Define the properties if properties was specified and is not undefined. - Handle<Object> properties = args.at<Object>(1); + Handle<Object> properties = args.at(1); if (!properties->IsUndefined(isolate)) { RETURN_FAILURE_ON_EXCEPTION( isolate, JSReceiver::DefineProperties(isolate, object, properties)); @@ -276,7 +254,7 @@ MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate, Handle<Object> key, Handle<Object> value, LanguageMode language_mode) { - if (object->IsUndefined(isolate) || object->IsNull(isolate)) { + if (object->IsNullOrUndefined(isolate)) { THROW_NEW_ERROR( isolate, NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object), @@ -297,7 +275,7 @@ MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate, RUNTIME_FUNCTION(Runtime_GetPrototype) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0); RETURN_RESULT_OR_FAILURE(isolate, JSReceiver::GetPrototype(isolate, obj)); } @@ -305,7 +283,7 @@ RUNTIME_FUNCTION(Runtime_GetPrototype) { RUNTIME_FUNCTION(Runtime_InternalSetPrototype) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0); CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); MAYBE_RETURN( @@ -316,7 +294,7 @@ RUNTIME_FUNCTION(Runtime_InternalSetPrototype) { RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); CONVERT_SMI_ARG_CHECKED(properties, 1); // Conservative upper limit to prevent fuzz tests from going OOM. @@ -331,7 +309,7 @@ RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) { RUNTIME_FUNCTION(Runtime_GetProperty) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); @@ -343,7 +321,7 @@ RUNTIME_FUNCTION(Runtime_GetProperty) { // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric. RUNTIME_FUNCTION(Runtime_KeyedGetProperty) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0); CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1); @@ -503,7 +481,7 @@ RUNTIME_FUNCTION(Runtime_HasProperty) { RUNTIME_FUNCTION(Runtime_GetOwnPropertyKeys) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); CONVERT_SMI_ARG_CHECKED(filter_value, 1); PropertyFilter filter = static_cast<PropertyFilter>(filter_value); @@ -522,7 +500,7 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyKeys) { // args[0]: object RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); if (!args[0]->IsJSObject()) { return Smi::kZero; } @@ -538,7 +516,7 @@ RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) { RUNTIME_FUNCTION(Runtime_ToFastProperties) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); if (object->IsJSObject() && !object->IsJSGlobalObject()) { JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0, @@ -550,7 +528,7 @@ RUNTIME_FUNCTION(Runtime_ToFastProperties) { RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); return *isolate->factory()->NewHeapNumber(0); } @@ -566,7 +544,7 @@ RUNTIME_FUNCTION(Runtime_NewObject) { RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Map, initial_map, 0); initial_map->CompleteInobjectSlackTracking(); @@ -577,7 +555,7 @@ RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) { RUNTIME_FUNCTION(Runtime_LoadMutableDouble) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1); CHECK((index->value() & 1) == 1); @@ -596,7 +574,7 @@ RUNTIME_FUNCTION(Runtime_LoadMutableDouble) { RUNTIME_FUNCTION(Runtime_TryMigrateInstance) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); if (!object->IsJSObject()) return Smi::kZero; Handle<JSObject> js_object = Handle<JSObject>::cast(object); @@ -612,13 +590,13 @@ RUNTIME_FUNCTION(Runtime_TryMigrateInstance) { RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(Object, obj, 0); return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy()); } static bool IsValidAccessor(Isolate* isolate, Handle<Object> obj) { - return obj->IsUndefined(isolate) || obj->IsCallable() || obj->IsNull(isolate); + return obj->IsNullOrUndefined(isolate) || obj->IsCallable(); } @@ -630,7 +608,7 @@ static bool IsValidAccessor(Isolate* isolate, Handle<Object> obj) { // descriptor. RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) { HandleScope scope(isolate); - DCHECK(args.length() == 5); + DCHECK_EQ(5, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); CHECK(!obj->IsNull(isolate)); CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); @@ -648,14 +626,36 @@ RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) { RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) { HandleScope scope(isolate); - DCHECK(args.length() == 5); + DCHECK_EQ(6, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); - CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); - CONVERT_SMI_ARG_CHECKED(set_function_name, 4); + CONVERT_SMI_ARG_CHECKED(flag, 3); + CONVERT_ARG_HANDLE_CHECKED(TypeFeedbackVector, vector, 4); + CONVERT_SMI_ARG_CHECKED(index, 5); + + StoreDataPropertyInLiteralICNexus nexus(vector, vector->ToSlot(index)); + if (nexus.ic_state() == UNINITIALIZED) { + if (name->IsUniqueName()) { + nexus.ConfigureMonomorphic(name, handle(object->map())); + } else { + nexus.ConfigureMegamorphic(); + } + } else if (nexus.ic_state() == MONOMORPHIC) { + if (nexus.FindFirstMap() != object->map() || + nexus.GetFeedbackExtra() != *name) { + nexus.ConfigureMegamorphic(); + } + } + + DataPropertyInLiteralFlags flags = + static_cast<DataPropertyInLiteralFlag>(flag); - if (set_function_name) { + PropertyAttributes attrs = (flags & DataPropertyInLiteralFlag::kDontEnum) + ? PropertyAttributes::DONT_ENUM + : PropertyAttributes::NONE; + + if (flags & DataPropertyInLiteralFlag::kSetFunctionName) { DCHECK(value->IsJSFunction()); JSFunction::SetName(Handle<JSFunction>::cast(value), name, isolate->factory()->empty_string()); @@ -671,42 +671,10 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) { return *object; } -RUNTIME_FUNCTION(Runtime_DefineDataProperty) { - HandleScope scope(isolate); - DCHECK(args.length() == 5); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); - CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); - CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); - CONVERT_SMI_ARG_CHECKED(set_function_name, 4); - - if (set_function_name) { - DCHECK(value->IsJSFunction()); - JSFunction::SetName(Handle<JSFunction>::cast(value), name, - isolate->factory()->empty_string()); - } - - PropertyDescriptor desc; - desc.set_writable(!(attrs & ReadOnly)); - desc.set_enumerable(!(attrs & DontEnum)); - desc.set_configurable(!(attrs & DontDelete)); - desc.set_value(value); - - Maybe<bool> result = JSReceiver::DefineOwnProperty(isolate, receiver, name, - &desc, Object::DONT_THROW); - RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); - if (result.IsNothing()) { - DCHECK(isolate->has_pending_exception()); - return isolate->heap()->exception(); - } - - return *receiver; -} - // Return property without being observable by accessors or interceptors. RUNTIME_FUNCTION(Runtime_GetDataProperty) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); return *JSReceiver::GetDataProperty(object, name); @@ -714,17 +682,17 @@ RUNTIME_FUNCTION(Runtime_GetDataProperty) { RUNTIME_FUNCTION(Runtime_GetConstructorName) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); - CHECK(!object->IsUndefined(isolate) && !object->IsNull(isolate)); + CHECK(!object->IsNullOrUndefined(isolate)); Handle<JSReceiver> recv = Object::ToObject(isolate, object).ToHandleChecked(); return *JSReceiver::GetConstructorName(recv); } RUNTIME_FUNCTION(Runtime_HasFastPackedElements) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(HeapObject, obj, 0); return isolate->heap()->ToBoolean( IsFastPackedElementsKind(obj->map()->elements_kind())); @@ -733,7 +701,7 @@ RUNTIME_FUNCTION(Runtime_HasFastPackedElements) { RUNTIME_FUNCTION(Runtime_ValueOf) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(Object, obj, 0); if (!obj->IsJSValue()) return obj; return JSValue::cast(obj)->value(); @@ -742,7 +710,7 @@ RUNTIME_FUNCTION(Runtime_ValueOf) { RUNTIME_FUNCTION(Runtime_IsJSReceiver) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(Object, obj, 0); return isolate->heap()->ToBoolean(obj->IsJSReceiver()); } @@ -750,7 +718,7 @@ RUNTIME_FUNCTION(Runtime_IsJSReceiver) { RUNTIME_FUNCTION(Runtime_ClassOf) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(Object, obj, 0); if (!obj->IsJSReceiver()) return isolate->heap()->null_value(); return JSReceiver::cast(obj)->class_name(); @@ -759,7 +727,7 @@ RUNTIME_FUNCTION(Runtime_ClassOf) { RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); CONVERT_ARG_HANDLE_CHECKED(JSFunction, getter, 2); @@ -776,10 +744,26 @@ RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) { return isolate->heap()->undefined_value(); } +RUNTIME_FUNCTION(Runtime_CopyDataProperties) { + HandleScope scope(isolate); + DCHECK(args.length() == 2); + CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, source, 1); + + // 2. If source is undefined or null, let keys be an empty List. + if (source->IsUndefined(isolate) || source->IsNull(isolate)) { + return isolate->heap()->undefined_value(); + } + + MAYBE_RETURN( + JSReceiver::SetOrCopyDataProperties(isolate, target, source, false), + isolate->heap()->exception()); + return isolate->heap()->undefined_value(); +} RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); CONVERT_ARG_HANDLE_CHECKED(JSFunction, setter, 2); @@ -947,7 +931,7 @@ RUNTIME_FUNCTION(Runtime_IsAccessCheckNeeded) { RUNTIME_FUNCTION(Runtime_CreateDataProperty) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, o, 0); CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); diff --git a/deps/v8/src/runtime/runtime-promise.cc b/deps/v8/src/runtime/runtime-promise.cc index 226993a50e..ec340e5b0a 100644 --- a/deps/v8/src/runtime/runtime-promise.cc +++ b/deps/v8/src/runtime/runtime-promise.cc @@ -1,27 +1,28 @@ // 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. - #include "src/runtime/runtime-utils.h" #include "src/debug/debug.h" #include "src/elements.h" -#include "src/promise-utils.h" namespace v8 { namespace internal { namespace { -void PromiseRejectEvent(Isolate* isolate, Handle<JSReceiver> promise, +void PromiseRejectEvent(Isolate* isolate, Handle<JSPromise> promise, Handle<Object> rejected_promise, Handle<Object> value, bool debug_event) { + isolate->RunPromiseHook(PromiseHookType::kResolve, promise, + isolate->factory()->undefined_value()); + if (isolate->debug()->is_active() && debug_event) { isolate->debug()->OnPromiseReject(rejected_promise, value); } - Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol(); - // Do not report if we actually have a handler. - if (JSReceiver::GetDataProperty(promise, key)->IsUndefined(isolate)) { + + // Report only if we don't actually have a handler. + if (!promise->has_handler()) { isolate->ReportPromiseReject(Handle<JSObject>::cast(promise), value, v8::kPromiseRejectWithNoHandler); } @@ -30,9 +31,9 @@ void PromiseRejectEvent(Isolate* isolate, Handle<JSReceiver> promise, } // namespace RUNTIME_FUNCTION(Runtime_PromiseRejectEventFromStack) { - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); HandleScope scope(isolate); - CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); + CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); Handle<Object> rejected_promise = promise; @@ -41,142 +42,126 @@ RUNTIME_FUNCTION(Runtime_PromiseRejectEventFromStack) { // undefined, which will be interpreted by PromiseRejectEvent // as being a caught exception event. rejected_promise = isolate->GetPromiseOnStackOnThrow(); + isolate->debug()->OnAsyncTaskEvent( + debug::kDebugEnqueuePromiseReject, + isolate->debug()->NextAsyncTaskId(promise)); } PromiseRejectEvent(isolate, promise, rejected_promise, value, true); return isolate->heap()->undefined_value(); } +RUNTIME_FUNCTION(Runtime_ReportPromiseReject) { + DCHECK_EQ(2, args.length()); + HandleScope scope(isolate); + CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); + isolate->ReportPromiseReject(Handle<JSObject>::cast(promise), value, + v8::kPromiseRejectWithNoHandler); + return isolate->heap()->undefined_value(); +} + RUNTIME_FUNCTION(Runtime_PromiseRevokeReject) { - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); HandleScope scope(isolate); - CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); - Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol(); + CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); // At this point, no revocation has been issued before - CHECK(JSReceiver::GetDataProperty(promise, key)->IsUndefined(isolate)); + CHECK(!promise->has_handler()); isolate->ReportPromiseReject(promise, Handle<Object>(), v8::kPromiseHandlerAddedAfterReject); return isolate->heap()->undefined_value(); } namespace { -void EnqueuePromiseReactionJob(Isolate* isolate, Handle<Object> value, - Handle<Object> tasks, Handle<Object> deferred, - Handle<Object> status) { - Handle<Object> debug_id = isolate->factory()->undefined_value(); - Handle<Object> debug_name = isolate->factory()->undefined_value(); - if (isolate->debug()->is_active()) { - MaybeHandle<Object> maybe_result; - Handle<Object> argv[] = {deferred, status}; - maybe_result = Execution::TryCall( - isolate, isolate->promise_debug_get_info(), - isolate->factory()->undefined_value(), arraysize(argv), argv); - Handle<Object> result; - if ((maybe_result).ToHandle(&result)) { - CHECK(result->IsJSArray()); - Handle<JSArray> array = Handle<JSArray>::cast(result); - ElementsAccessor* accessor = array->GetElementsAccessor(); - DCHECK(accessor->HasElement(array, 0)); - DCHECK(accessor->HasElement(array, 1)); - debug_id = accessor->Get(array, 0); - debug_name = accessor->Get(array, 1); - } + +// In an async function, reuse the existing stack related to the outer +// Promise. Otherwise, e.g. in a direct call to then, save a new stack. +// Promises with multiple reactions with one or more of them being async +// functions will not get a good stack trace, as async functions require +// different stacks from direct Promise use, but we save and restore a +// stack once for all reactions. +// +// If this isn't a case of async function, we return false, otherwise +// we set the correct id and return true. +// +// TODO(littledan): Improve this case. +bool GetDebugIdForAsyncFunction(Isolate* isolate, + Handle<PromiseReactionJobInfo> info, + int* debug_id) { + // deferred_promise can be Undefined, FixedArray or userland promise object. + if (!info->deferred_promise()->IsJSPromise()) { + return false; } - Handle<PromiseReactionJobInfo> info = - isolate->factory()->NewPromiseReactionJobInfo(value, tasks, deferred, - debug_id, debug_name, - isolate->native_context()); - isolate->EnqueueMicrotask(info); -} -void PromiseFulfill(Isolate* isolate, Handle<JSReceiver> promise, - Handle<Smi> status, Handle<Object> value, - Handle<Symbol> reaction) { - Handle<Object> tasks = JSReceiver::GetDataProperty(promise, reaction); - if (!tasks->IsUndefined(isolate)) { - Handle<Object> deferred = JSReceiver::GetDataProperty( - promise, isolate->factory()->promise_deferred_reaction_symbol()); - EnqueuePromiseReactionJob(isolate, value, tasks, deferred, status); + Handle<JSPromise> deferred_promise(JSPromise::cast(info->deferred_promise()), + isolate); + Handle<Symbol> handled_by_symbol = + isolate->factory()->promise_handled_by_symbol(); + Handle<Object> handled_by_promise = + JSObject::GetDataProperty(deferred_promise, handled_by_symbol); + + if (!handled_by_promise->IsJSPromise()) { + return false; } -} -} // namespace -RUNTIME_FUNCTION(Runtime_PromiseReject) { - DCHECK(args.length() == 3); - HandleScope scope(isolate); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, promise, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, reason, 1); - CONVERT_BOOLEAN_ARG_CHECKED(debug_event, 2); + Handle<JSPromise> handled_by_promise_js = + Handle<JSPromise>::cast(handled_by_promise); + Handle<Symbol> async_stack_id_symbol = + isolate->factory()->promise_async_stack_id_symbol(); + Handle<Object> id = + JSObject::GetDataProperty(handled_by_promise_js, async_stack_id_symbol); - PromiseRejectEvent(isolate, promise, promise, reason, debug_event); + // id can be Undefined or Smi. + if (!id->IsSmi()) { + return false; + } - Handle<Smi> status = handle(Smi::FromInt(kPromiseRejected), isolate); - Handle<Symbol> reaction = - isolate->factory()->promise_reject_reactions_symbol(); - PromiseFulfill(isolate, promise, status, reason, reaction); - return isolate->heap()->undefined_value(); + *debug_id = Handle<Smi>::cast(id)->value(); + return true; } -RUNTIME_FUNCTION(Runtime_PromiseFulfill) { - DCHECK(args.length() == 4); - HandleScope scope(isolate); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, promise, 0); - CONVERT_ARG_HANDLE_CHECKED(Smi, status, 1); - CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); - CONVERT_ARG_HANDLE_CHECKED(Symbol, reaction, 3); - PromiseFulfill(isolate, promise, status, value, reaction); - return isolate->heap()->undefined_value(); +void SetDebugInfo(Isolate* isolate, Handle<JSPromise> promise, + Handle<PromiseReactionJobInfo> info, int status) { + int id = kDebugPromiseNoID; + if (!GetDebugIdForAsyncFunction(isolate, info, &id)) { + id = isolate->debug()->NextAsyncTaskId(promise); + DCHECK(status != v8::Promise::kPending); + } + info->set_debug_id(id); } +void EnqueuePromiseReactionJob(Isolate* isolate, Handle<JSPromise> promise, + Handle<PromiseReactionJobInfo> info, + int status) { + if (isolate->debug()->is_active()) { + SetDebugInfo(isolate, promise, info, status); + } + + isolate->EnqueueMicrotask(info); +} + +} // namespace + RUNTIME_FUNCTION(Runtime_EnqueuePromiseReactionJob) { HandleScope scope(isolate); - DCHECK(args.length() == 4); - CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, tasks, 1); - CONVERT_ARG_HANDLE_CHECKED(Object, deferred, 2); - CONVERT_ARG_HANDLE_CHECKED(Object, status, 3); - EnqueuePromiseReactionJob(isolate, value, tasks, deferred, status); + DCHECK_EQ(3, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); + CONVERT_ARG_HANDLE_CHECKED(PromiseReactionJobInfo, info, 1); + CONVERT_SMI_ARG_CHECKED(status, 2); + EnqueuePromiseReactionJob(isolate, promise, info, status); return isolate->heap()->undefined_value(); } RUNTIME_FUNCTION(Runtime_EnqueuePromiseResolveThenableJob) { HandleScope scope(isolate); - DCHECK(args.length() == 3); - CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, resolution, 1); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, then, 2); - - // TODO(gsathya): Add fast path for native promises with unmodified - // PromiseThen (which don't need these resolving functions, but - // instead can just call resolve/reject directly). - Handle<JSFunction> resolve, reject; - PromiseUtils::CreateResolvingFunctions( - isolate, promise, isolate->factory()->false_value(), &resolve, &reject); - - Handle<Object> debug_id, debug_name; - if (isolate->debug()->is_active()) { - debug_id = - handle(Smi::FromInt(isolate->GetNextDebugMicrotaskId()), isolate); - debug_name = isolate->factory()->PromiseResolveThenableJob_string(); - isolate->debug()->OnAsyncTaskEvent(isolate->factory()->enqueue_string(), - debug_id, - Handle<String>::cast(debug_name)); - } else { - debug_id = isolate->factory()->undefined_value(); - debug_name = isolate->factory()->undefined_value(); - } - - Handle<PromiseResolveThenableJobInfo> info = - isolate->factory()->NewPromiseResolveThenableJobInfo( - resolution, then, resolve, reject, debug_id, debug_name, - isolate->native_context()); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(PromiseResolveThenableJobInfo, info, 0); isolate->EnqueueMicrotask(info); - return isolate->heap()->undefined_value(); } RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0); isolate->EnqueueMicrotask(microtask); return isolate->heap()->undefined_value(); @@ -184,10 +169,79 @@ RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) { RUNTIME_FUNCTION(Runtime_RunMicrotasks) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); isolate->RunMicrotasks(); return isolate->heap()->undefined_value(); } +RUNTIME_FUNCTION(Runtime_PromiseStatus) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); + + return Smi::FromInt(promise->status()); +} + +RUNTIME_FUNCTION(Runtime_PromiseResult) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); + return promise->result(); +} + +RUNTIME_FUNCTION(Runtime_PromiseMarkAsHandled) { + SealHandleScope shs(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_CHECKED(JSPromise, promise, 0); + + promise->set_has_handler(true); + return isolate->heap()->undefined_value(); +} + +RUNTIME_FUNCTION(Runtime_PromiseMarkHandledHint) { + SealHandleScope shs(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_CHECKED(JSPromise, promise, 0); + + promise->set_handled_hint(true); + return isolate->heap()->undefined_value(); +} + +RUNTIME_FUNCTION(Runtime_PromiseHookInit) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, parent, 1); + isolate->RunPromiseHook(PromiseHookType::kInit, promise, parent); + return isolate->heap()->undefined_value(); +} + +RUNTIME_FUNCTION(Runtime_PromiseHookResolve) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); + isolate->RunPromiseHook(PromiseHookType::kResolve, promise, + isolate->factory()->undefined_value()); + return isolate->heap()->undefined_value(); +} + +RUNTIME_FUNCTION(Runtime_PromiseHookBefore) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); + isolate->RunPromiseHook(PromiseHookType::kBefore, promise, + isolate->factory()->undefined_value()); + return isolate->heap()->undefined_value(); +} + +RUNTIME_FUNCTION(Runtime_PromiseHookAfter) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); + isolate->RunPromiseHook(PromiseHookType::kAfter, promise, + isolate->factory()->undefined_value()); + return isolate->heap()->undefined_value(); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-proxy.cc b/deps/v8/src/runtime/runtime-proxy.cc index 87c7c9112b..de8231e2e9 100644 --- a/deps/v8/src/runtime/runtime-proxy.cc +++ b/deps/v8/src/runtime/runtime-proxy.cc @@ -44,7 +44,7 @@ RUNTIME_FUNCTION(Runtime_JSProxyCall) { // 6.a. Return Call(target, thisArgument, argumentsList). ScopedVector<Handle<Object>> argv(arguments_length); for (int i = 0; i < arguments_length; ++i) { - argv[i] = args.at<Object>(i + 1); + argv[i] = args.at(i + 1); } RETURN_RESULT_OR_FAILURE( isolate, Execution::Call(isolate, target, receiver, arguments_length, @@ -100,7 +100,7 @@ RUNTIME_FUNCTION(Runtime_JSProxyConstruct) { // 6.b. Return Construct(target, argumentsList, newTarget). ScopedVector<Handle<Object>> argv(arguments_length); for (int i = 0; i < arguments_length; ++i) { - argv[i] = args.at<Object>(i + 1); + argv[i] = args.at(i + 1); } RETURN_RESULT_OR_FAILURE( isolate, Execution::New(isolate, target, new_target, arguments_length, @@ -135,7 +135,7 @@ RUNTIME_FUNCTION(Runtime_JSProxyConstruct) { RUNTIME_FUNCTION(Runtime_IsJSProxy) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(Object, obj, 0); return isolate->heap()->ToBoolean(obj->IsJSProxy()); } @@ -143,7 +143,7 @@ RUNTIME_FUNCTION(Runtime_IsJSProxy) { RUNTIME_FUNCTION(Runtime_JSProxyGetHandler) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(JSProxy, proxy, 0); return proxy->handler(); } @@ -151,7 +151,7 @@ RUNTIME_FUNCTION(Runtime_JSProxyGetHandler) { RUNTIME_FUNCTION(Runtime_JSProxyGetTarget) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(JSProxy, proxy, 0); return proxy->target(); } @@ -159,7 +159,7 @@ RUNTIME_FUNCTION(Runtime_JSProxyGetTarget) { RUNTIME_FUNCTION(Runtime_JSProxyRevoke) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0); JSProxy::Revoke(proxy); return isolate->heap()->undefined_value(); diff --git a/deps/v8/src/runtime/runtime-regexp.cc b/deps/v8/src/runtime/runtime-regexp.cc index d572eedd31..9a489ecff8 100644 --- a/deps/v8/src/runtime/runtime-regexp.cc +++ b/deps/v8/src/runtime/runtime-regexp.cc @@ -652,7 +652,7 @@ MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString( if (!heap->lo_space()->Contains(*answer)) { heap->CreateFillerObjectAt(end_of_string, delta, ClearRecordedSlots::kNo); } - heap->AdjustLiveBytes(*answer, -delta, Heap::CONCURRENT_TO_SWEEPER); + heap->AdjustLiveBytes(*answer, -delta); return *answer; } @@ -685,7 +685,7 @@ Object* StringReplaceGlobalRegExpWithStringHelper( RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2); @@ -698,7 +698,7 @@ RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) { RUNTIME_FUNCTION(Runtime_StringSplit) { HandleScope handle_scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1); CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]); @@ -781,7 +781,7 @@ RUNTIME_FUNCTION(Runtime_StringSplit) { // RegExpCreate ( P, F ) RUNTIME_FUNCTION(Runtime_RegExpCreate) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, source_object, 0); Handle<String> source; @@ -806,7 +806,7 @@ RUNTIME_FUNCTION(Runtime_RegExpCreate) { RUNTIME_FUNCTION(Runtime_RegExpExec) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); CONVERT_INT32_ARG_CHECKED(index, 2); @@ -822,7 +822,7 @@ RUNTIME_FUNCTION(Runtime_RegExpExec) { RUNTIME_FUNCTION(Runtime_RegExpInternalReplace) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2); @@ -1237,7 +1237,7 @@ MUST_USE_RESULT MaybeHandle<String> RegExpReplace(Isolate* isolate, // This is only called for StringReplaceGlobalRegExpWithFunction. RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) { HandleScope handles(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); @@ -1259,7 +1259,7 @@ RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) { RUNTIME_FUNCTION(Runtime_StringReplaceNonGlobalRegExpWithFunction) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1); @@ -1269,16 +1269,232 @@ RUNTIME_FUNCTION(Runtime_StringReplaceNonGlobalRegExpWithFunction) { isolate, subject, regexp, replace)); } +namespace { + +// ES##sec-speciesconstructor +// SpeciesConstructor ( O, defaultConstructor ) +MUST_USE_RESULT MaybeHandle<Object> SpeciesConstructor( + Isolate* isolate, Handle<JSReceiver> recv, + Handle<JSFunction> default_ctor) { + Handle<Object> ctor_obj; + ASSIGN_RETURN_ON_EXCEPTION( + isolate, ctor_obj, + JSObject::GetProperty(recv, isolate->factory()->constructor_string()), + Object); + + if (ctor_obj->IsUndefined(isolate)) return default_ctor; + + if (!ctor_obj->IsJSReceiver()) { + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kConstructorNotReceiver), + Object); + } + + Handle<JSReceiver> ctor = Handle<JSReceiver>::cast(ctor_obj); + + Handle<Object> species; + ASSIGN_RETURN_ON_EXCEPTION( + isolate, species, + JSObject::GetProperty(ctor, isolate->factory()->species_symbol()), + Object); + + if (species->IsNullOrUndefined(isolate)) { + return default_ctor; + } + + if (species->IsConstructor()) return species; + + THROW_NEW_ERROR( + isolate, NewTypeError(MessageTemplate::kSpeciesNotConstructor), Object); +} + +MUST_USE_RESULT MaybeHandle<Object> ToUint32(Isolate* isolate, + Handle<Object> object, + uint32_t* out) { + if (object->IsUndefined(isolate)) { + *out = kMaxUInt32; + return object; + } + + Handle<Object> number; + ASSIGN_RETURN_ON_EXCEPTION(isolate, number, Object::ToNumber(object), Object); + *out = NumberToUint32(*number); + return object; +} + +Handle<JSArray> NewJSArrayWithElements(Isolate* isolate, + Handle<FixedArray> elems, + int num_elems) { + elems->Shrink(num_elems); + return isolate->factory()->NewJSArrayWithElements(elems); +} + +} // namespace + +// Slow path for: +// ES#sec-regexp.prototype-@@replace +// RegExp.prototype [ @@split ] ( string, limit ) +RUNTIME_FUNCTION(Runtime_RegExpSplit) { + HandleScope scope(isolate); + DCHECK_EQ(3, args.length()); + + DCHECK(args[1]->IsString()); + + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, recv, 0); + CONVERT_ARG_HANDLE_CHECKED(String, string, 1); + CONVERT_ARG_HANDLE_CHECKED(Object, limit_obj, 2); + + Factory* factory = isolate->factory(); + + Handle<JSFunction> regexp_fun = isolate->regexp_function(); + Handle<Object> ctor; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, ctor, SpeciesConstructor(isolate, recv, regexp_fun)); + + Handle<Object> flags_obj; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, flags_obj, JSObject::GetProperty(recv, factory->flags_string())); + + Handle<String> flags; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, flags, + Object::ToString(isolate, flags_obj)); + + Handle<String> u_str = factory->LookupSingleCharacterStringFromCode('u'); + const bool unicode = (String::IndexOf(isolate, flags, u_str, 0) >= 0); + + Handle<String> y_str = factory->LookupSingleCharacterStringFromCode('y'); + const bool sticky = (String::IndexOf(isolate, flags, y_str, 0) >= 0); + + Handle<String> new_flags = flags; + if (!sticky) { + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, new_flags, + factory->NewConsString(flags, y_str)); + } + + Handle<JSReceiver> splitter; + { + const int argc = 2; + + ScopedVector<Handle<Object>> argv(argc); + argv[0] = recv; + argv[1] = new_flags; + + Handle<JSFunction> ctor_fun = Handle<JSFunction>::cast(ctor); + Handle<Object> splitter_obj; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, splitter_obj, Execution::New(ctor_fun, argc, argv.start())); + + splitter = Handle<JSReceiver>::cast(splitter_obj); + } + + uint32_t limit; + RETURN_FAILURE_ON_EXCEPTION(isolate, ToUint32(isolate, limit_obj, &limit)); + + const uint32_t length = string->length(); + + if (limit == 0) return *factory->NewJSArray(0); + + if (length == 0) { + Handle<Object> result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, RegExpUtils::RegExpExec(isolate, splitter, string, + factory->undefined_value())); + + if (!result->IsNull(isolate)) return *factory->NewJSArray(0); + + Handle<FixedArray> elems = factory->NewUninitializedFixedArray(1); + elems->set(0, *string); + return *factory->NewJSArrayWithElements(elems); + } + + static const int kInitialArraySize = 8; + Handle<FixedArray> elems = factory->NewFixedArrayWithHoles(kInitialArraySize); + int num_elems = 0; + + uint32_t string_index = 0; + uint32_t prev_string_index = 0; + while (string_index < length) { + RETURN_FAILURE_ON_EXCEPTION( + isolate, RegExpUtils::SetLastIndex(isolate, splitter, string_index)); + + Handle<Object> result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, RegExpUtils::RegExpExec(isolate, splitter, string, + factory->undefined_value())); + + if (result->IsNull(isolate)) { + string_index = RegExpUtils::AdvanceStringIndex(isolate, string, + string_index, unicode); + continue; + } + + Handle<Object> last_index_obj; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, last_index_obj, RegExpUtils::GetLastIndex(isolate, splitter)); + + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, last_index_obj, Object::ToLength(isolate, last_index_obj)); + + const uint32_t end = + std::min(PositiveNumberToUint32(*last_index_obj), length); + if (end == prev_string_index) { + string_index = RegExpUtils::AdvanceStringIndex(isolate, string, + string_index, unicode); + continue; + } + + { + Handle<String> substr = + factory->NewSubString(string, prev_string_index, string_index); + elems = FixedArray::SetAndGrow(elems, num_elems++, substr); + if (static_cast<uint32_t>(num_elems) == limit) { + return *NewJSArrayWithElements(isolate, elems, num_elems); + } + } + + prev_string_index = end; + + Handle<Object> num_captures_obj; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, num_captures_obj, + Object::GetProperty(result, isolate->factory()->length_string())); + + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, num_captures_obj, Object::ToLength(isolate, num_captures_obj)); + const int num_captures = PositiveNumberToUint32(*num_captures_obj); + + for (int i = 1; i < num_captures; i++) { + Handle<Object> capture; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, capture, Object::GetElement(isolate, result, i)); + elems = FixedArray::SetAndGrow(elems, num_elems++, capture); + if (static_cast<uint32_t>(num_elems) == limit) { + return *NewJSArrayWithElements(isolate, elems, num_elems); + } + } + + string_index = prev_string_index; + } + + { + Handle<String> substr = + factory->NewSubString(string, prev_string_index, length); + elems = FixedArray::SetAndGrow(elems, num_elems++, substr); + } + + return *NewJSArrayWithElements(isolate, elems, num_elems); +} + // Slow path for: // ES#sec-regexp.prototype-@@replace // RegExp.prototype [ @@replace ] ( string, replaceValue ) RUNTIME_FUNCTION(Runtime_RegExpReplace) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, recv, 0); CONVERT_ARG_HANDLE_CHECKED(String, string, 1); - Handle<Object> replace_obj = args.at<Object>(2); + Handle<Object> replace_obj = args.at(2); Factory* factory = isolate->factory(); @@ -1291,7 +1507,7 @@ RUNTIME_FUNCTION(Runtime_RegExpReplace) { replace_obj)); } - const int length = string->length(); + const uint32_t length = string->length(); const bool functional_replace = replace_obj->IsCallable(); Handle<String> replace; @@ -1348,7 +1564,7 @@ RUNTIME_FUNCTION(Runtime_RegExpReplace) { // TODO(jgruber): Look into ReplacementStringBuilder instead. IncrementalStringBuilder builder(isolate); - int next_source_position = 0; + uint32_t next_source_position = 0; for (const auto& result : results) { Handle<Object> captures_length_obj; @@ -1359,8 +1575,7 @@ RUNTIME_FUNCTION(Runtime_RegExpReplace) { ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, captures_length_obj, Object::ToLength(isolate, captures_length_obj)); - const int captures_length = - std::max(Handle<Smi>::cast(captures_length_obj)->value(), 0); + const int captures_length = PositiveNumberToUint32(*captures_length_obj); Handle<Object> match_obj; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, match_obj, @@ -1381,8 +1596,8 @@ RUNTIME_FUNCTION(Runtime_RegExpReplace) { // 2^53 - 1 (at least for ToLength), we might actually need uint64_t here? ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, position_obj, Object::ToInteger(isolate, position_obj)); - const int position = - std::max(std::min(Handle<Smi>::cast(position_obj)->value(), length), 0); + const uint32_t position = + std::min(PositiveNumberToUint32(*position_obj), length); ZoneVector<Handle<Object>> captures(&zone); for (int n = 0; n < captures_length; n++) { @@ -1442,16 +1657,28 @@ RUNTIME_FUNCTION(Runtime_RegExpReplace) { RUNTIME_FUNCTION(Runtime_RegExpExecReThrow) { SealHandleScope shs(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); Object* exception = isolate->pending_exception(); isolate->clear_pending_exception(); return isolate->ReThrow(exception); } +RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) { + HandleScope scope(isolate); + DCHECK_EQ(3, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); + CONVERT_ARG_HANDLE_CHECKED(String, source, 1); + CONVERT_ARG_HANDLE_CHECKED(String, flags, 2); + + RETURN_FAILURE_ON_EXCEPTION(isolate, + JSRegExp::Initialize(regexp, source, flags)); + + return *regexp; +} RUNTIME_FUNCTION(Runtime_IsRegExp) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(Object, obj, 0); return isolate->heap()->ToBoolean(obj->IsJSRegExp()); } diff --git a/deps/v8/src/runtime/runtime-scopes.cc b/deps/v8/src/runtime/runtime-scopes.cc index 377799fe04..6dae7dd609 100644 --- a/deps/v8/src/runtime/runtime-scopes.cc +++ b/deps/v8/src/runtime/runtime-scopes.cc @@ -88,8 +88,7 @@ Object* DeclareGlobal( // function. PropertyDetails old_details = it.property_details(); if (old_details.IsReadOnly() || old_details.IsDontEnum() || - (it.state() == LookupIterator::ACCESSOR && - it.GetAccessors()->IsAccessorPair())) { + (it.state() == LookupIterator::ACCESSOR)) { // ECMA-262 section 15.1.11 GlobalDeclarationInstantiation 5.d: // If hasRestrictedGlobal is true, throw a SyntaxError exception. // ECMA-262 section 18.2.1.3 EvalDeclarationInstantiation 8.a.iv.1.b: @@ -130,18 +129,18 @@ Object* DeclareGlobal( return isolate->heap()->undefined_value(); } -Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> pairs, int flags, - Handle<TypeFeedbackVector> feedback_vector) { +Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations, + int flags, Handle<TypeFeedbackVector> feedback_vector) { HandleScope scope(isolate); Handle<JSGlobalObject> global(isolate->global_object()); Handle<Context> context(isolate->context()); // Traverse the name/value pairs and set the properties. - int length = pairs->length(); - FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i += 2, { - FeedbackVectorSlot slot(Smi::cast(pairs->get(i))->value()); - Handle<String> name(feedback_vector->GetName(slot), isolate); - Handle<Object> initial_value(pairs->get(i + 1), isolate); + int length = declarations->length(); + FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i += 3, { + Handle<String> name(String::cast(declarations->get(i)), isolate); + FeedbackVectorSlot slot(Smi::cast(declarations->get(i + 1))->value()); + Handle<Object> initial_value(declarations->get(i + 2), isolate); bool is_var = initial_value->IsUndefined(isolate); bool is_function = initial_value->IsSharedFunctionInfo(); @@ -186,11 +185,11 @@ RUNTIME_FUNCTION(Runtime_DeclareGlobals) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 0); + CONVERT_ARG_HANDLE_CHECKED(FixedArray, declarations, 0); CONVERT_SMI_ARG_CHECKED(flags, 1); CONVERT_ARG_HANDLE_CHECKED(TypeFeedbackVector, feedback_vector, 2); - return DeclareGlobals(isolate, pairs, flags, feedback_vector); + return DeclareGlobals(isolate, declarations, flags, feedback_vector); } // TODO(ishell): merge this with Runtime::kDeclareGlobals once interpreter @@ -199,13 +198,13 @@ RUNTIME_FUNCTION(Runtime_DeclareGlobalsForInterpreter) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 0); + CONVERT_ARG_HANDLE_CHECKED(FixedArray, declarations, 0); CONVERT_SMI_ARG_CHECKED(flags, 1); CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 2); Handle<TypeFeedbackVector> feedback_vector(closure->feedback_vector(), isolate); - return DeclareGlobals(isolate, pairs, flags, feedback_vector); + return DeclareGlobals(isolate, declarations, flags, feedback_vector); } RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) { @@ -224,15 +223,15 @@ namespace { Object* DeclareEvalHelper(Isolate* isolate, Handle<String> name, Handle<Object> value) { - // Declarations are always made in a function, native, or script context, or - // a declaration block scope. Since this is called from eval, the context - // passed is the context of the caller, which may be some nested context and - // not the declaration context. + // Declarations are always made in a function, native, eval, or script + // context, or a declaration block scope. Since this is called from eval, the + // context passed is the context of the caller, which may be some nested + // context and not the declaration context. Handle<Context> context_arg(isolate->context(), isolate); Handle<Context> context(context_arg->declaration_context(), isolate); DCHECK(context->IsFunctionContext() || context->IsNativeContext() || - context->IsScriptContext() || + context->IsScriptContext() || context->IsEvalContext() || (context->IsBlockContext() && context->has_extension())); bool is_function = value->IsJSFunction(); @@ -313,6 +312,8 @@ Object* DeclareEvalHelper(Isolate* isolate, Handle<String> name, } DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject()); } else { + // Sloppy eval will never have an extension object, as vars are hoisted out, + // and lets are known statically. DCHECK(context->IsFunctionContext()); object = isolate->factory()->NewJSObject(isolate->context_extension_function()); @@ -352,7 +353,7 @@ std::unique_ptr<Handle<Object>[]> GetCallerArguments(Isolate* isolate, // Find frame containing arguments passed to the caller. JavaScriptFrameIterator it(isolate); JavaScriptFrame* frame = it.frame(); - List<JSFunction*> functions(2); + List<SharedFunctionInfo*> functions(2); frame->GetFunctions(&functions); if (functions.length() > 1) { int inlined_jsframe_index = functions.length() - 1; @@ -377,6 +378,8 @@ std::unique_ptr<Handle<Object>[]> GetCallerArguments(Isolate* isolate, NewArray<Handle<Object>>(*total_argc)); bool should_deoptimize = false; for (int i = 0; i < argument_count; i++) { + // If we materialize any object, we should deoptimize the frame because we + // might alias an object that was eliminated by escape analysis. should_deoptimize = should_deoptimize || iter->IsMaterializedObject(); Handle<Object> value = iter->GetValue(); param_data[i] = value; @@ -384,7 +387,7 @@ std::unique_ptr<Handle<Object>[]> GetCallerArguments(Isolate* isolate, } if (should_deoptimize) { - translated_values.StoreMaterializedValuesAndDeopt(); + translated_values.StoreMaterializedValuesAndDeopt(frame); } return param_data; @@ -407,7 +410,7 @@ std::unique_ptr<Handle<Object>[]> GetCallerArguments(Isolate* isolate, template <typename T> Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee, T parameters, int argument_count) { - CHECK(!IsSubclassConstructor(callee->shared()->kind())); + CHECK(!IsDerivedConstructor(callee->shared()->kind())); DCHECK(callee->shared()->has_simple_parameters()); Handle<JSObject> result = isolate->factory()->NewArgumentsObject(callee, argument_count); @@ -517,7 +520,7 @@ class ParameterArguments BASE_EMBEDDED { RUNTIME_FUNCTION(Runtime_NewSloppyArguments_Generic) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); // This generic runtime function can also be used when the caller has been // inlined, we use the slow but accurate {GetCallerArguments}. @@ -582,7 +585,7 @@ RUNTIME_FUNCTION(Runtime_NewRestParameter) { RUNTIME_FUNCTION(Runtime_NewSloppyArguments) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); Object** parameters = reinterpret_cast<Object**>(args[1]); CONVERT_SMI_ARG_CHECKED(argument_count, 2); @@ -590,26 +593,45 @@ RUNTIME_FUNCTION(Runtime_NewSloppyArguments) { return *NewSloppyArguments(isolate, callee, argument_getter, argument_count); } +RUNTIME_FUNCTION(Runtime_NewArgumentsElements) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + Object** frame = reinterpret_cast<Object**>(args[0]); + CONVERT_SMI_ARG_CHECKED(length, 1); + Handle<FixedArray> result = + isolate->factory()->NewUninitializedFixedArray(length); + int const offset = length + 1; + DisallowHeapAllocation no_gc; + WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); + for (int index = 0; index < length; ++index) { + result->set(index, frame[offset - index], mode); + } + return *result; +} RUNTIME_FUNCTION(Runtime_NewClosure) { HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); Handle<Context> context(isolate->context(), isolate); - return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, - NOT_TENURED); + Handle<JSFunction> function = + isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, + NOT_TENURED); + return *function; } RUNTIME_FUNCTION(Runtime_NewClosure_Tenured) { HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); Handle<Context> context(isolate->context(), isolate); // The caller ensures that we pretenure closures that are assigned // directly to properties. - return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, - TENURED); + Handle<JSFunction> function = + isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, + TENURED); + return *function; } static Object* FindNameClash(Handle<ScopeInfo> scope_info, @@ -654,7 +676,7 @@ static Object* FindNameClash(Handle<ScopeInfo> scope_info, RUNTIME_FUNCTION(Runtime_NewScriptContext) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1); @@ -670,8 +692,9 @@ RUNTIME_FUNCTION(Runtime_NewScriptContext) { // Script contexts have a canonical empty function as their closure, not the // anonymous closure containing the global code. See // FullCodeGenerator::PushFunctionArgumentForContextAllocation. - Handle<JSFunction> closure( - function->shared()->IsBuiltin() ? *function : native_context->closure()); + Handle<JSFunction> closure(function->shared()->IsUserJavaScript() + ? native_context->closure() + : *function); Handle<Context> result = isolate->factory()->NewScriptContext(closure, scope_info); @@ -684,19 +707,19 @@ RUNTIME_FUNCTION(Runtime_NewScriptContext) { return *result; } - RUNTIME_FUNCTION(Runtime_NewFunctionContext) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); + CONVERT_SMI_ARG_CHECKED(scope_type, 1); DCHECK(function->context() == isolate->context()); int length = function->shared()->scope_info()->ContextLength(); - return *isolate->factory()->NewFunctionContext(length, function); + return *isolate->factory()->NewFunctionContext( + length, function, static_cast<ScopeType>(scope_type)); } - RUNTIME_FUNCTION(Runtime_PushWithContext) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); diff --git a/deps/v8/src/runtime/runtime-simd.cc b/deps/v8/src/runtime/runtime-simd.cc index 9542a4420a..067e9d680d 100644 --- a/deps/v8/src/runtime/runtime-simd.cc +++ b/deps/v8/src/runtime/runtime-simd.cc @@ -160,7 +160,7 @@ inline float MaxNumber(float a, float b) { RUNTIME_FUNCTION(Runtime_IsSimdValue) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); return isolate->heap()->ToBoolean(args[0]->IsSimd128Value()); } @@ -171,7 +171,7 @@ RUNTIME_FUNCTION(Runtime_IsSimdValue) { // TODO(gdeepti): Fix to use ToNumber conversion once polyfill is updated. #define CONVERT_SIMD_LANE_ARG_CHECKED(name, index, lanes) \ - Handle<Object> name_object = args.at<Object>(index); \ + Handle<Object> name_object = args.at(index); \ if (!name_object->IsNumber()) { \ THROW_NEW_ERROR_RETURN_FAILURE( \ isolate, NewTypeError(MessageTemplate::kInvalidSimdIndex)); \ @@ -194,7 +194,7 @@ RUNTIME_FUNCTION(Runtime_IsSimdValue) { #define SIMD_UNARY_OP(type, lane_type, lane_count, op, result) \ static const int kLaneCount = lane_count; \ - DCHECK(args.length() == 1); \ + DCHECK_EQ(1, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ lane_type lanes[kLaneCount]; \ for (int i = 0; i < kLaneCount; i++) { \ @@ -204,7 +204,7 @@ RUNTIME_FUNCTION(Runtime_IsSimdValue) { #define SIMD_BINARY_OP(type, lane_type, lane_count, op, result) \ static const int kLaneCount = lane_count; \ - DCHECK(args.length() == 2); \ + DCHECK_EQ(2, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 1); \ lane_type lanes[kLaneCount]; \ @@ -215,7 +215,7 @@ RUNTIME_FUNCTION(Runtime_IsSimdValue) { #define SIMD_RELATIONAL_OP(type, bool_type, lane_count, a, b, op, result) \ static const int kLaneCount = lane_count; \ - DCHECK(args.length() == 2); \ + DCHECK_EQ(2, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 1); \ bool lanes[kLaneCount]; \ @@ -228,10 +228,10 @@ RUNTIME_FUNCTION(Runtime_IsSimdValue) { // Common functions. -#define GET_NUMERIC_ARG(lane_type, name, index) \ - Handle<Object> a; \ - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \ - isolate, a, Object::ToNumber(args.at<Object>(index))); \ +#define GET_NUMERIC_ARG(lane_type, name, index) \ + Handle<Object> a; \ + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, a, \ + Object::ToNumber(args.at(index))); \ name = ConvertNumber<lane_type>(a->Number()); #define GET_BOOLEAN_ARG(lane_type, name, index) \ @@ -264,7 +264,7 @@ RUNTIME_FUNCTION(Runtime_IsSimdValue) { #define SIMD_EXTRACT_FUNCTION(type, lane_type, lane_count, extract, replace) \ RUNTIME_FUNCTION(Runtime_##type##ExtractLane) { \ HandleScope scope(isolate); \ - DCHECK(args.length() == 2); \ + DCHECK_EQ(2, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, lane_count); \ return *isolate->factory()->extract(a->get_lane(lane)); \ @@ -274,7 +274,7 @@ RUNTIME_FUNCTION(Runtime_IsSimdValue) { RUNTIME_FUNCTION(Runtime_##type##ReplaceLane) { \ static const int kLaneCount = lane_count; \ HandleScope scope(isolate); \ - DCHECK(args.length() == 3); \ + DCHECK_EQ(3, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, simd, 0); \ CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, kLaneCount); \ lane_type lanes[kLaneCount]; \ @@ -409,7 +409,7 @@ SIMD_MAXNUM_FUNCTION(Float32x4, float, 4) FUNCTION(Uint8x16, uint8_t, 8, 16) #define CONVERT_SHIFT_ARG_CHECKED(name, index) \ - Handle<Object> name_object = args.at<Object>(index); \ + Handle<Object> name_object = args.at(index); \ if (!name_object->IsNumber()) { \ THROW_NEW_ERROR_RETURN_FAILURE( \ isolate, NewTypeError(MessageTemplate::kInvalidSimdOperation)); \ @@ -422,7 +422,7 @@ SIMD_MAXNUM_FUNCTION(Float32x4, float, 4) RUNTIME_FUNCTION(Runtime_##type##ShiftLeftByScalar) { \ static const int kLaneCount = lane_count; \ HandleScope scope(isolate); \ - DCHECK(args.length() == 2); \ + DCHECK_EQ(2, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ lane_type lanes[kLaneCount] = {0}; \ @@ -438,7 +438,7 @@ SIMD_MAXNUM_FUNCTION(Float32x4, float, 4) RUNTIME_FUNCTION(Runtime_##type##ShiftRightByScalar) { \ static const int kLaneCount = lane_count; \ HandleScope scope(isolate); \ - DCHECK(args.length() == 2); \ + DCHECK_EQ(2, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ lane_type lanes[kLaneCount] = {0}; \ @@ -455,7 +455,7 @@ SIMD_MAXNUM_FUNCTION(Float32x4, float, 4) RUNTIME_FUNCTION(Runtime_##type##ShiftRightByScalar) { \ static const int kLaneCount = lane_count; \ HandleScope scope(isolate); \ - DCHECK(args.length() == 2); \ + DCHECK_EQ(2, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ shift &= lane_bits - 1; \ @@ -485,7 +485,7 @@ SIMD_UINT_TYPES(SIMD_LSR_FUNCTION) #define SIMD_ANY_FUNCTION(type, lane_count) \ RUNTIME_FUNCTION(Runtime_##type##AnyTrue) { \ HandleScope scope(isolate); \ - DCHECK(args.length() == 1); \ + DCHECK_EQ(1, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ bool result = false; \ for (int i = 0; i < lane_count; i++) { \ @@ -500,7 +500,7 @@ SIMD_UINT_TYPES(SIMD_LSR_FUNCTION) #define SIMD_ALL_FUNCTION(type, lane_count) \ RUNTIME_FUNCTION(Runtime_##type##AllTrue) { \ HandleScope scope(isolate); \ - DCHECK(args.length() == 1); \ + DCHECK_EQ(1, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ bool result = true; \ for (int i = 0; i < lane_count; i++) { \ @@ -742,7 +742,7 @@ SIMD_LOGICAL_TYPES(SIMD_NOT_FUNCTION) RUNTIME_FUNCTION(Runtime_##type##Select) { \ static const int kLaneCount = lane_count; \ HandleScope scope(isolate); \ - DCHECK(args.length() == 3); \ + DCHECK_EQ(3, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(bool_type, mask, 0); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 1); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 2); \ @@ -795,7 +795,7 @@ SIMD_SIGNED_TYPES(SIMD_NEG_FUNCTION) RUNTIME_FUNCTION(Runtime_##type##From##from_type) { \ static const int kLaneCount = lane_count; \ HandleScope scope(isolate); \ - DCHECK(args.length() == 1); \ + DCHECK_EQ(1, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(from_type, a, 0); \ lane_type lanes[kLaneCount]; \ for (int i = 0; i < kLaneCount; i++) { \ @@ -860,7 +860,7 @@ SIMD_FROM_TYPES(SIMD_FROM_FUNCTION) RUNTIME_FUNCTION(Runtime_##type##From##from_type##Bits) { \ static const int kLaneCount = lane_count; \ HandleScope scope(isolate); \ - DCHECK(args.length() == 1); \ + DCHECK_EQ(1, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(from_type, a, 0); \ lane_type lanes[kLaneCount]; \ a->CopyBits(lanes); \ @@ -880,23 +880,23 @@ SIMD_FROM_BITS_TYPES(SIMD_FROM_BITS_FUNCTION) FUNCTION(Int32x4, int32_t, 4) \ FUNCTION(Uint32x4, uint32_t, 4) -#define SIMD_COERCE_INDEX(name, i) \ - Handle<Object> length_object, number_object; \ - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( \ - isolate, length_object, Object::ToLength(isolate, args.at<Object>(i))); \ - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number_object, \ - Object::ToNumber(args.at<Object>(i))); \ - if (number_object->Number() != length_object->Number()) { \ - THROW_NEW_ERROR_RETURN_FAILURE( \ - isolate, NewTypeError(MessageTemplate::kInvalidSimdIndex)); \ - } \ +#define SIMD_COERCE_INDEX(name, i) \ + Handle<Object> length_object, number_object; \ + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, length_object, \ + Object::ToLength(isolate, args.at(i))); \ + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number_object, \ + Object::ToNumber(args.at(i))); \ + if (number_object->Number() != length_object->Number()) { \ + THROW_NEW_ERROR_RETURN_FAILURE( \ + isolate, NewTypeError(MessageTemplate::kInvalidSimdIndex)); \ + } \ int32_t name = number_object->Number(); // Common Load and Store Functions #define SIMD_LOAD(type, lane_type, lane_count, count, result) \ static const int kLaneCount = lane_count; \ - DCHECK(args.length() == 2); \ + DCHECK_EQ(2, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(JSTypedArray, tarray, 0); \ SIMD_COERCE_INDEX(index, 1); \ size_t bpe = tarray->element_size(); \ @@ -916,7 +916,7 @@ SIMD_FROM_BITS_TYPES(SIMD_FROM_BITS_FUNCTION) #define SIMD_STORE(type, lane_type, lane_count, count, a) \ static const int kLaneCount = lane_count; \ - DCHECK(args.length() == 3); \ + DCHECK_EQ(3, args.length()); \ CONVERT_SIMD_ARG_HANDLE_THROW(JSTypedArray, tarray, 0); \ CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 2); \ SIMD_COERCE_INDEX(index, 1); \ diff --git a/deps/v8/src/runtime/runtime-strings.cc b/deps/v8/src/runtime/runtime-strings.cc index 328bdceb37..31d9f1fc6e 100644 --- a/deps/v8/src/runtime/runtime-strings.cc +++ b/deps/v8/src/runtime/runtime-strings.cc @@ -7,6 +7,7 @@ #include "src/arguments.h" #include "src/regexp/jsregexp-inl.h" #include "src/string-builder.h" +#include "src/string-case.h" #include "src/string-search.h" namespace v8 { @@ -60,7 +61,7 @@ MaybeHandle<String> StringReplaceOneCharWithString( RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); CONVERT_ARG_HANDLE_CHECKED(String, search, 1); CONVERT_ARG_HANDLE_CHECKED(String, replace, 2); @@ -86,23 +87,38 @@ RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) { return isolate->StackOverflow(); } - +// ES6 #sec-string.prototype.indexof +// String.prototype.indexOf(searchString [, position]) RUNTIME_FUNCTION(Runtime_StringIndexOf) { HandleScope scope(isolate); - DCHECK(args.length() == 3); - return String::IndexOf(isolate, args.at<Object>(0), args.at<Object>(1), - args.at<Object>(2)); + DCHECK_EQ(3, args.length()); + return String::IndexOf(isolate, args.at(0), args.at(1), args.at(2)); +} + +// ES6 #sec-string.prototype.indexof +// String.prototype.indexOf(searchString, position) +// Fast version that assumes that does not perform conversions of the incoming +// arguments. +RUNTIME_FUNCTION(Runtime_StringIndexOfUnchecked) { + HandleScope scope(isolate); + DCHECK_EQ(3, args.length()); + Handle<String> receiver_string = args.at<String>(0); + Handle<String> search_string = args.at<String>(1); + int index = std::min(std::max(args.smi_at(2), 0), receiver_string->length()); + + return Smi::FromInt(String::IndexOf(isolate, receiver_string, search_string, + static_cast<uint32_t>(index))); } RUNTIME_FUNCTION(Runtime_StringLastIndexOf) { HandleScope handle_scope(isolate); - return String::LastIndexOf(isolate, args.at<Object>(0), args.at<Object>(1), + return String::LastIndexOf(isolate, args.at(0), args.at(1), isolate->factory()->undefined_value()); } RUNTIME_FUNCTION(Runtime_SubString) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, string, 0); int start, end; @@ -134,7 +150,7 @@ RUNTIME_FUNCTION(Runtime_SubString) { RUNTIME_FUNCTION(Runtime_StringAdd) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, obj1, 0); CONVERT_ARG_HANDLE_CHECKED(Object, obj2, 1); isolate->counters()->string_add_runtime()->Increment(); @@ -151,7 +167,7 @@ RUNTIME_FUNCTION(Runtime_StringAdd) { RUNTIME_FUNCTION(Runtime_InternalizeString) { HandleScope handles(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, string, 0); return *isolate->factory()->InternalizeString(string); } @@ -159,7 +175,7 @@ RUNTIME_FUNCTION(Runtime_InternalizeString) { RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) { HandleScope handle_scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]); @@ -200,7 +216,7 @@ RUNTIME_FUNCTION(Runtime_StringCompare) { RUNTIME_FUNCTION(Runtime_StringBuilderConcat) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); int32_t array_length; if (!args[1]->ToInt32(&array_length)) { @@ -270,7 +286,7 @@ RUNTIME_FUNCTION(Runtime_StringBuilderConcat) { RUNTIME_FUNCTION(Runtime_StringBuilderJoin) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); int32_t array_length; if (!args[1]->ToInt32(&array_length)) { @@ -411,7 +427,7 @@ static void JoinSparseArrayWithSeparator(FixedArray* elements, RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0); CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); CONVERT_ARG_HANDLE_CHECKED(String, separator, 2); @@ -529,7 +545,7 @@ static int CopyCachedOneByteCharsToArray(Heap* heap, const uint8_t* chars, // For example, "foo" => ["f", "o", "o"]. RUNTIME_FUNCTION(Runtime_StringToArray) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, s, 0); CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); @@ -679,122 +695,6 @@ MUST_USE_RESULT static Object* ConvertCaseHelper( } } - -static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF; -static const uintptr_t kAsciiMask = kOneInEveryByte << 7; - -// Given a word and two range boundaries returns a word with high bit -// set in every byte iff the corresponding input byte was strictly in -// the range (m, n). All the other bits in the result are cleared. -// This function is only useful when it can be inlined and the -// boundaries are statically known. -// Requires: all bytes in the input word and the boundaries must be -// ASCII (less than 0x7F). -static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) { - // Use strict inequalities since in edge cases the function could be - // further simplified. - DCHECK(0 < m && m < n); - // Has high bit set in every w byte less than n. - uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; - // Has high bit set in every w byte greater than m. - uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); - return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); -} - - -#ifdef DEBUG -static bool CheckFastAsciiConvert(char* dst, const char* src, int length, - bool changed, bool is_to_lower) { - bool expected_changed = false; - for (int i = 0; i < length; i++) { - if (dst[i] == src[i]) continue; - expected_changed = true; - if (is_to_lower) { - DCHECK('A' <= src[i] && src[i] <= 'Z'); - DCHECK(dst[i] == src[i] + ('a' - 'A')); - } else { - DCHECK('a' <= src[i] && src[i] <= 'z'); - DCHECK(dst[i] == src[i] - ('a' - 'A')); - } - } - return (expected_changed == changed); -} -#endif - - -template <class Converter> -static bool FastAsciiConvert(char* dst, const char* src, int length, - bool* changed_out) { -#ifdef DEBUG - char* saved_dst = dst; - const char* saved_src = src; -#endif - DisallowHeapAllocation no_gc; - // We rely on the distance between upper and lower case letters - // being a known power of 2. - DCHECK('a' - 'A' == (1 << 5)); - // Boundaries for the range of input characters than require conversion. - static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1; - static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1; - bool changed = false; - uintptr_t or_acc = 0; - const char* const limit = src + length; - - // dst is newly allocated and always aligned. - DCHECK(IsAligned(reinterpret_cast<intptr_t>(dst), sizeof(uintptr_t))); - // Only attempt processing one word at a time if src is also aligned. - if (IsAligned(reinterpret_cast<intptr_t>(src), sizeof(uintptr_t))) { - // Process the prefix of the input that requires no conversion one aligned - // (machine) word at a time. - while (src <= limit - sizeof(uintptr_t)) { - const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src); - or_acc |= w; - if (AsciiRangeMask(w, lo, hi) != 0) { - changed = true; - break; - } - *reinterpret_cast<uintptr_t*>(dst) = w; - src += sizeof(uintptr_t); - dst += sizeof(uintptr_t); - } - // Process the remainder of the input performing conversion when - // required one word at a time. - while (src <= limit - sizeof(uintptr_t)) { - const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src); - or_acc |= w; - uintptr_t m = AsciiRangeMask(w, lo, hi); - // The mask has high (7th) bit set in every byte that needs - // conversion and we know that the distance between cases is - // 1 << 5. - *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2); - src += sizeof(uintptr_t); - dst += sizeof(uintptr_t); - } - } - // Process the last few bytes of the input (or the whole input if - // unaligned access is not supported). - while (src < limit) { - char c = *src; - or_acc |= c; - if (lo < c && c < hi) { - c ^= (1 << 5); - changed = true; - } - *dst = c; - ++src; - ++dst; - } - - if ((or_acc & kAsciiMask) != 0) return false; - - DCHECK(CheckFastAsciiConvert(saved_dst, saved_src, length, changed, - Converter::kIsToLower)); - - *changed_out = changed; - return true; -} - - template <class Converter> MUST_USE_RESULT static Object* ConvertCase( Handle<String> s, Isolate* isolate, @@ -818,12 +718,13 @@ MUST_USE_RESULT static Object* ConvertCase( String::FlatContent flat_content = s->GetFlatContent(); DCHECK(flat_content.IsFlat()); bool has_changed_character = false; - bool is_ascii = FastAsciiConvert<Converter>( + int index_to_first_unprocessed = FastAsciiConvert<Converter::kIsToLower>( reinterpret_cast<char*>(result->GetChars()), reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()), length, &has_changed_character); // If not ASCII, we discard the result and take the 2 byte path. - if (is_ascii) return has_changed_character ? *result : *s; + if (index_to_first_unprocessed == length) + return has_changed_character ? *result : *s; } Handle<SeqString> result; // Same length as input. @@ -857,7 +758,6 @@ RUNTIME_FUNCTION(Runtime_StringToLowerCase) { return ConvertCase(s, isolate, isolate->runtime_state()->to_lower_mapping()); } - RUNTIME_FUNCTION(Runtime_StringToUpperCase) { HandleScope scope(isolate); DCHECK_EQ(args.length(), 1); @@ -955,7 +855,7 @@ RUNTIME_FUNCTION(Runtime_StringNotEqual) { RUNTIME_FUNCTION(Runtime_FlattenString) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, str, 0); return *String::Flatten(str); } @@ -982,7 +882,7 @@ RUNTIME_FUNCTION(Runtime_ExternalStringGetChar) { RUNTIME_FUNCTION(Runtime_StringCharCodeAt) { SealHandleScope shs(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); if (!args[0]->IsString()) return isolate->heap()->undefined_value(); if (!args[1]->IsNumber()) return isolate->heap()->undefined_value(); if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value(); diff --git a/deps/v8/src/runtime/runtime-symbol.cc b/deps/v8/src/runtime/runtime-symbol.cc index 300a6439b1..2eaef63bbf 100644 --- a/deps/v8/src/runtime/runtime-symbol.cc +++ b/deps/v8/src/runtime/runtime-symbol.cc @@ -14,7 +14,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_CreateSymbol) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); CHECK(name->IsString() || name->IsUndefined(isolate)); Handle<Symbol> symbol = isolate->factory()->NewSymbol(); @@ -25,7 +25,7 @@ RUNTIME_FUNCTION(Runtime_CreateSymbol) { RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); CHECK(name->IsString() || name->IsUndefined(isolate)); Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol(); @@ -36,7 +36,7 @@ RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) { RUNTIME_FUNCTION(Runtime_SymbolDescription) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(Symbol, symbol, 0); return symbol->name(); } @@ -56,16 +56,9 @@ RUNTIME_FUNCTION(Runtime_SymbolDescriptiveString) { } -RUNTIME_FUNCTION(Runtime_SymbolRegistry) { - HandleScope scope(isolate); - DCHECK(args.length() == 0); - return *isolate->GetSymbolRegistry(); -} - - RUNTIME_FUNCTION(Runtime_SymbolIsPrivate) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(Symbol, symbol, 0); return isolate->heap()->ToBoolean(symbol->is_private()); } diff --git a/deps/v8/src/runtime/runtime-test.cc b/deps/v8/src/runtime/runtime-test.cc index 7054192a0f..bea7245c35 100644 --- a/deps/v8/src/runtime/runtime-test.cc +++ b/deps/v8/src/runtime/runtime-test.cc @@ -19,12 +19,51 @@ #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects.h" +namespace { +struct WasmCompileControls { + uint32_t MaxWasmBufferSize = std::numeric_limits<uint32_t>::max(); + bool AllowAnySizeForAsync = true; +}; + +// We need per-isolate controls, because we sometimes run tests in multiple +// isolates +// concurrently. +// To avoid upsetting the static initializer count, we lazy initialize this. +v8::base::LazyInstance<std::map<v8::Isolate*, WasmCompileControls>>::type + g_PerIsolateWasmControls = LAZY_INSTANCE_INITIALIZER; + +bool IsWasmCompileAllowed(v8::Isolate* isolate, v8::Local<v8::Value> value, + bool is_async) { + DCHECK_GT(g_PerIsolateWasmControls.Get().count(isolate), 0); + const WasmCompileControls& ctrls = g_PerIsolateWasmControls.Get().at(isolate); + return (is_async && ctrls.AllowAnySizeForAsync) || + (v8::Local<v8::ArrayBuffer>::Cast(value)->ByteLength() <= + ctrls.MaxWasmBufferSize); +} + +// Use the compile controls for instantiation, too +bool IsWasmInstantiateAllowed(v8::Isolate* isolate, + v8::Local<v8::Value> module_or_bytes, + v8::MaybeLocal<v8::Value> ffi, bool is_async) { + DCHECK_GT(g_PerIsolateWasmControls.Get().count(isolate), 0); + const WasmCompileControls& ctrls = g_PerIsolateWasmControls.Get().at(isolate); + if (is_async && ctrls.AllowAnySizeForAsync) return true; + if (!module_or_bytes->IsWebAssemblyCompiledModule()) { + return IsWasmCompileAllowed(isolate, module_or_bytes, is_async); + } + v8::Local<v8::WasmCompiledModule> module = + v8::Local<v8::WasmCompiledModule>::Cast(module_or_bytes); + return static_cast<uint32_t>(module->GetWasmWireBytes()->Length()) <= + ctrls.MaxWasmBufferSize; +} +} // namespace + namespace v8 { namespace internal { RUNTIME_FUNCTION(Runtime_ConstructDouble) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]); CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]); uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo; @@ -33,7 +72,7 @@ RUNTIME_FUNCTION(Runtime_ConstructDouble) { RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); // This function is used by fuzzers to get coverage in compiler. // Ignore calls on non-function objects to avoid runtime errors. @@ -48,7 +87,7 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) { // TODO(turbofan): Deoptimization is not supported yet. if (function->code()->is_turbofanned() && - function->shared()->asm_function() && !FLAG_turbo_asm_deoptimization) { + function->shared()->asm_function()) { return isolate->heap()->undefined_value(); } @@ -60,7 +99,7 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) { RUNTIME_FUNCTION(Runtime_DeoptimizeNow) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); Handle<JSFunction> function; @@ -74,7 +113,7 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeNow) { // TODO(turbofan): Deoptimization is not supported yet. if (function->code()->is_turbofanned() && - function->shared()->asm_function() && !FLAG_turbo_asm_deoptimization) { + function->shared()->asm_function()) { return isolate->heap()->undefined_value(); } @@ -86,7 +125,7 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeNow) { RUNTIME_FUNCTION(Runtime_RunningInSimulator) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); #if defined(USE_SIMULATOR) return isolate->heap()->true_value(); #else @@ -97,7 +136,7 @@ RUNTIME_FUNCTION(Runtime_RunningInSimulator) { RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); return isolate->heap()->ToBoolean( isolate->concurrent_recompilation_enabled()); } @@ -127,6 +166,12 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) { return isolate->heap()->undefined_value(); } + // If function isn't compiled, compile it now. + if (!function->shared()->is_compiled() && + !Compiler::Compile(function, Compiler::CLEAR_EXCEPTION)) { + return isolate->heap()->undefined_value(); + } + // If the function is already optimized, just return. if (function->IsOptimized()) return isolate->heap()->undefined_value(); @@ -146,7 +191,7 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) { RUNTIME_FUNCTION(Runtime_InterpretFunctionOnNextCall) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0); if (!function_object->IsJSFunction()) { return isolate->heap()->undefined_value(); @@ -164,13 +209,19 @@ RUNTIME_FUNCTION(Runtime_InterpretFunctionOnNextCall) { RUNTIME_FUNCTION(Runtime_BaselineFunctionOnNextCall) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0); if (!function_object->IsJSFunction()) { return isolate->heap()->undefined_value(); } Handle<JSFunction> function = Handle<JSFunction>::cast(function_object); + // If function isn't compiled, compile it now. + if (!function->shared()->is_compiled() && + !Compiler::Compile(function, Compiler::CLEAR_EXCEPTION)) { + return isolate->heap()->undefined_value(); + } + // Do not tier down if we are already on optimized code. Replacing optimized // code without actual deoptimization can lead to funny bugs. if (function->code()->kind() != Code::OPTIMIZED_FUNCTION && @@ -216,7 +267,7 @@ RUNTIME_FUNCTION(Runtime_OptimizeOsr) { RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(JSFunction, function, 0); function->shared()->set_disable_optimization_reason( kOptimizationDisabledForTest); @@ -277,7 +328,7 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) { RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) { - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); if (FLAG_block_concurrent_recompilation && isolate->concurrent_recompilation_enabled()) { isolate->optimizing_compile_dispatcher()->Unblock(); @@ -288,19 +339,23 @@ RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) { RUNTIME_FUNCTION(Runtime_GetOptimizationCount) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); return Smi::FromInt(function->shared()->opt_count()); } +static void ReturnThis(const v8::FunctionCallbackInfo<v8::Value>& args) { + args.GetReturnValue().Set(args.This()); +} RUNTIME_FUNCTION(Runtime_GetUndetectable) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); Local<v8::ObjectTemplate> desc = v8::ObjectTemplate::New(v8_isolate); desc->MarkAsUndetectable(); + desc->SetCallAsFunctionHandler(ReturnThis); Local<v8::Object> obj; if (!desc->NewInstance(v8_isolate->GetCurrentContext()).ToLocal(&obj)) { return nullptr; @@ -323,7 +378,7 @@ static void call_as_function(const v8::FunctionCallbackInfo<v8::Value>& args) { // parameters when it is called. RUNTIME_FUNCTION(Runtime_GetCallable) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(v8_isolate); Local<ObjectTemplate> instance_template = t->InstanceTemplate(); @@ -339,7 +394,7 @@ RUNTIME_FUNCTION(Runtime_GetCallable) { RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); function->ClearTypeFeedbackInfo(); Code* unoptimized = function->shared()->code(); @@ -412,9 +467,29 @@ RUNTIME_FUNCTION(Runtime_CheckWasmWrapperElision) { return isolate->heap()->ToBoolean(count == 1); } +RUNTIME_FUNCTION(Runtime_SetWasmCompileControls) { + HandleScope scope(isolate); + v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); + CHECK(args.length() == 2); + CONVERT_ARG_HANDLE_CHECKED(Smi, block_size, 0); + CONVERT_BOOLEAN_ARG_CHECKED(allow_async, 1); + WasmCompileControls& ctrl = (*g_PerIsolateWasmControls.Pointer())[v8_isolate]; + ctrl.AllowAnySizeForAsync = allow_async; + ctrl.MaxWasmBufferSize = static_cast<uint32_t>(block_size->value()); + isolate->set_allow_wasm_compile_callback(IsWasmCompileAllowed); + return isolate->heap()->undefined_value(); +} + +RUNTIME_FUNCTION(Runtime_SetWasmInstantiateControls) { + HandleScope scope(isolate); + CHECK(args.length() == 0); + isolate->set_allow_wasm_instantiate_callback(IsWasmInstantiateAllowed); + return isolate->heap()->undefined_value(); +} + RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); isolate->heap()->NotifyContextDisposed(true); return isolate->heap()->undefined_value(); } @@ -444,7 +519,7 @@ RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) { RUNTIME_FUNCTION(Runtime_DebugPrint) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); OFStream os(stdout); #ifdef DEBUG @@ -475,7 +550,7 @@ RUNTIME_FUNCTION(Runtime_DebugPrint) { RUNTIME_FUNCTION(Runtime_DebugTrace) { SealHandleScope shs(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); isolate->PrintStack(stdout); return isolate->heap()->undefined_value(); } @@ -485,7 +560,7 @@ RUNTIME_FUNCTION(Runtime_DebugTrace) { // very slowly for very deeply nested ConsStrings. For debugging use only. RUNTIME_FUNCTION(Runtime_GlobalPrint) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(String, string, 0); StringCharacterStream stream(string); @@ -501,7 +576,7 @@ RUNTIME_FUNCTION(Runtime_SystemBreak) { // The code below doesn't create handles, but when breaking here in GDB // having a handle scope might be useful. HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); base::OS::DebugBreak(); return isolate->heap()->undefined_value(); } @@ -510,7 +585,7 @@ RUNTIME_FUNCTION(Runtime_SystemBreak) { // Sets a v8 flag. RUNTIME_FUNCTION(Runtime_SetFlags) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(String, arg, 0); std::unique_ptr<char[]> flags = arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); @@ -521,7 +596,7 @@ RUNTIME_FUNCTION(Runtime_SetFlags) { RUNTIME_FUNCTION(Runtime_Abort) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_SMI_ARG_CHECKED(message_id, 0); const char* message = GetBailoutReason(static_cast<BailoutReason>(message_id)); @@ -535,7 +610,7 @@ RUNTIME_FUNCTION(Runtime_Abort) { RUNTIME_FUNCTION(Runtime_AbortJS) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, message, 0); base::OS::PrintError("abort: %s\n", message->ToCString().get()); isolate->PrintStack(stderr); @@ -546,14 +621,14 @@ RUNTIME_FUNCTION(Runtime_AbortJS) { RUNTIME_FUNCTION(Runtime_NativeScriptsCount) { - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); return Smi::FromInt(Natives::GetBuiltinsCount()); } // TODO(5510): remove this. RUNTIME_FUNCTION(Runtime_GetV8Version) { HandleScope scope(isolate); - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); const char* version_string = v8::V8::GetVersion(); @@ -564,7 +639,7 @@ RUNTIME_FUNCTION(Runtime_GetV8Version) { RUNTIME_FUNCTION(Runtime_DisassembleFunction) { HandleScope scope(isolate); #ifdef DEBUG - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); // Get the function and make sure it is compiled. CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0); if (!Compiler::Compile(func, Compiler::KEEP_EXCEPTION)) { @@ -628,7 +703,7 @@ RUNTIME_FUNCTION(Runtime_TraceTailCall) { RUNTIME_FUNCTION(Runtime_GetExceptionDetails) { HandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, exception_obj, 0); Factory* factory = isolate->factory(); @@ -653,7 +728,7 @@ RUNTIME_FUNCTION(Runtime_GetExceptionDetails) { RUNTIME_FUNCTION(Runtime_HaveSameMap) { SealHandleScope shs(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_CHECKED(JSObject, obj1, 0); CONVERT_ARG_CHECKED(JSObject, obj2, 1); return isolate->heap()->ToBoolean(obj1->map() == obj2->map()); @@ -662,41 +737,48 @@ RUNTIME_FUNCTION(Runtime_HaveSameMap) { RUNTIME_FUNCTION(Runtime_InNewSpace) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(Object, obj, 0); return isolate->heap()->ToBoolean(isolate->heap()->InNewSpace(obj)); } -static bool IsAsmWasmCode(Isolate* isolate, Handle<JSFunction> function) { +RUNTIME_FUNCTION(Runtime_IsAsmWasmCode) { + SealHandleScope shs(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_CHECKED(JSFunction, function, 0); if (!function->shared()->HasAsmWasmData()) { // Doesn't have wasm data. - return false; + return isolate->heap()->false_value(); } if (function->shared()->code() != isolate->builtins()->builtin(Builtins::kInstantiateAsmJs)) { // Hasn't been compiled yet. - return false; + return isolate->heap()->false_value(); } - return true; + return isolate->heap()->true_value(); } -RUNTIME_FUNCTION(Runtime_IsAsmWasmCode) { +namespace { +bool DisallowCodegenFromStringsCallback(v8::Local<v8::Context> context) { + return false; +} +} + +RUNTIME_FUNCTION(Runtime_DisallowCodegenFromStrings) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); - // TODO(mstarzinger): --always-opt should still allow asm.js->wasm, - // but currently does not. For now, pretend asm.js->wasm is on for - // this case. Be more accurate once this is corrected. - return isolate->heap()->ToBoolean( - ((FLAG_always_opt || FLAG_prepare_always_opt) && FLAG_validate_asm) || - IsAsmWasmCode(isolate, function)); + DCHECK_EQ(0, args.length()); + v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); + v8_isolate->SetAllowCodeGenerationFromStringsCallback( + DisallowCodegenFromStringsCallback); + return isolate->heap()->undefined_value(); } -RUNTIME_FUNCTION(Runtime_IsNotAsmWasmCode) { +RUNTIME_FUNCTION(Runtime_IsWasmCode) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); - return isolate->heap()->ToBoolean(!IsAsmWasmCode(isolate, function)); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_CHECKED(JSFunction, function, 0); + bool is_js_to_wasm = function->code()->kind() == Code::JS_TO_WASM_FUNCTION; + return isolate->heap()->ToBoolean(is_js_to_wasm); } #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ @@ -736,15 +818,18 @@ RUNTIME_FUNCTION(Runtime_SpeciesProtector) { return isolate->heap()->ToBoolean(isolate->IsArraySpeciesLookupChainIntact()); } +#define CONVERT_ARG_HANDLE_CHECKED_2(Type, name, index) \ + CHECK(Type::Is##Type(args[index])); \ + Handle<Type> name = args.at<Type>(index); + // Take a compiled wasm module, serialize it and copy the buffer into an array // buffer, which is then returned. RUNTIME_FUNCTION(Runtime_SerializeWasmModule) { HandleScope shs(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(JSObject, module_obj, 0); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED_2(WasmModuleObject, module_obj, 0); - Handle<FixedArray> orig = - handle(FixedArray::cast(module_obj->GetInternalField(0))); + Handle<WasmCompiledModule> orig(module_obj->compiled_module()); std::unique_ptr<ScriptData> data = WasmCompiledModuleSerializer::SerializeWasmModule(isolate, orig); void* buff = isolate->array_buffer_allocator()->Allocate(data->length()); @@ -758,7 +843,7 @@ RUNTIME_FUNCTION(Runtime_SerializeWasmModule) { // Return undefined if unsuccessful. RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) { HandleScope shs(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 0); CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, wire_bytes, 1); @@ -793,8 +878,8 @@ RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) { RUNTIME_FUNCTION(Runtime_ValidateWasmInstancesChain) { HandleScope shs(isolate); - DCHECK(args.length() == 2); - CONVERT_ARG_HANDLE_CHECKED(JSObject, module_obj, 0); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED_2(WasmModuleObject, module_obj, 0); CONVERT_ARG_HANDLE_CHECKED(Smi, instance_count, 1); wasm::testing::ValidateInstancesChain(isolate, module_obj, instance_count->value()); @@ -803,17 +888,34 @@ RUNTIME_FUNCTION(Runtime_ValidateWasmInstancesChain) { RUNTIME_FUNCTION(Runtime_ValidateWasmModuleState) { HandleScope shs(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(JSObject, module_obj, 0); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED_2(WasmModuleObject, module_obj, 0); wasm::testing::ValidateModuleState(isolate, module_obj); return isolate->heap()->ToBoolean(true); } RUNTIME_FUNCTION(Runtime_ValidateWasmOrphanedInstance) { HandleScope shs(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(JSObject, instance_obj, 0); - wasm::testing::ValidateOrphanedInstance(isolate, instance_obj); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED_2(WasmInstanceObject, instance, 0); + wasm::testing::ValidateOrphanedInstance(isolate, instance); + return isolate->heap()->ToBoolean(true); +} + +RUNTIME_FUNCTION(Runtime_Verify) { + HandleScope shs(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); +#ifdef VERIFY_HEAP + object->ObjectVerify(); +#else + CHECK(object->IsObject()); + if (object->IsHeapObject()) { + CHECK(HeapObject::cast(*object)->map()->IsMap()); + } else { + CHECK(object->IsSmi()); + } +#endif return isolate->heap()->ToBoolean(true); } diff --git a/deps/v8/src/runtime/runtime-typedarray.cc b/deps/v8/src/runtime/runtime-typedarray.cc index cb0e062d14..d5e394c345 100644 --- a/deps/v8/src/runtime/runtime-typedarray.cc +++ b/deps/v8/src/runtime/runtime-typedarray.cc @@ -15,7 +15,7 @@ namespace internal { RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0); return holder->byte_length(); } @@ -23,7 +23,7 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) { RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0); CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1); CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2); @@ -56,7 +56,7 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) { RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0); if (array_buffer->backing_store() == NULL) { CHECK(Smi::kZero == array_buffer->byte_length()); @@ -97,7 +97,7 @@ void Runtime::ArrayIdToTypeAndSize(int arrayId, ExternalArrayType* array_type, RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) { HandleScope scope(isolate); - DCHECK(args.length() == 6); + DCHECK_EQ(6, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); CONVERT_SMI_ARG_CHECKED(arrayId, 1); CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2); @@ -179,7 +179,7 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) { // Returns true if backing store was initialized or false otherwise. RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) { HandleScope scope(isolate); - DCHECK(args.length() == 4); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); CONVERT_SMI_ARG_CHECKED(arrayId, 1); CONVERT_ARG_HANDLE_CHECKED(Object, source, 2); @@ -310,7 +310,7 @@ enum TypedArraySetResultCodes { RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) { HandleScope scope(isolate); - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); if (!args[0]->IsJSTypedArray()) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kNotTypedArray)); @@ -369,7 +369,7 @@ RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) { RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) { - DCHECK(args.length() == 0); + DCHECK_EQ(0, args.length()); DCHECK_OBJECT_SIZE(FLAG_typed_array_max_size_in_heap + FixedTypedArrayBase::kDataOffset); return Smi::FromInt(FLAG_typed_array_max_size_in_heap); @@ -378,14 +378,14 @@ RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) { RUNTIME_FUNCTION(Runtime_IsTypedArray) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); return isolate->heap()->ToBoolean(args[0]->IsJSTypedArray()); } RUNTIME_FUNCTION(Runtime_IsSharedTypedArray) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); return isolate->heap()->ToBoolean( args[0]->IsJSTypedArray() && JSTypedArray::cast(args[0])->GetBuffer()->is_shared()); @@ -394,7 +394,7 @@ RUNTIME_FUNCTION(Runtime_IsSharedTypedArray) { RUNTIME_FUNCTION(Runtime_IsSharedIntegerTypedArray) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); if (!args[0]->IsJSTypedArray()) { return isolate->heap()->false_value(); } @@ -409,7 +409,7 @@ RUNTIME_FUNCTION(Runtime_IsSharedIntegerTypedArray) { RUNTIME_FUNCTION(Runtime_IsSharedInteger32TypedArray) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(1, args.length()); if (!args[0]->IsJSTypedArray()) { return isolate->heap()->false_value(); } diff --git a/deps/v8/src/runtime/runtime-utils.h b/deps/v8/src/runtime/runtime-utils.h index 147efed092..8c7714a0f6 100644 --- a/deps/v8/src/runtime/runtime-utils.h +++ b/deps/v8/src/runtime/runtime-utils.h @@ -6,6 +6,7 @@ #define V8_RUNTIME_RUNTIME_UTILS_H_ #include "src/base/logging.h" +#include "src/globals.h" #include "src/runtime/runtime.h" namespace v8 { @@ -24,7 +25,7 @@ namespace internal { #define CONVERT_NUMBER_ARG_HANDLE_CHECKED(name, index) \ CHECK(args[index]->IsNumber()); \ - Handle<Object> name = args.at<Object>(index); + Handle<Object> name = args.at(index); // Cast the given object to a boolean and store it in a variable with // the given name. If the object is not a boolean we crash safely. @@ -47,10 +48,10 @@ namespace internal { // Cast the given argument to a size_t and store its value in a variable with // the given name. If the argument is not a size_t we crash safely. -#define CONVERT_SIZE_ARG_CHECKED(name, index) \ - CHECK(args[index]->IsNumber()); \ - Handle<Object> name##_object = args.at<Object>(index); \ - size_t name = 0; \ +#define CONVERT_SIZE_ARG_CHECKED(name, index) \ + CHECK(args[index]->IsNumber()); \ + Handle<Object> name##_object = args.at(index); \ + size_t name = 0; \ CHECK(TryNumberToSize(*name##_object, &name)); // Call the specified converter on the object *comand store the result in diff --git a/deps/v8/src/runtime/runtime-wasm.cc b/deps/v8/src/runtime/runtime-wasm.cc index ab69046c45..3ae5b92da1 100644 --- a/deps/v8/src/runtime/runtime-wasm.cc +++ b/deps/v8/src/runtime/runtime-wasm.cc @@ -14,52 +14,115 @@ #include "src/objects-inl.h" #include "src/v8memory.h" #include "src/wasm/wasm-module.h" +#include "src/wasm/wasm-objects.h" +#include "src/wasm/wasm-opcodes.h" namespace v8 { namespace internal { +namespace { +Handle<WasmInstanceObject> GetWasmInstanceOnStackTop(Isolate* isolate) { + DisallowHeapAllocation no_allocation; + const Address entry = Isolate::c_entry_fp(isolate->thread_local_top()); + Address pc = + Memory::Address_at(entry + StandardFrameConstants::kCallerPCOffset); + Code* code = isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code; + DCHECK_EQ(Code::WASM_FUNCTION, code->kind()); + WasmInstanceObject* owning_instance = wasm::GetOwningWasmInstance(code); + CHECK_NOT_NULL(owning_instance); + return handle(owning_instance, isolate); +} +} // namespace + RUNTIME_FUNCTION(Runtime_WasmMemorySize) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); - Handle<JSObject> module_instance; - { - // Get the module JSObject - DisallowHeapAllocation no_allocation; - const Address entry = Isolate::c_entry_fp(isolate->thread_local_top()); - Address pc = - Memory::Address_at(entry + StandardFrameConstants::kCallerPCOffset); - Code* code = - isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code; - Object* owning_instance = wasm::GetOwningWasmInstance(code); - CHECK_NOT_NULL(owning_instance); - module_instance = handle(JSObject::cast(owning_instance), isolate); - } + Handle<WasmInstanceObject> instance = GetWasmInstanceOnStackTop(isolate); return *isolate->factory()->NewNumberFromInt( - wasm::GetInstanceMemorySize(isolate, module_instance)); + wasm::GetInstanceMemorySize(isolate, instance)); } RUNTIME_FUNCTION(Runtime_WasmGrowMemory) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_UINT32_ARG_CHECKED(delta_pages, 0); - Handle<JSObject> module_instance; - { - // Get the module JSObject - DisallowHeapAllocation no_allocation; - const Address entry = Isolate::c_entry_fp(isolate->thread_local_top()); - Address pc = - Memory::Address_at(entry + StandardFrameConstants::kCallerPCOffset); - Code* code = - isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code; - Object* owning_instance = wasm::GetOwningWasmInstance(code); - CHECK_NOT_NULL(owning_instance); - module_instance = handle(JSObject::cast(owning_instance), isolate); - } + Handle<WasmInstanceObject> instance = GetWasmInstanceOnStackTop(isolate); return *isolate->factory()->NewNumberFromInt( - wasm::GrowInstanceMemory(isolate, module_instance, delta_pages)); + wasm::GrowMemory(isolate, instance, delta_pages)); +} + +Object* ThrowRuntimeError(Isolate* isolate, int message_id, int byte_offset, + bool patch_source_position) { + HandleScope scope(isolate); + Handle<Object> error_obj = isolate->factory()->NewWasmRuntimeError( + static_cast<MessageTemplate::Template>(message_id)); + + if (!patch_source_position) { + return isolate->Throw(*error_obj); + } + + // For wasm traps, the byte offset (a.k.a source position) can not be + // determined from relocation info, since the explicit checks for traps + // converge in one singe block which calls this runtime function. + // We hence pass the byte offset explicitely, and patch it into the top-most + // frame (a wasm frame) on the collected stack trace. + // TODO(wasm): This implementation is temporary, see bug #5007: + // https://bugs.chromium.org/p/v8/issues/detail?id=5007 + Handle<JSObject> error = Handle<JSObject>::cast(error_obj); + Handle<Object> stack_trace_obj = JSReceiver::GetDataProperty( + error, isolate->factory()->stack_trace_symbol()); + // Patch the stack trace (array of <receiver, function, code, position>). + if (stack_trace_obj->IsJSArray()) { + Handle<FrameArray> stack_elements( + FrameArray::cast(JSArray::cast(*stack_trace_obj)->elements())); + DCHECK(stack_elements->Code(0)->kind() == AbstractCode::WASM_FUNCTION); + DCHECK(stack_elements->Offset(0)->value() >= 0); + stack_elements->SetOffset(0, Smi::FromInt(-1 - byte_offset)); + } + + // Patch the detailed stack trace (array of JSObjects with various + // properties). + Handle<Object> detailed_stack_trace_obj = JSReceiver::GetDataProperty( + error, isolate->factory()->detailed_stack_trace_symbol()); + if (detailed_stack_trace_obj->IsJSArray()) { + Handle<FixedArray> stack_elements( + FixedArray::cast(JSArray::cast(*detailed_stack_trace_obj)->elements())); + DCHECK_GE(stack_elements->length(), 1); + Handle<JSObject> top_frame(JSObject::cast(stack_elements->get(0))); + Handle<String> wasm_offset_key = + isolate->factory()->InternalizeOneByteString( + STATIC_CHAR_VECTOR("column")); + LookupIterator it(top_frame, wasm_offset_key, top_frame, + LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR); + if (it.IsFound()) { + DCHECK(JSReceiver::GetDataProperty(&it)->IsSmi()); + // Make column number 1-based here. + Maybe<bool> data_set = JSReceiver::SetDataProperty( + &it, handle(Smi::FromInt(byte_offset + 1), isolate)); + DCHECK(data_set.IsJust() && data_set.FromJust() == true); + USE(data_set); + } + } + + return isolate->Throw(*error_obj); +} + +RUNTIME_FUNCTION(Runtime_ThrowWasmError) { + DCHECK_EQ(2, args.length()); + CONVERT_SMI_ARG_CHECKED(message_id, 0); + CONVERT_SMI_ARG_CHECKED(byte_offset, 1); + return ThrowRuntimeError(isolate, message_id, byte_offset, true); } +#define DECLARE_ENUM(name) \ + RUNTIME_FUNCTION(Runtime_ThrowWasm##name) { \ + int message_id = wasm::WasmOpcodes::TrapReasonToMessageId(wasm::k##name); \ + return ThrowRuntimeError(isolate, message_id, 0, false); \ + } +FOREACH_WASM_TRAPREASON(DECLARE_ENUM) +#undef DECLARE_ENUM + RUNTIME_FUNCTION(Runtime_WasmThrowTypeError) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); @@ -89,5 +152,28 @@ RUNTIME_FUNCTION(Runtime_WasmGetCaughtExceptionValue) { return exception; } +RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) { + DCHECK(args.length() == 3); + HandleScope scope(isolate); + CONVERT_ARG_HANDLE_CHECKED(JSObject, instance_obj, 0); + CONVERT_NUMBER_CHECKED(int32_t, func_index, Int32, args[1]); + CONVERT_ARG_HANDLE_CHECKED(Object, arg_buffer_obj, 2); + CHECK(WasmInstanceObject::IsWasmInstanceObject(*instance_obj)); + + // The arg buffer is the raw pointer to the caller's stack. It looks like a + // Smi (lowest bit not set, as checked by IsSmi), but is no valid Smi. We just + // cast it back to the raw pointer. + CHECK(!arg_buffer_obj->IsHeapObject()); + CHECK(arg_buffer_obj->IsSmi()); + uint8_t* arg_buffer = reinterpret_cast<uint8_t*>(*arg_buffer_obj); + + Handle<WasmInstanceObject> instance = + Handle<WasmInstanceObject>::cast(instance_obj); + Handle<WasmDebugInfo> debug_info = + WasmInstanceObject::GetOrCreateDebugInfo(instance); + WasmDebugInfo::RunInterpreter(debug_info, func_index, arg_buffer); + return isolate->heap()->undefined_value(); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime.cc b/deps/v8/src/runtime/runtime.cc index 9d1cd39c5d..38f1805656 100644 --- a/deps/v8/src/runtime/runtime.cc +++ b/deps/v8/src/runtime/runtime.cc @@ -10,6 +10,7 @@ #include "src/handles-inl.h" #include "src/heap/heap.h" #include "src/isolate.h" +#include "src/objects-inl.h" #include "src/runtime/runtime-utils.h" namespace v8 { diff --git a/deps/v8/src/runtime/runtime.h b/deps/v8/src/runtime/runtime.h index 8e2e83c37e..7eadbe2c09 100644 --- a/deps/v8/src/runtime/runtime.h +++ b/deps/v8/src/runtime/runtime.h @@ -45,7 +45,6 @@ namespace internal { F(EstimateNumberOfElements, 1, 1) \ F(GetArrayKeys, 2, 1) \ F(NewArray, -1 /* >= 3 */, 1) \ - F(ArrayPush, -1, 1) \ F(FunctionBind, -1, 1) \ F(NormalizeElements, 1, 1) \ F(GrowArrayElements, 2, 1) \ @@ -75,22 +74,24 @@ namespace internal { F(AtomicsWake, 3, 1) \ F(AtomicsNumWaitersForTesting, 2, 1) -#define FOR_EACH_INTRINSIC_CLASSES(F) \ - F(ThrowNonMethodError, 0, 1) \ - F(ThrowUnsupportedSuperError, 0, 1) \ - F(ThrowConstructorNonCallableError, 1, 1) \ - F(ThrowArrayNotSubclassableError, 0, 1) \ - F(ThrowStaticPrototypeError, 0, 1) \ - F(ThrowIfStaticPrototype, 1, 1) \ - F(HomeObjectSymbol, 0, 1) \ - F(DefineClass, 4, 1) \ - F(LoadFromSuper, 3, 1) \ - F(LoadKeyedFromSuper, 3, 1) \ - F(StoreToSuper_Strict, 4, 1) \ - F(StoreToSuper_Sloppy, 4, 1) \ - F(StoreKeyedToSuper_Strict, 4, 1) \ - F(StoreKeyedToSuper_Sloppy, 4, 1) \ - F(GetSuperConstructor, 1, 1) +#define FOR_EACH_INTRINSIC_CLASSES(F) \ + F(ThrowUnsupportedSuperError, 0, 1) \ + F(ThrowConstructorNonCallableError, 1, 1) \ + F(ThrowStaticPrototypeError, 0, 1) \ + F(ThrowSuperAlreadyCalledError, 0, 1) \ + F(ThrowNotSuperConstructor, 2, 1) \ + F(HomeObjectSymbol, 0, 1) \ + F(DefineClass, 4, 1) \ + F(InstallClassNameAccessor, 1, 1) \ + F(InstallClassNameAccessorWithCheck, 1, 1) \ + F(LoadFromSuper, 3, 1) \ + F(LoadKeyedFromSuper, 3, 1) \ + F(StoreToSuper_Strict, 4, 1) \ + F(StoreToSuper_Sloppy, 4, 1) \ + F(StoreKeyedToSuper_Strict, 4, 1) \ + F(StoreKeyedToSuper_Sloppy, 4, 1) \ + F(GetSuperConstructor, 1, 1) \ + F(NewWithSpread, -1, 1) #define FOR_EACH_INTRINSIC_COLLECTIONS(F) \ F(StringGetRawHashField, 1, 1) \ @@ -147,7 +148,7 @@ namespace internal { F(DebugGetInternalProperties, 1, 1) \ F(DebugGetPropertyDetails, 2, 1) \ F(DebugGetProperty, 2, 1) \ - F(DebugPropertyTypeFromDetails, 1, 1) \ + F(DebugPropertyKindFromDetails, 1, 1) \ F(DebugPropertyAttributesFromDetails, 1, 1) \ F(CheckExecutionState, 1, 1) \ F(GetFrameCount, 1, 1) \ @@ -169,9 +170,10 @@ namespace internal { F(ChangeBreakOnException, 2, 1) \ F(IsBreakOnException, 1, 1) \ F(PrepareStep, 2, 1) \ + F(PrepareStepFrame, 0, 1) \ F(ClearStepping, 0, 1) \ - F(DebugEvaluate, 6, 1) \ - F(DebugEvaluateGlobal, 4, 1) \ + F(DebugEvaluate, 4, 1) \ + F(DebugEvaluateGlobal, 2, 1) \ F(DebugGetLoadedScripts, 0, 1) \ F(DebugReferencedBy, 3, 1) \ F(DebugConstructedBy, 2, 1) \ @@ -190,14 +192,17 @@ namespace internal { F(ScriptLocationFromLine, 4, 1) \ F(ScriptLocationFromLine2, 4, 1) \ F(ScriptPositionInfo, 3, 1) \ + F(ScriptPositionInfo2, 3, 1) \ F(ScriptSourceLine, 2, 1) \ - F(DebugPrepareStepInIfStepping, 1, 1) \ + F(DebugOnFunctionCall, 1, 1) \ F(DebugPrepareStepInSuspendedGenerator, 0, 1) \ - F(DebugRecordAsyncFunction, 1, 1) \ + F(DebugRecordGenerator, 1, 1) \ F(DebugPushPromise, 1, 1) \ F(DebugPopPromise, 0, 1) \ - F(DebugNextMicrotaskId, 0, 1) \ - F(DebugAsyncTaskEvent, 3, 1) \ + F(DebugPromiseReject, 2, 1) \ + F(DebugNextAsyncTaskId, 1, 1) \ + F(DebugAsyncEventEnqueueRecurring, 2, 1) \ + F(DebugAsyncFunctionPromiseCreated, 1, 1) \ F(DebugIsActive, 0, 1) \ F(DebugBreakInOptimizedCode, 0, 1) @@ -210,11 +215,9 @@ namespace internal { F(ForInNext, 4, 1) #define FOR_EACH_INTRINSIC_INTERPRETER(F) \ - F(InterpreterNewClosure, 2, 1) \ + F(InterpreterNewClosure, 4, 1) \ F(InterpreterTraceBytecodeEntry, 3, 1) \ F(InterpreterTraceBytecodeExit, 3, 1) \ - F(InterpreterClearPendingMessage, 0, 1) \ - F(InterpreterSetPendingMessage, 1, 1) \ F(InterpreterAdvanceBytecodeOffset, 2, 1) #define FOR_EACH_INTRINSIC_FUNCTION(F) \ @@ -241,10 +244,10 @@ namespace internal { #define FOR_EACH_INTRINSIC_GENERATOR(F) \ F(CreateJSGeneratorObject, 2, 1) \ - F(SuspendJSGeneratorObject, 1, 1) \ F(GeneratorClose, 1, 1) \ F(GeneratorGetFunction, 1, 1) \ F(GeneratorGetReceiver, 1, 1) \ + F(GeneratorGetContext, 1, 1) \ F(GeneratorGetInputOrDebugPos, 1, 1) \ F(GeneratorGetContinuation, 1, 1) \ F(GeneratorGetSourcePosition, 1, 1) \ @@ -258,15 +261,12 @@ namespace internal { F(GetLanguageTagVariants, 1, 1) \ F(IsInitializedIntlObject, 1, 1) \ F(IsInitializedIntlObjectOfType, 2, 1) \ - F(MarkAsInitializedIntlObjectOfType, 3, 1) \ - F(GetImplFromInitializedIntlObject, 1, 1) \ + F(MarkAsInitializedIntlObjectOfType, 2, 1) \ F(CreateDateTimeFormat, 3, 1) \ F(InternalDateFormat, 2, 1) \ F(InternalDateFormatToParts, 2, 1) \ - F(InternalDateParse, 2, 1) \ F(CreateNumberFormat, 3, 1) \ F(InternalNumberFormat, 2, 1) \ - F(InternalNumberParse, 2, 1) \ F(CreateCollator, 3, 1) \ F(InternalCompare, 3, 1) \ F(StringNormalize, 2, 1) \ @@ -292,8 +292,8 @@ namespace internal { F(CheckIsBootstrapping, 0, 1) \ F(CreateListFromArrayLike, 1, 1) \ F(EnqueueMicrotask, 1, 1) \ - F(EnqueuePromiseReactionJob, 4, 1) \ - F(EnqueuePromiseResolveThenableJob, 3, 1) \ + F(EnqueuePromiseReactionJob, 3, 1) \ + F(EnqueuePromiseResolveThenableJob, 1, 1) \ F(GetAndResetRuntimeCallStats, -1 /* <= 2 */, 1) \ F(ExportExperimentalFromRuntime, 1, 1) \ F(ExportFromRuntime, 1, 1) \ @@ -301,15 +301,21 @@ namespace internal { F(InstallToContext, 1, 1) \ F(Interrupt, 0, 1) \ F(IS_VAR, 1, 1) \ - F(IsWasmInstance, 1, 1) \ F(NewReferenceError, 2, 1) \ F(NewSyntaxError, 2, 1) \ F(NewTypeError, 2, 1) \ F(OrdinaryHasInstance, 2, 1) \ - F(PromiseReject, 3, 1) \ - F(PromiseFulfill, 4, 1) \ + F(ReportPromiseReject, 2, 1) \ + F(PromiseHookInit, 2, 1) \ + F(PromiseHookResolve, 1, 1) \ + F(PromiseHookBefore, 1, 1) \ + F(PromiseHookAfter, 1, 1) \ + F(PromiseMarkAsHandled, 1, 1) \ + F(PromiseMarkHandledHint, 1, 1) \ F(PromiseRejectEventFromStack, 2, 1) \ F(PromiseRevokeReject, 1, 1) \ + F(PromiseResult, 1, 1) \ + F(PromiseStatus, 1, 1) \ F(PromoteScheduledException, 0, 1) \ F(ReThrow, 1, 1) \ F(RunMicrotasks, 0, 1) \ @@ -324,16 +330,18 @@ namespace internal { F(ThrowGeneratorRunning, 0, 1) \ F(ThrowIllegalInvocation, 0, 1) \ F(ThrowIncompatibleMethodReceiver, 2, 1) \ + F(ThrowInvalidHint, 1, 1) \ F(ThrowInvalidStringLength, 0, 1) \ F(ThrowIteratorResultNotAnObject, 1, 1) \ + F(ThrowSymbolIteratorInvalid, 0, 1) \ F(ThrowNotGeneric, 1, 1) \ F(ThrowReferenceError, 1, 1) \ F(ThrowStackOverflow, 0, 1) \ F(ThrowTypeError, -1 /* >= 1 */, 1) \ - F(ThrowWasmError, 2, 1) \ F(ThrowUndefinedOrNullToObject, 1, 1) \ F(Typeof, 1, 1) \ - F(UnwindAndFindExceptionHandler, 0, 1) + F(UnwindAndFindExceptionHandler, 0, 1) \ + F(AllowDynamicFunction, 1, 1) #define FOR_EACH_INTRINSIC_LITERALS(F) \ F(CreateRegExpLiteral, 4, 1) \ @@ -341,13 +349,13 @@ namespace internal { F(CreateArrayLiteral, 4, 1) \ F(CreateArrayLiteralStubBailout, 3, 1) - #define FOR_EACH_INTRINSIC_LIVEEDIT(F) \ F(LiveEditFindSharedFunctionInfosForScript, 1, 1) \ F(LiveEditGatherCompileInfo, 2, 1) \ F(LiveEditReplaceScript, 3, 1) \ - F(LiveEditFunctionSourceUpdated, 1, 1) \ + F(LiveEditFunctionSourceUpdated, 2, 1) \ F(LiveEditReplaceFunctionCode, 2, 1) \ + F(LiveEditFixupScript, 2, 1) \ F(LiveEditFunctionSetScript, 2, 1) \ F(LiveEditReplaceRefToNestedFunction, 3, 1) \ F(LiveEditPatchFunctionPositions, 2, 1) \ @@ -402,14 +410,14 @@ namespace internal { F(TryMigrateInstance, 1, 1) \ F(IsJSGlobalProxy, 1, 1) \ F(DefineAccessorPropertyUnchecked, 5, 1) \ - F(DefineDataPropertyInLiteral, 5, 1) \ - F(DefineDataProperty, 5, 1) \ + F(DefineDataPropertyInLiteral, 6, 1) \ F(GetDataProperty, 2, 1) \ F(GetConstructorName, 1, 1) \ F(HasFastPackedElements, 1, 1) \ F(ValueOf, 1, 1) \ F(IsJSReceiver, 1, 1) \ F(ClassOf, 1, 1) \ + F(CopyDataProperties, 2, 1) \ F(DefineGetterPropertyUnchecked, 4, 1) \ F(DefineSetterPropertyUnchecked, 4, 1) \ F(ToObject, 1, 1) \ @@ -465,8 +473,10 @@ namespace internal { F(RegExpExec, 4, 1) \ F(RegExpExecMultiple, 4, 1) \ F(RegExpExecReThrow, 4, 1) \ + F(RegExpInitializeAndCompile, 3, 1) \ F(RegExpInternalReplace, 3, 1) \ F(RegExpReplace, 3, 1) \ + F(RegExpSplit, 3, 1) \ F(StringReplaceGlobalRegExpWithString, 4, 1) \ F(StringReplaceNonGlobalRegExpWithFunction, 3, 1) \ F(StringSplit, 3, 1) @@ -482,10 +492,11 @@ namespace internal { F(NewStrictArguments, 1, 1) \ F(NewRestParameter, 1, 1) \ F(NewSloppyArguments, 3, 1) \ - F(NewClosure, 1, 1) \ - F(NewClosure_Tenured, 1, 1) \ + F(NewArgumentsElements, 2, 1) \ + F(NewClosure, 3, 1) \ + F(NewClosure_Tenured, 3, 1) \ F(NewScriptContext, 2, 1) \ - F(NewFunctionContext, 1, 1) \ + F(NewFunctionContext, 2, 1) \ F(PushModuleContext, 3, 1) \ F(PushWithContext, 3, 1) \ F(PushCatchContext, 4, 1) \ @@ -809,6 +820,7 @@ namespace internal { #define FOR_EACH_INTRINSIC_STRINGS(F) \ F(StringReplaceOneCharWithString, 3, 1) \ F(StringIndexOf, 3, 1) \ + F(StringIndexOfUnchecked, 3, 1) \ F(StringLastIndexOf, 2, 1) \ F(SubString, 3, 1) \ F(StringAdd, 2, 1) \ @@ -837,7 +849,6 @@ namespace internal { F(CreatePrivateSymbol, 1, 1) \ F(SymbolDescription, 1, 1) \ F(SymbolDescriptiveString, 1, 1) \ - F(SymbolRegistry, 0, 1) \ F(SymbolIsPrivate, 1, 1) #define FOR_EACH_INTRINSIC_TEST(F) \ @@ -898,10 +909,14 @@ namespace internal { F(SerializeWasmModule, 1, 1) \ F(DeserializeWasmModule, 2, 1) \ F(IsAsmWasmCode, 1, 1) \ - F(IsNotAsmWasmCode, 1, 1) \ + F(IsWasmCode, 1, 1) \ + F(DisallowCodegenFromStrings, 0, 1) \ F(ValidateWasmInstancesChain, 2, 1) \ F(ValidateWasmModuleState, 1, 1) \ - F(ValidateWasmOrphanedInstance, 1, 1) + F(ValidateWasmOrphanedInstance, 1, 1) \ + F(SetWasmCompileControls, 2, 1) \ + F(SetWasmInstantiateControls, 0, 1) \ + F(Verify, 1, 1) #define FOR_EACH_INTRINSIC_TYPEDARRAY(F) \ F(ArrayBufferGetByteLength, 1, 1) \ @@ -920,12 +935,22 @@ namespace internal { F(IsSharedIntegerTypedArray, 1, 1) \ F(IsSharedInteger32TypedArray, 1, 1) -#define FOR_EACH_INTRINSIC_WASM(F) \ - F(WasmGrowMemory, 1, 1) \ - F(WasmMemorySize, 0, 1) \ - F(WasmThrowTypeError, 0, 1) \ - F(WasmThrow, 2, 1) \ - F(WasmGetCaughtExceptionValue, 1, 1) +#define FOR_EACH_INTRINSIC_WASM(F) \ + F(WasmGrowMemory, 1, 1) \ + F(WasmMemorySize, 0, 1) \ + F(ThrowWasmError, 2, 1) \ + F(WasmThrowTypeError, 0, 1) \ + F(WasmThrow, 2, 1) \ + F(WasmGetCaughtExceptionValue, 1, 1) \ + F(ThrowWasmTrapUnreachable, 0, 1) \ + F(ThrowWasmTrapMemOutOfBounds, 0, 1) \ + F(ThrowWasmTrapDivByZero, 0, 1) \ + F(ThrowWasmTrapDivUnrepresentable, 0, 1) \ + F(ThrowWasmTrapRemByZero, 0, 1) \ + F(ThrowWasmTrapFloatUnrepresentable, 0, 1) \ + F(ThrowWasmTrapFuncInvalid, 0, 1) \ + F(ThrowWasmTrapFuncSigMismatch, 0, 1) \ + F(WasmRunInterpreter, 3, 1) #define FOR_EACH_INTRINSIC_RETURN_PAIR(F) \ F(LoadLookupSlotForCall, 1, 2) @@ -946,8 +971,8 @@ namespace internal { F(KeyedStoreIC_Miss, 5, 1) \ F(KeyedStoreIC_Slow, 5, 1) \ F(LoadElementWithInterceptor, 2, 1) \ - F(LoadGlobalIC_Miss, 2, 1) \ - F(LoadGlobalIC_Slow, 2, 1) \ + F(LoadGlobalIC_Miss, 3, 1) \ + F(LoadGlobalIC_Slow, 1, 1) \ F(LoadIC_Miss, 4, 1) \ F(LoadPropertyWithInterceptor, 3, 1) \ F(LoadPropertyWithInterceptorOnly, 3, 1) \ @@ -1009,14 +1034,13 @@ FOR_EACH_INTRINSIC_RETURN_OBJECT(F) class Runtime : public AllStatic { public: - enum FunctionId { + enum FunctionId : int32_t { #define F(name, nargs, ressize) k##name, #define I(name, nargs, ressize) kInline##name, - FOR_EACH_INTRINSIC(F) - FOR_EACH_INTRINSIC(I) + FOR_EACH_INTRINSIC(F) FOR_EACH_INTRINSIC(I) #undef I #undef F - kNumFunctions, + kNumFunctions, }; enum IntrinsicType { RUNTIME, INLINE }; |