diff options
author | Ali Ijaz Sheikh <ofrobots@google.com> | 2016-01-20 09:45:45 -0800 |
---|---|---|
committer | Ali Ijaz Sheikh <ofrobots@google.com> | 2016-01-21 16:53:58 -0800 |
commit | ef4170ea03a80b21b2d8a65ce432efaa370fe2fa (patch) | |
tree | e382b1b38b729cd8155b56b441c3a563914854a3 /deps/v8/src/runtime | |
parent | 5f6dfab832979999d2f806fc1a2f1c11a25b0f35 (diff) | |
download | node-new-ef4170ea03a80b21b2d8a65ce432efaa370fe2fa.tar.gz |
deps: upgrade to V8 4.8.271.17
Pick up V8 4.8 branch-head. This branch brings in @@isConcatSpreadable,
@@toPrimitive and ToLength ES6 changes. For full details see:
http://v8project.blogspot.de/2015/11/v8-release-48.html
https://github.com/v8/v8/commit/fa163e2
Ref: https://github.com/nodejs/node/pull/4399
PR-URL: https://github.com/nodejs/node/pull/4785
Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/v8/src/runtime')
-rw-r--r-- | deps/v8/src/runtime/runtime-array.cc | 17 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-atomics.cc | 4 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-classes.cc | 39 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-debug.cc | 107 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-function.cc | 137 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-futex.cc | 4 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-internal.cc | 16 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-interpreter.cc | 80 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-liveedit.cc | 9 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-maths.cc | 20 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-numbers.cc | 8 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-object.cc | 287 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-regexp.cc | 120 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-scopes.cc | 63 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-strings.cc | 24 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-symbol.cc | 4 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-typedarray.cc | 14 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-utils.h | 4 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime.cc | 26 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime.h | 85 |
20 files changed, 571 insertions, 497 deletions
diff --git a/deps/v8/src/runtime/runtime-array.cc b/deps/v8/src/runtime/runtime-array.cc index 6fc1ad4ea1..67eaa4b632 100644 --- a/deps/v8/src/runtime/runtime-array.cc +++ b/deps/v8/src/runtime/runtime-array.cc @@ -9,6 +9,7 @@ #include "src/elements.h" #include "src/factory.h" #include "src/isolate-inl.h" +#include "src/key-accumulator.h" #include "src/messages.h" #include "src/prototype.h" @@ -206,6 +207,7 @@ RUNTIME_FUNCTION(Runtime_GetArrayKeys) { } KeyAccumulator accumulator(isolate); + // No need to separate protoype levels since we only get numbers/element keys for (PrototypeIterator iter(isolate, array, PrototypeIterator::START_AT_RECEIVER); !iter.IsAtEnd(); iter.Advance()) { @@ -216,16 +218,14 @@ RUNTIME_FUNCTION(Runtime_GetArrayKeys) { // collecting keys in that case. return *isolate->factory()->NewNumberFromUint(length); } + accumulator.NextPrototype(); Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); - Handle<FixedArray> current_keys = - isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE)); - current->GetOwnElementKeys(*current_keys, NONE); - accumulator.AddKeys(current_keys, FixedArray::ALL_KEYS); + JSObject::CollectOwnElementKeys(current, &accumulator, NONE); } // Erase any keys >= length. // TODO(adamk): Remove this step when the contract of %GetArrayKeys // is changed to let this happen on the JS side. - Handle<FixedArray> keys = accumulator.GetKeys(); + Handle<FixedArray> keys = accumulator.GetKeys(KEEP_NUMBERS); for (int i = 0; i < keys->length(); i++) { if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i); } @@ -253,7 +253,7 @@ static Object* ArrayConstructorCommon(Isolate* isolate, can_use_type_feedback = false; } else if (value != 0) { holey = true; - if (value >= JSObject::kInitialMaxFastElementArray) { + if (value >= JSArray::kInitialMaxFastElementArray) { can_inline_array_constructor = false; } } @@ -321,8 +321,9 @@ static Object* ArrayConstructorCommon(Isolate* isolate, if (original_constructor->has_instance_prototype()) { Handle<Object> prototype = handle(original_constructor->instance_prototype(), isolate); - RETURN_FAILURE_ON_EXCEPTION( - isolate, JSObject::SetPrototype(array, prototype, false)); + MAYBE_RETURN(JSObject::SetPrototype(array, prototype, false, + Object::THROW_ON_ERROR), + isolate->heap()->exception()); } } diff --git a/deps/v8/src/runtime/runtime-atomics.cc b/deps/v8/src/runtime/runtime-atomics.cc index 84eab2ce11..636371c134 100644 --- a/deps/v8/src/runtime/runtime-atomics.cc +++ b/deps/v8/src/runtime/runtime-atomics.cc @@ -721,5 +721,5 @@ RUNTIME_FUNCTION(Runtime_AtomicsIsLockFree) { uint32_t usize = NumberToUint32(*size); return isolate->heap()->ToBoolean(AtomicIsLockFree(usize)); } -} -} // namespace v8::internal +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/runtime/runtime-classes.cc b/deps/v8/src/runtime/runtime-classes.cc index 51e682f325..ca5fecb0ab 100644 --- a/deps/v8/src/runtime/runtime-classes.cc +++ b/deps/v8/src/runtime/runtime-classes.cc @@ -123,6 +123,7 @@ static MaybeHandle<Object> DefineClass(Isolate* isolate, Handle<Object> name, Handle<Map> map = isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); + map->set_is_prototype_map(true); if (constructor->map()->is_strong()) { map->set_is_strong(); if (super_class->IsNull()) { @@ -162,9 +163,8 @@ static MaybeHandle<Object> DefineClass(Isolate* isolate, Handle<Object> name, Object); if (!constructor_parent.is_null()) { - RETURN_ON_EXCEPTION( - isolate, JSObject::SetPrototype(constructor, constructor_parent, false), - Object); + MAYBE_RETURN_NULL(JSObject::SetPrototype(constructor, constructor_parent, + false, Object::THROW_ON_ERROR)); } JSObject::AddProperty(prototype, isolate->factory()->constructor_string(), @@ -224,7 +224,6 @@ RUNTIME_FUNCTION(Runtime_FinalizeClassDefinition) { CONVERT_ARG_HANDLE_CHECKED(JSObject, constructor, 0); CONVERT_ARG_HANDLE_CHECKED(JSObject, prototype, 1); - JSObject::MigrateSlowToFast(prototype, 0, "RuntimeToFastProperties"); JSObject::MigrateSlowToFast(constructor, 0, "RuntimeToFastProperties"); if (constructor->map()->is_strong()) { @@ -269,7 +268,8 @@ static MaybeHandle<Object> LoadFromSuper(Isolate* isolate, Handle<JSObject> home_object, Handle<Name> name, LanguageMode language_mode) { - if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) { + if (home_object->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), home_object)) { isolate->ReportFailedAccessCheck(home_object); RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); } @@ -293,7 +293,8 @@ static MaybeHandle<Object> LoadElementFromSuper(Isolate* isolate, Handle<JSObject> home_object, uint32_t index, LanguageMode language_mode) { - if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) { + if (home_object->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), home_object)) { isolate->ReportFailedAccessCheck(home_object); RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); } @@ -369,7 +370,8 @@ RUNTIME_FUNCTION(Runtime_LoadKeyedFromSuper) { static Object* StoreToSuper(Isolate* isolate, Handle<JSObject> home_object, Handle<Object> receiver, Handle<Name> name, Handle<Object> value, LanguageMode language_mode) { - if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) { + if (home_object->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), home_object)) { isolate->ReportFailedAccessCheck(home_object); RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); } @@ -379,12 +381,10 @@ static Object* StoreToSuper(Isolate* isolate, Handle<JSObject> home_object, if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value(); LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto)); - Handle<Object> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, - Object::SetSuperProperty(&it, value, language_mode, - Object::CERTAINLY_NOT_STORE_FROM_KEYED)); - return *result; + MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode, + Object::CERTAINLY_NOT_STORE_FROM_KEYED), + isolate->heap()->exception()); + return *value; } @@ -393,7 +393,8 @@ static Object* StoreElementToSuper(Isolate* isolate, Handle<Object> receiver, uint32_t index, Handle<Object> value, LanguageMode language_mode) { - if (home_object->IsAccessCheckNeeded() && !isolate->MayAccess(home_object)) { + if (home_object->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), home_object)) { isolate->ReportFailedAccessCheck(home_object); RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); } @@ -403,12 +404,10 @@ static Object* StoreElementToSuper(Isolate* isolate, if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value(); LookupIterator it(isolate, receiver, index, Handle<JSReceiver>::cast(proto)); - Handle<Object> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, - Object::SetSuperProperty(&it, value, language_mode, - Object::MAY_BE_STORE_FROM_KEYED)); - return *result; + MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode, + Object::MAY_BE_STORE_FROM_KEYED), + isolate->heap()->exception()); + return *value; } diff --git a/deps/v8/src/runtime/runtime-debug.cc b/deps/v8/src/runtime/runtime-debug.cc index 9f49e4d5d2..27216fb323 100644 --- a/deps/v8/src/runtime/runtime-debug.cc +++ b/deps/v8/src/runtime/runtime-debug.cc @@ -156,29 +156,24 @@ MaybeHandle<JSArray> Runtime::GetInternalProperties(Isolate* isolate, RUNTIME_ASSERT_HANDLIFIED(function->function_bindings()->IsFixedArray(), JSArray); - Handle<FixedArray> bindings(function->function_bindings()); + Handle<BindingsArray> bindings(function->function_bindings()); Handle<FixedArray> result = factory->NewFixedArray(2 * 3); Handle<String> target = factory->NewStringFromAsciiChecked("[[TargetFunction]]"); result->set(0, *target); - result->set(1, bindings->get(JSFunction::kBoundFunctionIndex)); + result->set(1, bindings->bound_function()); Handle<String> bound_this = factory->NewStringFromAsciiChecked("[[BoundThis]]"); result->set(2, *bound_this); - result->set(3, bindings->get(JSFunction::kBoundThisIndex)); + result->set(3, bindings->bound_this()); - Handle<FixedArray> arguments = factory->NewFixedArray( - bindings->length() - JSFunction::kBoundArgumentsStartIndex); - bindings->CopyTo( - JSFunction::kBoundArgumentsStartIndex, *arguments, 0, - bindings->length() - JSFunction::kBoundArgumentsStartIndex); Handle<String> bound_args = factory->NewStringFromAsciiChecked("[[BoundArgs]]"); result->set(4, *bound_args); Handle<JSArray> arguments_array = - factory->NewJSArrayWithElements(arguments); + BindingsArray::CreateBoundArguments(bindings); result->set(5, *arguments_array); return factory->NewJSArrayWithElements(result); } @@ -456,7 +451,7 @@ RUNTIME_FUNCTION(Runtime_GetFrameCount) { it.frame()->Summarize(&frames); for (int i = frames.length() - 1; i >= 0; i--) { // Omit functions from native and extension scripts. - if (frames[i].function()->IsSubjectToDebugging()) n++; + if (frames[i].function()->shared()->IsSubjectToDebugging()) n++; } } return Smi::FromInt(n); @@ -534,7 +529,7 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { // Get scope info and read from it for local variable information. Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); - RUNTIME_ASSERT(function->IsSubjectToDebugging()); + RUNTIME_ASSERT(function->shared()->IsSubjectToDebugging()); Handle<SharedFunctionInfo> shared(function->shared()); Handle<ScopeInfo> scope_info(shared->scope_info()); DCHECK(*scope_info != ScopeInfo::Empty(isolate)); @@ -709,22 +704,19 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { } // Add the receiver (same as in function frame). - // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE - // THE FRAME ITERATOR TO WRAP THE RECEIVER. Handle<Object> receiver(it.frame()->receiver(), isolate); - DCHECK(!function->IsBuiltin()); + DCHECK(!function->shared()->IsBuiltin()); if (!receiver->IsJSObject() && is_sloppy(shared->language_mode())) { - // If the receiver is not a JSObject and the function is not a - // builtin or strict-mode we have hit an optimization where a - // value object is not converted into a wrapped JS objects. To - // hide this optimization from the debugger, we wrap the receiver - // by creating correct wrapper object based on the calling frame's - // native context. - it.Advance(); + // If the receiver is not a JSObject and the function is not a builtin or + // strict-mode we have hit an optimization where a value object is not + // converted into a wrapped JS objects. To hide this optimization from the + // debugger, we wrap the receiver by creating correct wrapper object based + // on the function's native context. + // See ECMA-262 6.0, 9.2.1.2, 6 b iii. if (receiver->IsUndefined()) { receiver = handle(function->global_proxy()); } else { - Context* context = Context::cast(it.frame()->context()); + Context* context = function->context(); Handle<Context> native_context(Context::cast(context->native_context())); if (!Object::ToObject(isolate, receiver, native_context) .ToHandle(&receiver)) { @@ -1070,11 +1062,11 @@ RUNTIME_FUNCTION(Runtime_GetThreadDetails) { // Sets the disable break state // args[0]: disable break state -RUNTIME_FUNCTION(Runtime_SetDisableBreak) { +RUNTIME_FUNCTION(Runtime_SetBreakPointsActive) { HandleScope scope(isolate); DCHECK(args.length() == 1); - CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0); - isolate->debug()->set_disable_break(disable_break); + CONVERT_BOOLEAN_ARG_CHECKED(active, 0); + isolate->debug()->set_break_points_active(active); return isolate->heap()->undefined_value(); } @@ -1457,7 +1449,7 @@ RUNTIME_FUNCTION(Runtime_DebugGetPrototype) { HandleScope shs(isolate); DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); - return *Object::GetPrototypeSkipHiddenPrototypes(isolate, obj); + return *Object::GetPrototype(isolate, obj); } @@ -1620,33 +1612,56 @@ RUNTIME_FUNCTION(Runtime_GetScript) { } +bool DebugStepInIsActive(Debug* debug) { + return debug->is_active() && debug->IsStepping() && + debug->last_step_action() == StepIn; +} + + // Check whether debugger is about to step into the callback that is passed -// to a built-in function such as Array.forEach. +// to a built-in function such as Array.forEach. This check is done before +// %DebugPrepareStepInIfStepping and is not strictly necessary. However, if it +// returns false, we can skip %DebugPrepareStepInIfStepping, useful in loops. RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) { + SealHandleScope shs(isolate); DCHECK(args.length() == 1); - Debug* debug = isolate->debug(); - if (!debug->is_active() || !debug->IsStepping() || - debug->last_step_action() != StepIn) { + if (!DebugStepInIsActive(isolate->debug())) { return isolate->heap()->false_value(); } - CONVERT_ARG_CHECKED(Object, callback, 0); + CONVERT_ARG_CHECKED(Object, object, 0); + RUNTIME_ASSERT(object->IsJSFunction() || object->IsJSGeneratorObject()); // We do not step into the callback if it's a builtin other than a bound, // or not even a function. - return isolate->heap()->ToBoolean( - callback->IsJSFunction() && - (JSFunction::cast(callback)->IsSubjectToDebugging() || - JSFunction::cast(callback)->shared()->bound())); + JSFunction* fun; + if (object->IsJSFunction()) { + fun = JSFunction::cast(object); + } else { + fun = JSGeneratorObject::cast(object)->function(); + } + return isolate->heap()->ToBoolean(fun->shared()->IsSubjectToDebugging() || + fun->shared()->bound()); +} + + +void FloodDebugSubjectWithOneShot(Debug* debug, Handle<JSFunction> function) { + if (function->shared()->IsSubjectToDebugging() || + function->shared()->bound()) { + // When leaving the function, step out has been activated, but not performed + // if we do not leave the builtin. To be able to step into the function + // again, we need to clear the step out at this point. + debug->ClearStepOut(); + debug->FloodWithOneShotGeneric(function); + } } // 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. +// 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) { DCHECK(args.length() == 1); - RUNTIME_ASSERT(isolate->debug()->is_active()); - Debug* debug = isolate->debug(); - if (!debug->IsStepping()) return isolate->heap()->undefined_value(); + if (!DebugStepInIsActive(debug)) return isolate->heap()->undefined_value(); HandleScope scope(isolate); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); @@ -1658,21 +1673,23 @@ RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) { fun = Handle<JSFunction>( Handle<JSGeneratorObject>::cast(object)->function(), isolate); } - // When leaving the function, step out has been activated, but not performed - // if we do not leave the builtin. To be able to step into the function - // again, we need to clear the step out at this point. - debug->ClearStepOut(); - debug->FloodWithOneShotGeneric(fun); + + FloodDebugSubjectWithOneShot(debug, fun); return isolate->heap()->undefined_value(); } RUNTIME_FUNCTION(Runtime_DebugPushPromise) { - DCHECK(args.length() == 2); + DCHECK(args.length() == 3); HandleScope scope(isolate); CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 1); + CONVERT_ARG_HANDLE_CHECKED(Object, handler, 2); isolate->PushPromise(promise, function); + Debug* debug = isolate->debug(); + if (handler->IsJSFunction() && DebugStepInIsActive(debug)) { + FloodDebugSubjectWithOneShot(debug, Handle<JSFunction>::cast(handler)); + } return isolate->heap()->undefined_value(); } diff --git a/deps/v8/src/runtime/runtime-function.cc b/deps/v8/src/runtime/runtime-function.cc index 18a0865f27..16e6149e7c 100644 --- a/deps/v8/src/runtime/runtime-function.cc +++ b/deps/v8/src/runtime/runtime-function.cc @@ -47,12 +47,40 @@ RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) { } -RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) { +RUNTIME_FUNCTION(Runtime_CompleteFunctionConstruction) { SealHandleScope shs(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_CHECKED(JSFunction, f, 0); - f->shared()->set_name_should_print_as_anonymous(true); - return isolate->heap()->undefined_value(); + DCHECK(args.length() == 3); + CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0); + CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 1); + CONVERT_ARG_HANDLE_CHECKED(Object, new_target, 2); + func->shared()->set_name_should_print_as_anonymous(true); + + // If new.target is equal to |constructor| then the function |func| created + // is already correctly setup and nothing else should be done here. + // But if new.target is not equal to |constructor| then we are have a + // Function builtin subclassing case and therefore the function |func| + // has wrong initial map. To fix that we create a new function object with + // correct initial map. + if (new_target->IsUndefined() || *constructor == *new_target) { + return *func; + } + + // Create a new JSFunction object with correct initial map. + HandleScope handle_scope(isolate); + Handle<JSFunction> original_constructor = + Handle<JSFunction>::cast(new_target); + + DCHECK(constructor->has_initial_map()); + Handle<Map> initial_map = + JSFunction::EnsureDerivedHasInitialMap(original_constructor, constructor); + + Handle<SharedFunctionInfo> shared_info(func->shared(), isolate); + Handle<Context> context(func->context(), isolate); + Handle<JSFunction> result = + isolate->factory()->NewFunctionFromSharedFunctionInfo( + initial_map, shared_info, context, NOT_TENURED); + DCHECK_EQ(func->IsConstructor(), result->IsConstructor()); + return *result; } @@ -135,7 +163,7 @@ RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) { CONVERT_ARG_CHECKED(JSFunction, fun, 0); CONVERT_ARG_CHECKED(String, name, 1); - fun->SetInstanceClassName(name); + fun->shared()->set_instance_class_name(name); return isolate->heap()->undefined_value(); } @@ -357,7 +385,7 @@ RUNTIME_FUNCTION(Runtime_FunctionBindArguments) { HandleScope scope(isolate); DCHECK(args.length() == 4); CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1); + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, bindee, 1); CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2); CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3); @@ -378,30 +406,28 @@ RUNTIME_FUNCTION(Runtime_FunctionBindArguments) { } // Initialize array of bindings (function, this, and any existing arguments // if the function was already bound). - Handle<FixedArray> new_bindings; - int i; + Handle<BindingsArray> new_bindings; + int out_index = 0; + Handle<TypeFeedbackVector> vector( + bound_function->shared()->feedback_vector()); if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) { - Handle<FixedArray> old_bindings( + Handle<BindingsArray> old_bindings( JSFunction::cast(*bindee)->function_bindings()); - RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex); - new_bindings = - isolate->factory()->NewFixedArray(old_bindings->length() + argc); - bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex), - isolate); - i = 0; - for (int n = old_bindings->length(); i < n; i++) { - new_bindings->set(i, old_bindings->get(i)); + RUNTIME_ASSERT(old_bindings->bindings_count() >= 0); + bindee = handle(old_bindings->bound_function(), isolate); + Handle<Object> old_bound_this(old_bindings->bound_this(), isolate); + new_bindings = BindingsArray::New(isolate, vector, bindee, old_bound_this, + old_bindings->bindings_count() + argc); + for (int n = old_bindings->bindings_count(); out_index < n; out_index++) { + new_bindings->set_binding(out_index, old_bindings->binding(out_index)); } } else { - int array_size = JSFunction::kBoundArgumentsStartIndex + argc; - new_bindings = isolate->factory()->NewFixedArray(array_size); - new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee); - new_bindings->set(JSFunction::kBoundThisIndex, *this_object); - i = 2; + new_bindings = + BindingsArray::New(isolate, vector, bindee, this_object, argc); } // Copy arguments, skipping the first which is "this_arg". - for (int j = 0; j < argc; j++, i++) { - new_bindings->set(i, *arguments[j + 1]); + for (int j = 0; j < argc; j++, out_index++) { + new_bindings->set_binding(out_index, *arguments[j + 1]); } new_bindings->set_map_no_write_barrier(isolate->heap()->fixed_array_map()); bound_function->set_function_bindings(*new_bindings); @@ -444,9 +470,9 @@ RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) { if (callable->IsJSFunction()) { Handle<JSFunction> function = Handle<JSFunction>::cast(callable); if (function->shared()->bound()) { - RUNTIME_ASSERT(function->function_bindings()->IsFixedArray()); - Handle<FixedArray> bindings(function->function_bindings()); - return *isolate->factory()->NewJSArrayWithElements(bindings); + RUNTIME_ASSERT(function->function_bindings()->IsBindingsArray()); + Handle<BindingsArray> bindings(function->function_bindings()); + return *BindingsArray::CreateRuntimeBindings(bindings); } } return isolate->heap()->undefined_value(); @@ -462,12 +488,10 @@ RUNTIME_FUNCTION(Runtime_NewObjectFromBound) { // The argument is a bound function. Extract its bound arguments // and callable. - Handle<FixedArray> bound_args = - Handle<FixedArray>(FixedArray::cast(function->function_bindings())); - int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex; - Handle<Object> bound_function( - JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)), - isolate); + Handle<BindingsArray> bound_args = + handle(BindingsArray::cast(function->function_bindings())); + int bound_argc = bound_args->bindings_count(); + Handle<Object> bound_function(bound_args->bound_function(), isolate); DCHECK(!bound_function->IsJSFunction() || !Handle<JSFunction>::cast(bound_function)->shared()->bound()); @@ -475,8 +499,7 @@ RUNTIME_FUNCTION(Runtime_NewObjectFromBound) { base::SmartArrayPointer<Handle<Object>> param_data = Runtime::GetCallerArguments(isolate, bound_argc, &total_argc); for (int i = 0; i < bound_argc; i++) { - param_data[i] = Handle<Object>( - bound_args->get(JSFunction::kBoundArgumentsStartIndex + i), isolate); + param_data[i] = handle(bound_args->binding(i), isolate); } Handle<Object> result; @@ -547,41 +570,22 @@ RUNTIME_FUNCTION(Runtime_GetOriginalConstructor) { DCHECK(args.length() == 0); JavaScriptFrameIterator it(isolate); JavaScriptFrame* frame = it.frame(); - return frame->IsConstructor() ? frame->GetOriginalConstructor() - : isolate->heap()->undefined_value(); + // Currently we don't inline [[Construct]] calls. + return frame->IsConstructor() && !frame->HasInlinedFrames() + ? frame->GetOriginalConstructor() + : isolate->heap()->undefined_value(); } -// TODO(bmeurer): Kill %_CallFunction ASAP as it is almost never used -// correctly because of the weird semantics underneath. -RUNTIME_FUNCTION(Runtime_CallFunction) { +// ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee. +RUNTIME_FUNCTION(Runtime_ConvertReceiver) { HandleScope scope(isolate); - DCHECK(args.length() >= 2); - int argc = args.length() - 2; - CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1); - Object* receiver = args[0]; - - // If there are too many arguments, allocate argv via malloc. - const int argv_small_size = 10; - Handle<Object> argv_small_buffer[argv_small_size]; - base::SmartArrayPointer<Handle<Object>> argv_large_buffer; - Handle<Object>* argv = argv_small_buffer; - if (argc > argv_small_size) { - argv = new Handle<Object>[argc]; - if (argv == NULL) return isolate->StackOverflow(); - argv_large_buffer = base::SmartArrayPointer<Handle<Object>>(argv); - } - - for (int i = 0; i < argc; ++i) { - argv[i] = Handle<Object>(args[1 + i], isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); + if (receiver->IsNull() || receiver->IsUndefined()) { + return isolate->global_proxy(); } - - Handle<JSReceiver> hfun(fun); - Handle<Object> hreceiver(receiver, isolate); - Handle<Object> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, Execution::Call(isolate, hfun, hreceiver, argc, argv)); - return *result; + return *Object::ToObject(isolate, receiver).ToHandleChecked(); } @@ -608,5 +612,6 @@ RUNTIME_FUNCTION(Runtime_ThrowStrongModeTooFewArguments) { THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(MessageTemplate::kStrongArity)); } + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-futex.cc b/deps/v8/src/runtime/runtime-futex.cc index a96758d9f3..b2bad77c98 100644 --- a/deps/v8/src/runtime/runtime-futex.cc +++ b/deps/v8/src/runtime/runtime-futex.cc @@ -89,5 +89,5 @@ RUNTIME_FUNCTION(Runtime_AtomicsFutexNumWaitersForTesting) { return FutexEmulation::NumWaitersForTesting(isolate, array_buffer, addr); } -} -} // namespace v8::internal +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/runtime/runtime-internal.cc b/deps/v8/src/runtime/runtime-internal.cc index 90d5532af3..478a954b3e 100644 --- a/deps/v8/src/runtime/runtime-internal.cc +++ b/deps/v8/src/runtime/runtime-internal.cc @@ -307,6 +307,7 @@ RUNTIME_FUNCTION(Runtime_FormatMessageString) { ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, result, MessageTemplate::FormatMessage(template_index, arg0, arg1, arg2)); + isolate->native_context()->IncrementErrorsThrown(); return *result; } @@ -318,6 +319,7 @@ RUNTIME_FUNCTION(Runtime_FormatMessageString) { CONVERT_ARG_HANDLE_CHECKED(JSObject, call_site_obj, 0); \ Handle<String> result; \ CallSite call_site(isolate, call_site_obj); \ + RUNTIME_ASSERT(call_site.IsValid()) \ return RETURN(call_site.NAME(), isolate); \ } @@ -370,18 +372,6 @@ RUNTIME_FUNCTION(Runtime_IncrementStatsCounter) { } -RUNTIME_FUNCTION(Runtime_Likely) { - DCHECK(args.length() == 1); - return args[0]; -} - - -RUNTIME_FUNCTION(Runtime_Unlikely) { - DCHECK(args.length() == 1); - return args[0]; -} - - RUNTIME_FUNCTION(Runtime_HarmonyToString) { // TODO(caitp): Delete this runtime method when removing --harmony-tostring return isolate->heap()->ToBoolean(FLAG_harmony_tostring); @@ -423,7 +413,7 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object) { ? new ParseInfo(&zone, location.function()) : new ParseInfo(&zone, location.script())); if (Parser::ParseStatic(info.get())) { - CallPrinter printer(isolate, &zone); + CallPrinter printer(isolate); const char* string = printer.Print(info->literal(), location.start_pos()); return isolate->factory()->NewStringFromAsciiChecked(string); } else { diff --git a/deps/v8/src/runtime/runtime-interpreter.cc b/deps/v8/src/runtime/runtime-interpreter.cc index e0a171267f..ef86869ccc 100644 --- a/deps/v8/src/runtime/runtime-interpreter.cc +++ b/deps/v8/src/runtime/runtime-interpreter.cc @@ -96,7 +96,7 @@ RUNTIME_FUNCTION(Runtime_InterpreterGreaterThanOrEqual) { RUNTIME_FUNCTION(Runtime_InterpreterStrictEquals) { - SealHandleScope scope(isolate); + SealHandleScope shs(isolate); DCHECK_EQ(2, args.length()); CONVERT_ARG_CHECKED(Object, x, 0); CONVERT_ARG_CHECKED(Object, y, 1); @@ -105,7 +105,7 @@ RUNTIME_FUNCTION(Runtime_InterpreterStrictEquals) { RUNTIME_FUNCTION(Runtime_InterpreterStrictNotEquals) { - SealHandleScope scope(isolate); + SealHandleScope shs(isolate); DCHECK_EQ(2, args.length()); CONVERT_ARG_CHECKED(Object, x, 0); CONVERT_ARG_CHECKED(Object, y, 1); @@ -114,12 +114,86 @@ RUNTIME_FUNCTION(Runtime_InterpreterStrictNotEquals) { RUNTIME_FUNCTION(Runtime_InterpreterToBoolean) { - SealHandleScope scope(isolate); + SealHandleScope shs(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_CHECKED(Object, x, 0); return isolate->heap()->ToBoolean(x->BooleanValue()); } +RUNTIME_FUNCTION(Runtime_InterpreterLogicalNot) { + SealHandleScope shs(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_CHECKED(Object, x, 0); + return isolate->heap()->ToBoolean(!x->BooleanValue()); +} + + +RUNTIME_FUNCTION(Runtime_InterpreterTypeOf) { + SealHandleScope shs(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, x, 0); + return Object::cast(*Object::TypeOf(isolate, x)); +} + + +RUNTIME_FUNCTION(Runtime_InterpreterNewClosure) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); + CONVERT_SMI_ARG_CHECKED(pretenured_flag, 1); + Handle<Context> context(isolate->context(), isolate); + return *isolate->factory()->NewFunctionFromSharedFunctionInfo( + shared, context, static_cast<PretenureFlag>(pretenured_flag)); +} + + +RUNTIME_FUNCTION(Runtime_InterpreterForInPrepare) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); + CONVERT_ARG_HANDLE_CHECKED(HeapObject, property_names, 1); + + Handle<Object> cache_type = property_names; + Handle<Map> cache_type_map = handle(property_names->map(), isolate); + Handle<Map> receiver_map = handle(receiver->map(), isolate); + + Handle<FixedArray> cache_array; + int cache_length; + + if (cache_type_map.is_identical_to(isolate->factory()->meta_map())) { + int enum_length = cache_type_map->EnumLength(); + DescriptorArray* descriptors = receiver_map->instance_descriptors(); + if (enum_length > 0 && descriptors->HasEnumCache()) { + cache_array = handle(descriptors->GetEnumCache(), isolate); + cache_length = cache_array->length(); + } else { + cache_array = isolate->factory()->empty_fixed_array(); + cache_length = 0; + } + } else { + cache_array = Handle<FixedArray>::cast(cache_type); + cache_length = cache_array->length(); + + STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); + if (receiver_map->instance_type() <= LAST_JS_PROXY_TYPE) { + DCHECK_GE(receiver_map->instance_type(), LAST_JS_PROXY_TYPE); + // Zero indicates proxy + cache_type = Handle<Object>(Smi::FromInt(0), isolate); + } else { + // One entails slow check + cache_type = Handle<Object>(Smi::FromInt(1), isolate); + } + } + + Handle<FixedArray> result = isolate->factory()->NewFixedArray(4); + result->set(0, *receiver); + result->set(1, *cache_array); + result->set(2, *cache_type); + result->set(3, Smi::FromInt(cache_length)); + return *result; +} + + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-liveedit.cc b/deps/v8/src/runtime/runtime-liveedit.cc index 947ef2c29b..dd3405a44c 100644 --- a/deps/v8/src/runtime/runtime-liveedit.cc +++ b/deps/v8/src/runtime/runtime-liveedit.cc @@ -229,7 +229,14 @@ RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) { CONVERT_ARG_HANDLE_CHECKED(String, s1, 0); CONVERT_ARG_HANDLE_CHECKED(String, s2, 1); - return *LiveEdit::CompareStrings(s1, s2); + Handle<JSArray> result = LiveEdit::CompareStrings(s1, s2); + uint32_t array_length; + CHECK(result->length()->ToArrayLength(&array_length)); + if (array_length > 0) { + isolate->debug()->feature_tracker()->Track(DebugFeatureTracker::kLiveEdit); + } + + return *result; } diff --git a/deps/v8/src/runtime/runtime-maths.cc b/deps/v8/src/runtime/runtime-maths.cc index 504261679e..70c587d745 100644 --- a/deps/v8/src/runtime/runtime-maths.cc +++ b/deps/v8/src/runtime/runtime-maths.cc @@ -6,6 +6,7 @@ #include "src/arguments.h" #include "src/assembler.h" +#include "src/base/utils/random-number-generator.h" #include "src/codegen.h" #include "src/third_party/fdlibm/fdlibm.h" @@ -67,8 +68,8 @@ RUNTIME_FUNCTION(Runtime_RemPiO2) { CONVERT_DOUBLE_ARG_CHECKED(x, 0); CONVERT_ARG_CHECKED(JSTypedArray, result, 1); RUNTIME_ASSERT(result->byte_length() == Smi::FromInt(2 * sizeof(double))); - void* backing_store = JSArrayBuffer::cast(result->buffer())->backing_store(); - double* y = static_cast<double*>(backing_store); + FixedFloat64Array* array = FixedFloat64Array::cast(result->elements()); + double* y = static_cast<double*>(array->DataPtr()); return Smi::FromInt(fdlibm::rempio2(x, y)); } @@ -244,5 +245,20 @@ RUNTIME_FUNCTION(Runtime_IsMinusZero) { HeapNumber* number = HeapNumber::cast(obj); return isolate->heap()->ToBoolean(IsMinusZero(number->value())); } + + +RUNTIME_FUNCTION(Runtime_InitializeRNG) { + HandleScope scope(isolate); + DCHECK(args.length() == 0); + static const int kSize = 4; + Handle<FixedArray> array = isolate->factory()->NewFixedArray(kSize); + uint16_t seeds[kSize]; + do { + isolate->random_number_generator()->NextBytes(seeds, + kSize * sizeof(*seeds)); + } while (!(seeds[0] && seeds[1] && seeds[2] && seeds[3])); + for (int i = 0; i < kSize; i++) array->set(i, Smi::FromInt(seeds[i])); + return *isolate->factory()->NewJSArrayWithElements(array); +} } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-numbers.cc b/deps/v8/src/runtime/runtime-numbers.cc index 177b3ff584..f976df951c 100644 --- a/deps/v8/src/runtime/runtime-numbers.cc +++ b/deps/v8/src/runtime/runtime-numbers.cc @@ -8,6 +8,7 @@ #include "src/base/bits.h" #include "src/bootstrapper.h" #include "src/codegen.h" +#include "src/isolate-inl.h" namespace v8 { namespace internal { @@ -171,12 +172,13 @@ RUNTIME_FUNCTION(Runtime_NumberToStringSkipCache) { } +// TODO(bmeurer): Kill this runtime entry. Uses in date.js are wrong anyway. RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) { HandleScope scope(isolate); DCHECK(args.length() == 1); - - CONVERT_DOUBLE_ARG_CHECKED(number, 0); - double double_value = DoubleToInteger(number); + CONVERT_ARG_HANDLE_CHECKED(Object, input, 0); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, input, Object::ToNumber(input)); + double double_value = DoubleToInteger(input->Number()); // Map both -0 and +0 to +0. if (double_value == 0) double_value = 0; diff --git a/deps/v8/src/runtime/runtime-object.cc b/deps/v8/src/runtime/runtime-object.cc index 4782a31430..a16e1295b9 100644 --- a/deps/v8/src/runtime/runtime-object.cc +++ b/deps/v8/src/runtime/runtime-object.cc @@ -26,26 +26,12 @@ MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate, Object); } - // Check if the given key is an array index. - uint32_t index = 0; - if (key->ToArrayIndex(&index)) { - return Object::GetElement(isolate, object, index, language_mode); - } + bool success = false; + LookupIterator it = + LookupIterator::PropertyOrElement(isolate, object, key, &success); + if (!success) return MaybeHandle<Object>(); - // Convert the key to a name - possibly by calling back into JavaScript. - Handle<Name> name; - ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key), - Object); - - // Check if the name is trivially convertible to an index and get - // the element if so. - // TODO(verwaest): Make sure GetProperty(LookupIterator*) can handle this, and - // remove the special casing here. - if (name->AsArrayIndex(&index)) { - return Object::GetElement(isolate, object, index); - } else { - return Object::GetProperty(object, name, language_mode); - } + return Object::GetProperty(&it, language_mode); } @@ -70,7 +56,7 @@ static MaybeHandle<Object> KeyedGetObjectProperty(Isolate* isolate, DisallowHeapAllocation no_allocation; Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj); Handle<Name> key = Handle<Name>::cast(key_obj); - if (receiver->IsGlobalObject()) { + if (receiver->IsJSGlobalObject()) { // Attempt dictionary lookup. GlobalDictionary* dictionary = receiver->global_dictionary(); int entry = dictionary->FindEntry(key); @@ -135,17 +121,12 @@ MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate, Handle<JSReceiver> receiver, Handle<Object> key, LanguageMode language_mode) { - // Check if the given key is an array index. - uint32_t index = 0; - if (key->ToArrayIndex(&index)) { - return JSReceiver::DeleteElement(receiver, index, language_mode); - } + bool success = false; + LookupIterator it = LookupIterator::PropertyOrElement( + isolate, receiver, key, &success, LookupIterator::HIDDEN); + if (!success) return MaybeHandle<Object>(); - Handle<Name> name; - ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key), - Object); - - return JSReceiver::DeletePropertyOrElement(receiver, name, language_mode); + return JSReceiver::DeleteProperty(&it, language_mode); } @@ -162,18 +143,14 @@ MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate, } // Check if the given key is an array index. - uint32_t index = 0; - if (key->ToArrayIndex(&index)) { - return Object::SetElement(isolate, object, index, value, language_mode); - } + bool success = false; + LookupIterator it = + LookupIterator::PropertyOrElement(isolate, object, key, &success); + if (!success) return MaybeHandle<Object>(); - Handle<Name> name; - ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key), - Object); - - LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name); - return Object::SetProperty(&it, value, language_mode, - Object::MAY_BE_STORE_FROM_KEYED); + MAYBE_RETURN_NULL(Object::SetProperty(&it, value, language_mode, + Object::MAY_BE_STORE_FROM_KEYED)); + return value; } @@ -181,68 +158,31 @@ RUNTIME_FUNCTION(Runtime_GetPrototype) { HandleScope scope(isolate); DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); - // We don't expect access checks to be needed on JSProxy objects. - DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject()); - PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER); - do { - if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() && - !isolate->MayAccess(PrototypeIterator::GetCurrent<JSObject>(iter))) { - return isolate->heap()->null_value(); - } - iter.AdvanceIgnoringProxies(); - if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { - return *PrototypeIterator::GetCurrent(iter); - } - } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)); - return *PrototypeIterator::GetCurrent(iter); + return *Object::GetPrototype(isolate, obj); } RUNTIME_FUNCTION(Runtime_InternalSetPrototype) { HandleScope scope(isolate); DCHECK(args.length() == 2); - CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0); CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); - DCHECK(!obj->IsAccessCheckNeeded()); - DCHECK(!obj->map()->is_observed()); - Handle<Object> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, JSObject::SetPrototype(obj, prototype, false)); - return *result; + MAYBE_RETURN( + JSReceiver::SetPrototype(obj, prototype, false, Object::THROW_ON_ERROR), + isolate->heap()->exception()); + return *obj; } RUNTIME_FUNCTION(Runtime_SetPrototype) { HandleScope scope(isolate); DCHECK(args.length() == 2); - CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0); CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); - if (obj->IsAccessCheckNeeded() && !isolate->MayAccess(obj)) { - isolate->ReportFailedAccessCheck(obj); - RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); - return isolate->heap()->undefined_value(); - } - if (obj->map()->is_observed()) { - Handle<Object> old_value = - Object::GetPrototypeSkipHiddenPrototypes(isolate, obj); - Handle<Object> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, JSObject::SetPrototype(obj, prototype, true)); - - Handle<Object> new_value = - Object::GetPrototypeSkipHiddenPrototypes(isolate, obj); - if (!new_value->SameValue(*old_value)) { - RETURN_FAILURE_ON_EXCEPTION( - isolate, JSObject::EnqueueChangeRecord( - obj, "setPrototype", isolate->factory()->proto_string(), - old_value)); - } - return *result; - } - Handle<Object> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, JSObject::SetPrototype(obj, prototype, true)); - return *result; + MAYBE_RETURN( + JSReceiver::SetPrototype(obj, prototype, true, Object::THROW_ON_ERROR), + isolate->heap()->exception()); + return *obj; } @@ -325,19 +265,18 @@ RUNTIME_FUNCTION(Runtime_GetOwnProperty) { RUNTIME_FUNCTION(Runtime_PreventExtensions) { HandleScope scope(isolate); DCHECK(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); - Handle<Object> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, - JSObject::PreventExtensions(obj)); - return *result; + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0); + if (JSReceiver::PreventExtensions(obj, Object::THROW_ON_ERROR).IsNothing()) + return isolate->heap()->exception(); + return *obj; } RUNTIME_FUNCTION(Runtime_IsExtensible) { - SealHandleScope shs(isolate); + HandleScope scope(isolate); DCHECK(args.length() == 1); - CONVERT_ARG_CHECKED(JSObject, obj, 0); - return isolate->heap()->ToBoolean(obj->IsExtensible()); + CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); + return isolate->heap()->ToBoolean(JSObject::IsExtensible(obj)); } @@ -399,7 +338,8 @@ RUNTIME_FUNCTION(Runtime_LoadGlobalViaContext) { // Lookup the named property on the global object. Handle<ScopeInfo> scope_info(script_context->scope_info(), isolate); Handle<Name> name(scope_info->ContextSlotName(slot), isolate); - Handle<GlobalObject> global_object(script_context->global_object(), isolate); + Handle<JSGlobalObject> global_object(script_context->global_object(), + isolate); LookupIterator it(global_object, name, LookupIterator::HIDDEN); // Switch to fast mode only if there is a data property and it's not on @@ -433,7 +373,8 @@ Object* StoreGlobalViaContext(Isolate* isolate, int slot, Handle<Object> value, // Lookup the named property on the global object. Handle<ScopeInfo> scope_info(script_context->scope_info(), isolate); Handle<Name> name(scope_info->ContextSlotName(slot), isolate); - Handle<GlobalObject> global_object(script_context->global_object(), isolate); + Handle<JSGlobalObject> global_object(script_context->global_object(), + isolate); LookupIterator it(global_object, name, LookupIterator::HIDDEN); // Switch to fast mode only if there is a data property and it's not on @@ -449,12 +390,10 @@ Object* StoreGlobalViaContext(Isolate* isolate, int slot, Handle<Object> value, script_context->set(slot, isolate->heap()->empty_property_cell()); } - Handle<Object> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, - Object::SetProperty(&it, value, language_mode, - Object::CERTAINLY_NOT_STORE_FROM_KEYED)); - return *result; + MAYBE_RETURN(Object::SetProperty(&it, value, language_mode, + Object::CERTAINLY_NOT_STORE_FROM_KEYED), + isolate->heap()->exception()); + return *value; } } // namespace @@ -691,6 +630,8 @@ static Object* HasOwnPropertyImplementation(Isolate* isolate, ->is_hidden_prototype()) { // TODO(verwaest): The recursion is not necessary for keys that are array // indices. Removing this. + // Casting to JSObject is fine because JSProxies are never used as + // hidden prototypes. return HasOwnPropertyImplementation( isolate, Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key); @@ -831,8 +772,9 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { for (PrototypeIterator iter(isolate, object, PrototypeIterator::START_AT_RECEIVER); !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) { - Handle<JSObject> jsproto = - Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); + // Casting to JSObject is fine because |object| is guaranteed to be one, + // and we'll only look at hidden prototypes which are never JSProxies. + Handle<JSObject> jsproto = PrototypeIterator::GetCurrent<JSObject>(iter); total_property_count += jsproto->NumberOfOwnProperties(filter); } @@ -847,8 +789,9 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { for (PrototypeIterator iter(isolate, object, PrototypeIterator::START_AT_RECEIVER); !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) { - Handle<JSObject> jsproto = - Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); + // Casting to JSObject is fine because |object| is guaranteed to be one, + // and we'll only look at hidden prototypes which are never JSProxies. + Handle<JSObject> jsproto = PrototypeIterator::GetCurrent<JSObject>(iter); int own = jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); // Names from hidden prototypes may already have been added // for inherited function template instances. Count the duplicates @@ -873,7 +816,8 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { CHECK_EQ(total_property_count, next_copy_index); - if (object->IsAccessCheckNeeded() && !isolate->MayAccess(object)) { + if (object->IsAccessCheckNeeded() && + !isolate->MayAccess(handle(isolate->context()), object)) { for (int i = 0; i < total_property_count; i++) { Handle<Name> name(Name::cast(names->get(i))); if (name.is_identical_to(hidden_string)) continue; @@ -920,11 +864,25 @@ RUNTIME_FUNCTION(Runtime_GetOwnElementNames) { if (!args[0]->IsJSObject()) { return isolate->heap()->undefined_value(); } - CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); + CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); + + // TODO(cbruni): implement proper prototype lookup like in GetOwnPropertyNames + if (object->IsJSGlobalProxy()) { + // All the elements are stored on the globa_object and not directly on the + // global object proxy. + PrototypeIterator iter(isolate, object, + PrototypeIterator::START_AT_PROTOTYPE); + if (iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { + return *isolate->factory()->NewJSArray(0); + } + // Casting to JSObject is fine because |object| is guaranteed to be one, + // and we'll only look at hidden prototypes which are never JSProxies. + object = PrototypeIterator::GetCurrent<JSObject>(iter); + } - int n = obj->NumberOfOwnElements(NONE); + int n = object->NumberOfOwnElements(NONE); Handle<FixedArray> names = isolate->factory()->NewFixedArray(n); - obj->GetOwnElementKeys(*names, NONE); + object->GetOwnElementKeys(*names, NONE); return *isolate->factory()->NewJSArrayWithElements(names); } @@ -989,34 +947,9 @@ RUNTIME_FUNCTION(Runtime_OwnKeys) { Handle<FixedArray> contents; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, contents, JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY)); - - // Some fast paths through GetKeysInFixedArrayFor reuse a cached - // property array and since the result is mutable we have to create - // a fresh clone on each invocation. - int length = contents->length(); - Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); - int offset = 0; - // Use an outer loop to avoid creating too many handles in the current - // handle scope. - while (offset < length) { - HandleScope scope(isolate); - offset += 100; - int end = Min(offset, length); - for (int i = offset - 100; i < end; i++) { - Object* entry = contents->get(i); - if (entry->IsString()) { - copy->set(i, entry); - } else { - DCHECK(entry->IsNumber()); - Handle<Object> entry_handle(entry, isolate); - Handle<Object> entry_str = - isolate->factory()->NumberToString(entry_handle); - copy->set(i, *entry_str); - } - } - } - return *isolate->factory()->NewJSArrayWithElements(copy); + isolate, contents, JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY, + SKIP_SYMBOLS, CONVERT_TO_STRING)); + return *isolate->factory()->NewJSArrayWithElements(contents); } @@ -1024,7 +957,7 @@ RUNTIME_FUNCTION(Runtime_ToFastProperties) { HandleScope scope(isolate); DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); - if (object->IsJSObject() && !object->IsGlobalObject()) { + if (object->IsJSObject() && !object->IsJSGlobalObject()) { JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0, "RuntimeToFastProperties"); } @@ -1066,45 +999,23 @@ static Object* Runtime_NewObjectHelper(Isolate* isolate, // Handle stepping into constructors if step into is active. if (debug->StepInActive()) debug->HandleStepIn(function, true); - if (function->has_initial_map()) { - if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) { - // The 'Function' function ignores the receiver object when - // called using 'new' and creates a new JSFunction object that - // is returned. The receiver object is only used for error - // reporting if an error occurs when constructing the new - // JSFunction. Factory::NewJSObject() should not be used to - // allocate JSFunctions since it does not properly initialize - // the shared part of the function. Since the receiver is - // ignored anyway, we use the global object as the receiver - // instead of a new JSFunction object. This way, errors are - // reported the same way whether or not 'Function' is called - // using 'new'. - return isolate->global_proxy(); - } - } - // The function should be compiled for the optimization hints to be // available. Compiler::Compile(function, CLEAR_EXCEPTION); - Handle<JSObject> result; - if (site.is_null()) { - result = isolate->factory()->NewJSObject(function); - } else { - result = isolate->factory()->NewJSObjectWithMemento(function, site); + JSFunction::EnsureHasInitialMap(function); + if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) { + // The 'Function' function ignores the receiver object when + // called using 'new' and creates a new JSFunction object that + // is returned. + return isolate->heap()->undefined_value(); } - // Set up the prototoype using original function. - // TODO(dslomov): instead of setting the __proto__, - // use and cache the correct map. - if (*original_function != *function) { - if (original_function->has_instance_prototype()) { - Handle<Object> prototype = - handle(original_function->instance_prototype(), isolate); - RETURN_FAILURE_ON_EXCEPTION( - isolate, JSObject::SetPrototype(result, prototype, false)); - } - } + Handle<Map> initial_map = + JSFunction::EnsureDerivedHasInitialMap(original_function, function); + + Handle<JSObject> result = + isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site); isolate->counters()->constructed_objects()->Increment(); isolate->counters()->constructed_objects_runtime()->Increment(); @@ -1127,8 +1038,8 @@ RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) { HandleScope scope(isolate); DCHECK(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); - function->CompleteInobjectSlackTracking(); + CONVERT_ARG_HANDLE_CHECKED(Map, initial_map, 0); + initial_map->CompleteInobjectSlackTracking(); return isolate->heap()->undefined_value(); } @@ -1586,9 +1497,8 @@ RUNTIME_FUNCTION(Runtime_InstanceOf) { if (callable->IsJSFunction()) { Handle<JSFunction> function = Handle<JSFunction>::cast(callable); if (function->shared()->bound()) { - Handle<FixedArray> bindings(function->function_bindings(), isolate); - callable = - handle(bindings->get(JSFunction::kBoundFunctionIndex), isolate); + Handle<BindingsArray> bindings(function->function_bindings(), isolate); + callable = handle(bindings->bound_function(), isolate); } } DCHECK(callable->IsCallable()); @@ -1636,5 +1546,22 @@ RUNTIME_FUNCTION(Runtime_IsAccessCheckNeeded) { } +RUNTIME_FUNCTION(Runtime_ObjectDefineProperty) { + HandleScope scope(isolate); + DCHECK(args.length() == 3); + CONVERT_ARG_HANDLE_CHECKED(Object, o, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, name, 1); + CONVERT_ARG_HANDLE_CHECKED(Object, attributes, 2); + return JSReceiver::DefineProperty(isolate, o, name, attributes); +} + + +RUNTIME_FUNCTION(Runtime_ObjectDefineProperties) { + HandleScope scope(isolate); + DCHECK(args.length() == 2); + CONVERT_ARG_HANDLE_CHECKED(Object, o, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, properties, 1); + return JSReceiver::DefineProperties(isolate, o, properties); +} } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-regexp.cc b/deps/v8/src/runtime/runtime-regexp.cc index 48154ea275..b4cf184c40 100644 --- a/deps/v8/src/runtime/runtime-regexp.cc +++ b/deps/v8/src/runtime/runtime-regexp.cc @@ -693,8 +693,10 @@ RUNTIME_FUNCTION(Runtime_StringSplit) { RUNTIME_ASSERT(pattern_length > 0); if (limit == 0xffffffffu) { + FixedArray* last_match_cache_unused; Handle<Object> cached_answer( RegExpResultsCache::Lookup(isolate->heap(), *subject, *pattern, + &last_match_cache_unused, RegExpResultsCache::STRING_SPLIT_SUBSTRINGS), isolate); if (*cached_answer != Smi::FromInt(0)) { @@ -757,6 +759,7 @@ RUNTIME_FUNCTION(Runtime_StringSplit) { if (limit == 0xffffffffu) { if (result->HasFastObjectElements()) { RegExpResultsCache::Enter(isolate, subject, pattern, elements, + isolate->factory()->empty_fixed_array(), RegExpResultsCache::STRING_SPLIT_SUBSTRINGS); } } @@ -785,6 +788,22 @@ RUNTIME_FUNCTION(Runtime_RegExpExec) { } +RUNTIME_FUNCTION(Runtime_RegExpFlags) { + SealHandleScope shs(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); + return regexp->flags(); +} + + +RUNTIME_FUNCTION(Runtime_RegExpSource) { + SealHandleScope shs(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); + return regexp->source(); +} + + RUNTIME_FUNCTION(Runtime_RegExpConstructResult) { HandleScope handle_scope(isolate); DCHECK(args.length() == 3); @@ -921,58 +940,24 @@ RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) { ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, escaped_source, EscapeRegExpSource(isolate, source)); - Handle<Object> global = factory->ToBoolean(flags.is_global()); - Handle<Object> ignore_case = factory->ToBoolean(flags.is_ignore_case()); - Handle<Object> multiline = factory->ToBoolean(flags.is_multiline()); - Handle<Object> sticky = factory->ToBoolean(flags.is_sticky()); - Handle<Object> unicode = factory->ToBoolean(flags.is_unicode()); + regexp->set_source(*escaped_source); + regexp->set_flags(Smi::FromInt(flags.value())); Map* map = regexp->map(); Object* constructor = map->GetConstructor(); - if (!FLAG_harmony_regexps && !FLAG_harmony_unicode_regexps && - constructor->IsJSFunction() && + if (constructor->IsJSFunction() && JSFunction::cast(constructor)->initial_map() == map) { // If we still have the original map, set in-object properties directly. - regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *escaped_source); - // Both true and false are immovable immortal objects so no need for write - // barrier. - regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, *global, - SKIP_WRITE_BARRIER); - regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, *ignore_case, - SKIP_WRITE_BARRIER); - regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, *multiline, - SKIP_WRITE_BARRIER); regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER); } else { - // Map has changed, so use generic, but slower, method. We also end here if - // the --harmony-regexp flag is set, because the initial map does not have - // space for the 'sticky' flag, since it is from the snapshot, but must work - // both with and without --harmony-regexp. When sticky comes out from under - // the flag, we will be able to use the fast initial map. - PropertyAttributes final = - static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); + // Map has changed, so use generic, but slower, method. PropertyAttributes writable = static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); - Handle<Object> zero(Smi::FromInt(0), isolate); - JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->source_string(), - escaped_source, final).Check(); - JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->global_string(), - global, final).Check(); - JSObject::SetOwnPropertyIgnoreAttributes( - regexp, factory->ignore_case_string(), ignore_case, final).Check(); JSObject::SetOwnPropertyIgnoreAttributes( - regexp, factory->multiline_string(), multiline, final).Check(); - if (FLAG_harmony_regexps) { - JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->sticky_string(), - sticky, final).Check(); - } - if (FLAG_harmony_unicode_regexps) { - JSObject::SetOwnPropertyIgnoreAttributes( - regexp, factory->unicode_string(), unicode, final).Check(); - } - JSObject::SetOwnPropertyIgnoreAttributes( - regexp, factory->last_index_string(), zero, writable).Check(); + regexp, factory->last_index_string(), + Handle<Smi>(Smi::FromInt(0), isolate), writable) + .Check(); } Handle<Object> result; @@ -1017,23 +1002,23 @@ static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject, static const int kMinLengthToCache = 0x1000; if (subject_length > kMinLengthToCache) { - Handle<Object> cached_answer( - RegExpResultsCache::Lookup(isolate->heap(), *subject, regexp->data(), - RegExpResultsCache::REGEXP_MULTIPLE_INDICES), - isolate); - if (*cached_answer != Smi::FromInt(0)) { + FixedArray* last_match_cache; + Object* cached_answer = RegExpResultsCache::Lookup( + isolate->heap(), *subject, regexp->data(), &last_match_cache, + RegExpResultsCache::REGEXP_MULTIPLE_INDICES); + if (cached_answer->IsFixedArray()) { + int capture_registers = (capture_count + 1) * 2; + int32_t* last_match = NewArray<int32_t>(capture_registers); + for (int i = 0; i < capture_registers; i++) { + last_match[i] = Smi::cast(last_match_cache->get(i))->value(); + } Handle<FixedArray> cached_fixed_array = - Handle<FixedArray>(FixedArray::cast(*cached_answer)); + Handle<FixedArray>(FixedArray::cast(cached_answer)); // The cache FixedArray is a COW-array and can therefore be reused. JSArray::SetContent(result_array, cached_fixed_array); - // The actual length of the result array is stored in the last element of - // the backing store (the backing FixedArray may have a larger capacity). - Object* cached_fixed_array_last_element = - cached_fixed_array->get(cached_fixed_array->length() - 1); - Smi* js_array_length = Smi::cast(cached_fixed_array_last_element); - result_array->set_length(js_array_length); RegExpImpl::SetLastMatchInfo(last_match_array, subject, capture_count, - NULL); + last_match); + DeleteArray(last_match); return *result_array; } } @@ -1121,19 +1106,24 @@ static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject, } RegExpImpl::SetLastMatchInfo(last_match_array, subject, capture_count, - NULL); + global_cache.LastSuccessfulMatch()); if (subject_length > kMinLengthToCache) { - // Store the length of the result array into the last element of the - // backing FixedArray. - builder.EnsureCapacity(1); - Handle<FixedArray> fixed_array = builder.array(); - fixed_array->set(fixed_array->length() - 1, - Smi::FromInt(builder.length())); + // Store the last successful match into the array for caching. + // TODO(yangguo): do not expose last match to JS and simplify caching. + int capture_registers = (capture_count + 1) * 2; + Handle<FixedArray> last_match_cache = + isolate->factory()->NewFixedArray(capture_registers); + int32_t* last_match = global_cache.LastSuccessfulMatch(); + for (int i = 0; i < capture_registers; i++) { + last_match_cache->set(i, Smi::FromInt(last_match[i])); + } + Handle<FixedArray> result_fixed_array = builder.array(); + result_fixed_array->Shrink(builder.length()); // Cache the result and turn the FixedArray into a COW array. - RegExpResultsCache::Enter(isolate, subject, - handle(regexp->data(), isolate), fixed_array, - RegExpResultsCache::REGEXP_MULTIPLE_INDICES); + RegExpResultsCache::Enter( + isolate, subject, handle(regexp->data(), isolate), result_fixed_array, + last_match_cache, RegExpResultsCache::REGEXP_MULTIPLE_INDICES); } return *builder.ToJSArray(result_array); } else { @@ -1149,8 +1139,8 @@ RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) { HandleScope handles(isolate); DCHECK(args.length() == 4); - CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); + CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2); CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); RUNTIME_ASSERT(last_match_info->HasFastObjectElements()); diff --git a/deps/v8/src/runtime/runtime-scopes.cc b/deps/v8/src/runtime/runtime-scopes.cc index c3928a7703..ecbe5cd17d 100644 --- a/deps/v8/src/runtime/runtime-scopes.cc +++ b/deps/v8/src/runtime/runtime-scopes.cc @@ -30,7 +30,7 @@ RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) { // May throw a RedeclarationError. -static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global, +static Object* DeclareGlobals(Isolate* isolate, Handle<JSGlobalObject> global, Handle<String> name, Handle<Object> value, PropertyAttributes attr, bool is_var, bool is_const, bool is_function) { @@ -87,7 +87,7 @@ static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global, RUNTIME_FUNCTION(Runtime_DeclareGlobals) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); - Handle<GlobalObject> global(isolate->global_object()); + Handle<JSGlobalObject> global(isolate->global_object()); Handle<Context> context(isolate->context()); CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 0); @@ -155,7 +155,7 @@ RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) { CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 1); CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); - Handle<GlobalObject> global(isolate->context()->global_object()); + Handle<JSGlobalObject> global(isolate->context()->global_object()); Handle<Object> result; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, result, Object::SetProperty(global, name, value, language_mode)); @@ -172,7 +172,7 @@ RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) { CONVERT_ARG_HANDLE_CHECKED(String, name, 0); CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); - Handle<GlobalObject> global = isolate->global_object(); + Handle<JSGlobalObject> global = isolate->global_object(); // Lookup the property as own on the global object. LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); @@ -223,10 +223,22 @@ Object* DeclareLookupSlot(Isolate* isolate, Handle<String> name, int index; PropertyAttributes attributes; - ContextLookupFlags flags = DONT_FOLLOW_CHAINS; BindingFlags binding_flags; - Handle<Object> holder = - context->Lookup(name, flags, &index, &attributes, &binding_flags); + + if ((attr & EVAL_DECLARED) != 0) { + // Check for a conflict with a lexically scoped variable + context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, + &binding_flags); + if (attributes != ABSENT && + (binding_flags == MUTABLE_CHECK_INITIALIZED || + binding_flags == IMMUTABLE_CHECK_INITIALIZED)) { + return ThrowRedeclarationError(isolate, name); + } + attr = static_cast<PropertyAttributes>(attr & ~EVAL_DECLARED); + } + + Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, + &attributes, &binding_flags); if (holder.is_null()) { // In case of JSProxy, an exception might have been thrown. if (isolate->has_pending_exception()) return isolate->heap()->exception(); @@ -307,21 +319,14 @@ Object* DeclareLookupSlot(Isolate* isolate, Handle<String> name, RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) { HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - CONVERT_ARG_HANDLE_CHECKED(String, name, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 1); - - return DeclareLookupSlot(isolate, name, initial_value, NONE); -} - - -RUNTIME_FUNCTION(Runtime_DeclareReadOnlyLookupSlot) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); + DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, name, 0); CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 1); + CONVERT_ARG_HANDLE_CHECKED(Smi, property_attributes, 2); - return DeclareLookupSlot(isolate, name, initial_value, READ_ONLY); + PropertyAttributes attributes = + static_cast<PropertyAttributes>(property_attributes->value()); + return DeclareLookupSlot(isolate, name, initial_value, attributes); } @@ -410,7 +415,7 @@ template <typename T> Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee, T parameters, int argument_count) { CHECK(!IsSubclassConstructor(callee->shared()->kind())); - DCHECK(callee->has_simple_parameters()); + DCHECK(callee->shared()->has_simple_parameters()); Handle<JSObject> result = isolate->factory()->NewArgumentsObject(callee, argument_count); @@ -621,7 +626,7 @@ RUNTIME_FUNCTION(Runtime_NewClosure_Tenured) { } static Object* FindNameClash(Handle<ScopeInfo> scope_info, - Handle<GlobalObject> global_object, + Handle<JSGlobalObject> global_object, Handle<ScriptContextTable> script_context) { Isolate* isolate = scope_info->GetIsolate(); for (int var = 0; var < scope_info->ContextLocalCount(); var++) { @@ -643,7 +648,7 @@ static Object* FindNameClash(Handle<ScopeInfo> scope_info, return ThrowRedeclarationError(isolate, name); } - GlobalObject::InvalidatePropertyCell(global_object, name); + JSGlobalObject::InvalidatePropertyCell(global_object, name); } } return isolate->heap()->undefined_value(); @@ -656,7 +661,7 @@ RUNTIME_FUNCTION(Runtime_NewScriptContext) { CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1); - Handle<GlobalObject> global_object(function->context()->global_object()); + Handle<JSGlobalObject> global_object(function->context()->global_object()); Handle<Context> native_context(global_object->native_context()); Handle<ScriptContextTable> script_context_table( native_context->script_context_table()); @@ -668,9 +673,8 @@ 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(global_object->IsJSBuiltinsObject() - ? *function - : native_context->closure()); + Handle<JSFunction> closure( + function->shared()->IsBuiltin() ? *function : native_context->closure()); Handle<Context> result = isolate->factory()->NewScriptContext(closure, scope_info); @@ -859,7 +863,8 @@ RUNTIME_FUNCTION(Runtime_DeclareModules) { } } - JSObject::PreventExtensions(module).Assert(); + if (JSObject::PreventExtensions(module, Object::THROW_ON_ERROR).IsNothing()) + DCHECK(false); } DCHECK(!isolate->has_pending_exception()); @@ -905,7 +910,7 @@ RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) { static Object* ComputeReceiverForNonGlobal(Isolate* isolate, JSObject* holder) { - DCHECK(!holder->IsGlobalObject()); + DCHECK(!holder->IsJSGlobalObject()); // If the holder isn't a context extension object, we just return it // as the receiver. This allows arguments objects to be used as @@ -983,7 +988,7 @@ static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate, Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder); // GetProperty below can cause GC. Handle<Object> receiver_handle( - object->IsGlobalObject() + object->IsJSGlobalObject() ? Object::cast(isolate->heap()->undefined_value()) : object->IsJSProxy() ? static_cast<Object*>(*object) : ComputeReceiverForNonGlobal( diff --git a/deps/v8/src/runtime/runtime-strings.cc b/deps/v8/src/runtime/runtime-strings.cc index 3ce5a58e2b..dd4983e75f 100644 --- a/deps/v8/src/runtime/runtime-strings.cc +++ b/deps/v8/src/runtime/runtime-strings.cc @@ -405,18 +405,6 @@ RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) { } -RUNTIME_FUNCTION(Runtime_CharFromCode) { - HandleScope handlescope(isolate); - DCHECK(args.length() == 1); - if (args[0]->IsNumber()) { - CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]); - code &= 0xffff; - return *isolate->factory()->LookupSingleCharacterStringFromCode(code); - } - return isolate->heap()->empty_string(); -} - - RUNTIME_FUNCTION(Runtime_StringCompare) { HandleScope handle_scope(isolate); DCHECK_EQ(2, args.length()); @@ -1185,8 +1173,14 @@ RUNTIME_FUNCTION(Runtime_FlattenString) { RUNTIME_FUNCTION(Runtime_StringCharFromCode) { - SealHandleScope shs(isolate); - return __RT_impl_Runtime_CharFromCode(args, isolate); + HandleScope handlescope(isolate); + DCHECK_EQ(1, args.length()); + if (args[0]->IsNumber()) { + CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]); + code &= 0xffff; + return *isolate->factory()->LookupSingleCharacterStringFromCode(code); + } + return isolate->heap()->empty_string(); } @@ -1198,7 +1192,7 @@ RUNTIME_FUNCTION(Runtime_StringCharAt) { if (std::isinf(args.number_at(1))) return isolate->heap()->empty_string(); Object* code = __RT_impl_Runtime_StringCharCodeAtRT(args, isolate); if (code->IsNaN()) return isolate->heap()->empty_string(); - return __RT_impl_Runtime_CharFromCode(Arguments(1, &code), isolate); + return __RT_impl_Runtime_StringCharFromCode(Arguments(1, &code), isolate); } diff --git a/deps/v8/src/runtime/runtime-symbol.cc b/deps/v8/src/runtime/runtime-symbol.cc index 778c241709..234b45606d 100644 --- a/deps/v8/src/runtime/runtime-symbol.cc +++ b/deps/v8/src/runtime/runtime-symbol.cc @@ -28,7 +28,9 @@ RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) { DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); - return *isolate->factory()->NewPrivateSymbol(name); + Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol(); + if (name->IsString()) symbol->set_name(*name); + return *symbol; } diff --git a/deps/v8/src/runtime/runtime-typedarray.cc b/deps/v8/src/runtime/runtime-typedarray.cc index 8a3fce0a92..f39e37072d 100644 --- a/deps/v8/src/runtime/runtime-typedarray.cc +++ b/deps/v8/src/runtime/runtime-typedarray.cc @@ -33,7 +33,7 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) { holder, isolate, allocated_length, true, is_shared ? SharedFlag::kShared : SharedFlag::kNotShared)) { THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength)); + isolate, NewRangeError(MessageTemplate::kArrayBufferAllocationFailed)); } return *holder; } @@ -164,8 +164,8 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) { // All checks are done, now we can modify objects. - DCHECK(holder->GetInternalFieldCount() == - v8::ArrayBufferView::kInternalFieldCount); + DCHECK_EQ(v8::ArrayBufferView::kInternalFieldCount, + holder->GetInternalFieldCount()); for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { holder->SetInternalField(i, Smi::FromInt(0)); } @@ -238,8 +238,8 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) { } size_t byte_length = length * element_size; - DCHECK(holder->GetInternalFieldCount() == - v8::ArrayBufferView::kInternalFieldCount); + DCHECK_EQ(v8::ArrayBufferView::kInternalFieldCount, + holder->GetInternalFieldCount()); for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { holder->SetInternalField(i, Smi::FromInt(0)); } @@ -441,8 +441,8 @@ RUNTIME_FUNCTION(Runtime_DataViewInitialize) { CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2); CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3); - DCHECK(holder->GetInternalFieldCount() == - v8::ArrayBufferView::kInternalFieldCount); + DCHECK_EQ(v8::ArrayBufferView::kInternalFieldCount, + holder->GetInternalFieldCount()); for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { holder->SetInternalField(i, Smi::FromInt(0)); } diff --git a/deps/v8/src/runtime/runtime-utils.h b/deps/v8/src/runtime/runtime-utils.h index 4b072b1eb6..ded2c090c8 100644 --- a/deps/v8/src/runtime/runtime-utils.h +++ b/deps/v8/src/runtime/runtime-utils.h @@ -162,7 +162,7 @@ static inline ObjectPair MakePair(Object* x, Object* y) { } #endif -} -} // namespace v8::internal +} // namespace internal +} // namespace v8 #endif // V8_RUNTIME_RUNTIME_UTILS_H_ diff --git a/deps/v8/src/runtime/runtime.cc b/deps/v8/src/runtime/runtime.cc index 15451c5c6e..90f4e4ce33 100644 --- a/deps/v8/src/runtime/runtime.cc +++ b/deps/v8/src/runtime/runtime.cc @@ -4,6 +4,7 @@ #include "src/runtime/runtime.h" +#include "src/assembler.h" #include "src/contexts.h" #include "src/handles-inl.h" #include "src/heap/heap.h" @@ -94,6 +95,31 @@ const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { } +const Runtime::Function* Runtime::RuntimeFunctionTable(Isolate* isolate) { + if (isolate->external_reference_redirector()) { + // When running with the simulator we need to provide a table which has + // redirected runtime entry addresses. + if (!isolate->runtime_state()->redirected_intrinsic_functions()) { + size_t function_count = arraysize(kIntrinsicFunctions); + Function* redirected_functions = new Function[function_count]; + memcpy(redirected_functions, kIntrinsicFunctions, + sizeof(kIntrinsicFunctions)); + for (size_t i = 0; i < function_count; i++) { + ExternalReference redirected_entry(static_cast<Runtime::FunctionId>(i), + isolate); + redirected_functions[i].entry = redirected_entry.address(); + } + isolate->runtime_state()->set_redirected_intrinsic_functions( + redirected_functions); + } + + return isolate->runtime_state()->redirected_intrinsic_functions(); + } else { + return kIntrinsicFunctions; + } +} + + std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) { return os << Runtime::FunctionForId(id)->name; } diff --git a/deps/v8/src/runtime/runtime.h b/deps/v8/src/runtime/runtime.h index 6e55d74794..23f9bdc1f7 100644 --- a/deps/v8/src/runtime/runtime.h +++ b/deps/v8/src/runtime/runtime.h @@ -176,7 +176,7 @@ namespace internal { F(DebugPrintScopes, 0, 1) \ F(GetThreadCount, 1, 1) \ F(GetThreadDetails, 2, 1) \ - F(SetDisableBreak, 1, 1) \ + F(SetBreakPointsActive, 1, 1) \ F(GetBreakLocations, 2, 1) \ F(SetFunctionBreakPoint, 3, 1) \ F(SetScriptBreakPoint, 4, 1) \ @@ -201,7 +201,7 @@ namespace internal { F(GetScript, 1, 1) \ F(DebugCallbackSupportsStepping, 1, 1) \ F(DebugPrepareStepInIfStepping, 1, 1) \ - F(DebugPushPromise, 2, 1) \ + F(DebugPushPromise, 3, 1) \ F(DebugPopPromise, 0, 1) \ F(DebugPromiseEvent, 1, 1) \ F(DebugAsyncTaskEvent, 1, 1) \ @@ -225,14 +225,18 @@ namespace internal { F(InterpreterGreaterThan, 2, 1) \ F(InterpreterLessThanOrEqual, 2, 1) \ F(InterpreterGreaterThanOrEqual, 2, 1) \ - F(InterpreterToBoolean, 1, 1) + F(InterpreterToBoolean, 1, 1) \ + F(InterpreterLogicalNot, 1, 1) \ + F(InterpreterTypeOf, 1, 1) \ + F(InterpreterNewClosure, 2, 1) \ + F(InterpreterForInPrepare, 1, 1) #define FOR_EACH_INTRINSIC_FUNCTION(F) \ F(FunctionGetName, 1, 1) \ F(FunctionSetName, 2, 1) \ F(FunctionNameShouldPrintAsAnonymous, 1, 1) \ - F(FunctionMarkNameShouldPrintAsAnonymous, 1, 1) \ + F(CompleteFunctionConstruction, 3, 1) \ F(FunctionIsArrow, 1, 1) \ F(FunctionIsConciseMethod, 1, 1) \ F(FunctionRemovePrototype, 1, 1) \ @@ -256,7 +260,7 @@ namespace internal { F(Call, -1 /* >= 2 */, 1) \ F(Apply, 5, 1) \ F(GetOriginalConstructor, 0, 1) \ - F(CallFunction, -1 /* receiver + n args + function */, 1) \ + F(ConvertReceiver, 1, 1) \ F(IsConstructCall, 0, 1) \ F(IsFunction, 1, 1) @@ -345,8 +349,6 @@ namespace internal { F(CallSiteIsConstructorRT, 1, 1) \ F(IS_VAR, 1, 1) \ F(IncrementStatsCounter, 1, 1) \ - F(Likely, 1, 1) \ - F(Unlikely, 1, 1) \ F(HarmonyToString, 0, 1) \ F(GetTypeFeedbackVector, 1, 1) \ F(GetCallerJSFunction, 0, 1) \ @@ -399,7 +401,8 @@ namespace internal { F(RoundNumber, 1, 1) \ F(MathSqrt, 1, 1) \ F(MathFround, 1, 1) \ - F(IsMinusZero, 1, 1) + F(IsMinusZero, 1, 1) \ + F(InitializeRNG, 0, 1) #define FOR_EACH_INTRINSIC_NUMBERS(F) \ @@ -495,7 +498,9 @@ namespace internal { F(InstanceOf, 2, 1) \ F(HasInPrototypeChain, 2, 1) \ F(CreateIterResultObject, 2, 1) \ - F(IsAccessCheckNeeded, 1, 1) + F(IsAccessCheckNeeded, 1, 1) \ + F(ObjectDefineProperties, 2, 1) \ + F(ObjectDefineProperty, 3, 1) #define FOR_EACH_INTRINSIC_OBSERVE(F) \ @@ -551,6 +556,8 @@ namespace internal { F(StringReplaceGlobalRegExpWithString, 4, 1) \ F(StringSplit, 3, 1) \ F(RegExpExec, 4, 1) \ + F(RegExpFlags, 1, 1) \ + F(RegExpSource, 1, 1) \ F(RegExpConstructResult, 3, 1) \ F(RegExpInitializeAndCompile, 3, 1) \ F(MaterializeRegExpLiteral, 4, 1) \ @@ -564,8 +571,7 @@ namespace internal { F(DeclareGlobals, 2, 1) \ F(InitializeVarGlobal, 3, 1) \ F(InitializeConstGlobal, 2, 1) \ - F(DeclareLookupSlot, 2, 1) \ - F(DeclareReadOnlyLookupSlot, 2, 1) \ + F(DeclareLookupSlot, 3, 1) \ F(InitializeLegacyConstLookupSlot, 3, 1) \ F(NewSloppyArguments_Generic, 1, 1) \ F(NewStrictArguments_Generic, 1, 1) \ @@ -904,7 +910,6 @@ namespace internal { F(InternalizeString, 1, 1) \ F(StringMatch, 3, 1) \ F(StringCharCodeAtRT, 2, 1) \ - F(CharFromCode, 1, 1) \ F(StringCompare, 2, 1) \ F(StringBuilderConcat, 3, 1) \ F(StringBuilderJoin, 3, 1) \ @@ -1110,27 +1115,6 @@ FOR_EACH_INTRINSIC_RETURN_OBJECT(F) //--------------------------------------------------------------------------- // Runtime provides access to all C++ runtime functions. -class RuntimeState { - public: - unibrow::Mapping<unibrow::ToUppercase, 128>* to_upper_mapping() { - return &to_upper_mapping_; - } - unibrow::Mapping<unibrow::ToLowercase, 128>* to_lower_mapping() { - return &to_lower_mapping_; - } - - private: - RuntimeState() {} - unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping_; - unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping_; - - friend class Isolate; - friend class Runtime; - - DISALLOW_COPY_AND_ASSIGN(RuntimeState); -}; - - class Runtime : public AllStatic { public: enum FunctionId { @@ -1179,6 +1163,9 @@ class Runtime : public AllStatic { // Get the intrinsic function with the given function entry address. static const Function* FunctionForEntry(Address ref); + // Get the runtime intrinsic function table. + static const Function* RuntimeFunctionTable(Isolate* isolate); + MUST_USE_RESULT static MaybeHandle<Object> DeleteObjectProperty( Isolate* isolate, Handle<JSReceiver> receiver, Handle<Object> key, LanguageMode language_mode); @@ -1229,6 +1216,38 @@ class Runtime : public AllStatic { }; +class RuntimeState { + public: + unibrow::Mapping<unibrow::ToUppercase, 128>* to_upper_mapping() { + return &to_upper_mapping_; + } + unibrow::Mapping<unibrow::ToLowercase, 128>* to_lower_mapping() { + return &to_lower_mapping_; + } + + Runtime::Function* redirected_intrinsic_functions() { + return redirected_intrinsic_functions_.get(); + } + + void set_redirected_intrinsic_functions( + Runtime::Function* redirected_intrinsic_functions) { + redirected_intrinsic_functions_.Reset(redirected_intrinsic_functions); + } + + private: + RuntimeState() {} + unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping_; + unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping_; + + base::SmartArrayPointer<Runtime::Function> redirected_intrinsic_functions_; + + friend class Isolate; + friend class Runtime; + + DISALLOW_COPY_AND_ASSIGN(RuntimeState); +}; + + std::ostream& operator<<(std::ostream&, Runtime::FunctionId); //--------------------------------------------------------------------------- |