diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2015-01-07 18:38:38 +0100 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2015-01-07 22:11:18 +0100 |
commit | dad73f645cde6920e79db956e7ef82ed640d7615 (patch) | |
tree | 7ba3f3fc7e0722c5f130065461b7c56f571af383 /deps/v8/src/runtime | |
parent | 53ba494537259b18b346dc6150d6a100c557e08f (diff) | |
download | node-new-dad73f645cde6920e79db956e7ef82ed640d7615.tar.gz |
deps: upgrade v8 to 3.31.74.1
PR-URL: https://github.com/iojs/io.js/pull/243
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Diffstat (limited to 'deps/v8/src/runtime')
-rw-r--r-- | deps/v8/src/runtime/runtime-array.cc | 163 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-classes.cc | 117 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-collections.cc | 77 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-compiler.cc | 17 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-debug.cc | 120 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-generator.cc | 12 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-literals.cc | 47 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-object.cc | 119 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-observe.cc | 13 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-regexp.cc | 139 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-scopes.cc | 80 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-strings.cc | 2 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-test.cc | 14 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime-uri.cc | 32 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime.cc | 3 | ||||
-rw-r--r-- | deps/v8/src/runtime/runtime.h | 63 | ||||
-rw-r--r-- | deps/v8/src/runtime/string-builder.h | 296 |
17 files changed, 695 insertions, 619 deletions
diff --git a/deps/v8/src/runtime/runtime-array.cc b/deps/v8/src/runtime/runtime-array.cc index 523d8f5faa..a017236a54 100644 --- a/deps/v8/src/runtime/runtime-array.cc +++ b/deps/v8/src/runtime/runtime-array.cc @@ -289,11 +289,11 @@ static uint32_t EstimateElementCount(Handle<JSArray> array) { template <class ExternalArrayClass, class ElementType> -static void IterateExternalArrayElements(Isolate* isolate, - Handle<JSObject> receiver, - bool elements_are_ints, - bool elements_are_guaranteed_smis, - ArrayConcatVisitor* visitor) { +static void IterateTypedArrayElements(Isolate* isolate, + Handle<JSObject> receiver, + bool elements_are_ints, + bool elements_are_guaranteed_smis, + ArrayConcatVisitor* visitor) { Handle<ExternalArrayClass> array( ExternalArrayClass::cast(receiver->elements())); uint32_t len = static_cast<uint32_t>(array->length()); @@ -439,8 +439,27 @@ static void CollectElementIndices(Handle<JSObject> object, uint32_t range, } +static bool IterateElementsSlow(Isolate* isolate, Handle<JSObject> receiver, + uint32_t length, ArrayConcatVisitor* visitor) { + for (uint32_t i = 0; i < length; ++i) { + HandleScope loop_scope(isolate); + Maybe<bool> maybe = JSReceiver::HasElement(receiver, i); + if (!maybe.has_value) return false; + if (maybe.value) { + Handle<Object> element_value; + ASSIGN_RETURN_ON_EXCEPTION_VALUE( + isolate, element_value, + Runtime::GetElementOrCharAt(isolate, receiver, i), false); + visitor->visit(i, element_value); + } + } + visitor->increase_index_offset(length); + return true; +} + + /** - * A helper function that visits elements of a JSArray in numerical + * A helper function that visits elements of a JSObject in numerical * order. * * The visitor argument called for each existing element in the array @@ -449,9 +468,32 @@ static void CollectElementIndices(Handle<JSObject> object, uint32_t range, * length. * Returns false if any access threw an exception, otherwise true. */ -static bool IterateElements(Isolate* isolate, Handle<JSArray> receiver, +static bool IterateElements(Isolate* isolate, Handle<JSObject> receiver, ArrayConcatVisitor* visitor) { - uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); + uint32_t length = 0; + + if (receiver->IsJSArray()) { + Handle<JSArray> array(Handle<JSArray>::cast(receiver)); + length = static_cast<uint32_t>(array->length()->Number()); + } else { + Handle<Object> val; + Handle<Object> key(isolate->heap()->length_string(), isolate); + ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, val, + Runtime::GetObjectProperty(isolate, receiver, key), false); + // TODO(caitp): Support larger element indexes (up to 2^53-1). + if (!val->ToUint32(&length)) { + ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, val, + Execution::ToLength(isolate, val), false); + val->ToUint32(&length); + } + } + + if (!(receiver->IsJSArray() || receiver->IsJSTypedArray())) { + // For classes which are not known to be safe to access via elements alone, + // use the slow case. + return IterateElementsSlow(isolate, receiver, length, visitor); + } + switch (receiver->GetElementsKind()) { case FAST_SMI_ELEMENTS: case FAST_ELEMENTS: @@ -552,55 +594,132 @@ static bool IterateElements(Isolate* isolate, Handle<JSArray> receiver, } break; } + case UINT8_CLAMPED_ELEMENTS: { + Handle<FixedUint8ClampedArray> pixels( + FixedUint8ClampedArray::cast(receiver->elements())); + for (uint32_t j = 0; j < length; j++) { + Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate); + visitor->visit(j, e); + } + break; + } case EXTERNAL_INT8_ELEMENTS: { - IterateExternalArrayElements<ExternalInt8Array, int8_t>( + IterateTypedArrayElements<ExternalInt8Array, int8_t>( isolate, receiver, true, true, visitor); break; } + case INT8_ELEMENTS: { + IterateTypedArrayElements<FixedInt8Array, int8_t>( + isolate, receiver, true, true, visitor); + break; + } case EXTERNAL_UINT8_ELEMENTS: { - IterateExternalArrayElements<ExternalUint8Array, uint8_t>( + IterateTypedArrayElements<ExternalUint8Array, uint8_t>( isolate, receiver, true, true, visitor); break; } + case UINT8_ELEMENTS: { + IterateTypedArrayElements<FixedUint8Array, uint8_t>( + isolate, receiver, true, true, visitor); + break; + } case EXTERNAL_INT16_ELEMENTS: { - IterateExternalArrayElements<ExternalInt16Array, int16_t>( + IterateTypedArrayElements<ExternalInt16Array, int16_t>( isolate, receiver, true, true, visitor); break; } + case INT16_ELEMENTS: { + IterateTypedArrayElements<FixedInt16Array, int16_t>( + isolate, receiver, true, true, visitor); + break; + } case EXTERNAL_UINT16_ELEMENTS: { - IterateExternalArrayElements<ExternalUint16Array, uint16_t>( + IterateTypedArrayElements<ExternalUint16Array, uint16_t>( isolate, receiver, true, true, visitor); break; } + case UINT16_ELEMENTS: { + IterateTypedArrayElements<FixedUint16Array, uint16_t>( + isolate, receiver, true, true, visitor); + break; + } case EXTERNAL_INT32_ELEMENTS: { - IterateExternalArrayElements<ExternalInt32Array, int32_t>( + IterateTypedArrayElements<ExternalInt32Array, int32_t>( isolate, receiver, true, false, visitor); break; } + case INT32_ELEMENTS: { + IterateTypedArrayElements<FixedInt32Array, int32_t>( + isolate, receiver, true, false, visitor); + break; + } case EXTERNAL_UINT32_ELEMENTS: { - IterateExternalArrayElements<ExternalUint32Array, uint32_t>( + IterateTypedArrayElements<ExternalUint32Array, uint32_t>( isolate, receiver, true, false, visitor); break; } + case UINT32_ELEMENTS: { + IterateTypedArrayElements<FixedUint32Array, uint32_t>( + isolate, receiver, true, false, visitor); + break; + } case EXTERNAL_FLOAT32_ELEMENTS: { - IterateExternalArrayElements<ExternalFloat32Array, float>( + IterateTypedArrayElements<ExternalFloat32Array, float>( isolate, receiver, false, false, visitor); break; } + case FLOAT32_ELEMENTS: { + IterateTypedArrayElements<FixedFloat32Array, float>( + isolate, receiver, false, false, visitor); + break; + } case EXTERNAL_FLOAT64_ELEMENTS: { - IterateExternalArrayElements<ExternalFloat64Array, double>( + IterateTypedArrayElements<ExternalFloat64Array, double>( isolate, receiver, false, false, visitor); break; } - default: - UNREACHABLE(); + case FLOAT64_ELEMENTS: { + IterateTypedArrayElements<FixedFloat64Array, double>( + isolate, receiver, false, false, visitor); + break; + } + case SLOPPY_ARGUMENTS_ELEMENTS: { + ElementsAccessor* accessor = receiver->GetElementsAccessor(); + for (uint32_t index = 0; index < length; index++) { + HandleScope loop_scope(isolate); + if (accessor->HasElement(receiver, receiver, index)) { + Handle<Object> element; + ASSIGN_RETURN_ON_EXCEPTION_VALUE( + isolate, element, accessor->Get(receiver, receiver, index), + false); + visitor->visit(index, element); + } + } break; + } } visitor->increase_index_offset(length); return true; } +static bool IsConcatSpreadable(Isolate* isolate, Handle<Object> obj) { + HandleScope handle_scope(isolate); + if (!obj->IsSpecObject()) return false; + if (obj->IsJSArray()) return true; + if (FLAG_harmony_arrays) { + Handle<Symbol> key(isolate->factory()->is_concat_spreadable_symbol()); + Handle<Object> value; + MaybeHandle<Object> maybeValue = + i::Runtime::GetObjectProperty(isolate, obj, key); + if (maybeValue.ToHandle(&value)) { + return value->BooleanValue(); + } + } + return false; +} + + /** * Array::concat implementation. * See ECMAScript 262, 15.4.4.4. @@ -771,9 +890,11 @@ RUNTIME_FUNCTION(Runtime_ArrayConcat) { for (int i = 0; i < argument_count; i++) { Handle<Object> obj(elements->get(i), isolate); - if (obj->IsJSArray()) { - Handle<JSArray> array = Handle<JSArray>::cast(obj); - if (!IterateElements(isolate, array, &visitor)) { + bool spreadable = IsConcatSpreadable(isolate, obj); + if (isolate->has_pending_exception()) return isolate->heap()->exception(); + if (spreadable) { + Handle<JSObject> object = Handle<JSObject>::cast(obj); + if (!IterateElements(isolate, object, &visitor)) { return isolate->heap()->exception(); } } else { diff --git a/deps/v8/src/runtime/runtime-classes.cc b/deps/v8/src/runtime/runtime-classes.cc index cc4e09b52f..7c827f0bd9 100644 --- a/deps/v8/src/runtime/runtime-classes.cc +++ b/deps/v8/src/runtime/runtime-classes.cc @@ -62,7 +62,7 @@ RUNTIME_FUNCTION(Runtime_DefineClass) { DCHECK(args.length() == 6); CONVERT_ARG_HANDLE_CHECKED(Object, name, 0); CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 1); - CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 2); + CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 2); CONVERT_ARG_HANDLE_CHECKED(Script, script, 3); CONVERT_SMI_ARG_CHECKED(start_position, 4); CONVERT_SMI_ARG_CHECKED(end_position, 5); @@ -98,58 +98,54 @@ RUNTIME_FUNCTION(Runtime_DefineClass) { Handle<Map> map = isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); - map->set_prototype(*prototype_parent); + map->SetPrototype(prototype_parent); + map->set_constructor(*constructor); Handle<JSObject> prototype = isolate->factory()->NewJSObjectFromMap(map); Handle<String> name_string = name->IsString() ? Handle<String>::cast(name) : isolate->factory()->empty_string(); + constructor->shared()->set_name(*name_string); - Handle<JSFunction> ctor; - if (constructor->IsSpecFunction()) { - ctor = Handle<JSFunction>::cast(constructor); - JSFunction::SetPrototype(ctor, prototype); - PropertyAttributes attribs = - static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); - RETURN_FAILURE_ON_EXCEPTION( - isolate, - JSObject::SetOwnPropertyIgnoreAttributes( - ctor, isolate->factory()->prototype_string(), prototype, attribs)); - } else { - // TODO(arv): This should not use an empty function but a function that - // calls super. - Handle<Code> code(isolate->builtins()->builtin(Builtins::kEmptyFunction)); - ctor = isolate->factory()->NewFunction(name_string, code, prototype, true); - } + JSFunction::SetPrototype(constructor, prototype); + PropertyAttributes attribs = + static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); + RETURN_FAILURE_ON_EXCEPTION( + isolate, JSObject::SetOwnPropertyIgnoreAttributes( + constructor, isolate->factory()->prototype_string(), + prototype, attribs)); + // TODO(arv): Only do this conditionally. Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol()); RETURN_FAILURE_ON_EXCEPTION( isolate, JSObject::SetOwnPropertyIgnoreAttributes( - ctor, home_object_symbol, prototype, DONT_ENUM)); + constructor, home_object_symbol, prototype, DONT_ENUM)); if (!constructor_parent.is_null()) { RETURN_FAILURE_ON_EXCEPTION( - isolate, JSObject::SetPrototype(ctor, constructor_parent, false)); + isolate, + JSObject::SetPrototype(constructor, constructor_parent, false)); } JSObject::AddProperty(prototype, isolate->factory()->constructor_string(), - ctor, DONT_ENUM); + constructor, DONT_ENUM); // Install private properties that are used to construct the FunctionToString. RETURN_FAILURE_ON_EXCEPTION( + isolate, Object::SetProperty(constructor, + isolate->factory()->class_script_symbol(), + script, STRICT)); + RETURN_FAILURE_ON_EXCEPTION( isolate, - Object::SetProperty(ctor, isolate->factory()->class_script_symbol(), - script, STRICT)); + Object::SetProperty( + constructor, isolate->factory()->class_start_position_symbol(), + handle(Smi::FromInt(start_position), isolate), STRICT)); RETURN_FAILURE_ON_EXCEPTION( isolate, Object::SetProperty( - ctor, isolate->factory()->class_start_position_symbol(), - handle(Smi::FromInt(start_position), isolate), STRICT)); - RETURN_FAILURE_ON_EXCEPTION( - isolate, - Object::SetProperty(ctor, isolate->factory()->class_end_position_symbol(), - handle(Smi::FromInt(end_position), isolate), STRICT)); + constructor, isolate->factory()->class_end_position_symbol(), + handle(Smi::FromInt(end_position), isolate), STRICT)); - return *ctor; + return *constructor; } @@ -160,11 +156,6 @@ RUNTIME_FUNCTION(Runtime_DefineClassMethod) { CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 2); - RETURN_FAILURE_ON_EXCEPTION( - isolate, JSObject::SetOwnPropertyIgnoreAttributes( - function, isolate->factory()->home_object_symbol(), object, - DONT_ENUM)); - uint32_t index; if (key->ToArrayIndex(&index)) { RETURN_FAILURE_ON_EXCEPTION( @@ -198,11 +189,6 @@ RUNTIME_FUNCTION(Runtime_DefineClassGetter) { Runtime::ToName(isolate, key)); RETURN_FAILURE_ON_EXCEPTION( isolate, - JSObject::SetOwnPropertyIgnoreAttributes( - getter, isolate->factory()->home_object_symbol(), object, DONT_ENUM)); - - RETURN_FAILURE_ON_EXCEPTION( - isolate, JSObject::DefineAccessor(object, name, getter, isolate->factory()->null_value(), NONE)); return isolate->heap()->undefined_value(); @@ -221,10 +207,6 @@ RUNTIME_FUNCTION(Runtime_DefineClassSetter) { Runtime::ToName(isolate, key)); RETURN_FAILURE_ON_EXCEPTION( isolate, - JSObject::SetOwnPropertyIgnoreAttributes( - setter, isolate->factory()->home_object_symbol(), object, DONT_ENUM)); - RETURN_FAILURE_ON_EXCEPTION( - isolate, JSObject::DefineAccessor(object, name, isolate->factory()->null_value(), setter, NONE)); return isolate->heap()->undefined_value(); @@ -455,5 +437,52 @@ RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Sloppy) { return StoreKeyedToSuper(isolate, home_object, receiver, key, value, SLOPPY); } + + +RUNTIME_FUNCTION(Runtime_DefaultConstructorSuperCall) { + HandleScope scope(isolate); + DCHECK(args.length() == 0); + + // Compute the frame holding the arguments. + JavaScriptFrameIterator it(isolate); + it.AdvanceToArgumentsFrame(); + JavaScriptFrame* frame = it.frame(); + + Handle<JSFunction> function(frame->function(), isolate); + Handle<Object> receiver(frame->receiver(), isolate); + + Handle<Object> proto_function; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, proto_function, + Runtime::GetPrototype(isolate, function)); + + // Get the actual number of provided arguments. + const int argc = frame->ComputeParametersCount(); + + // Loose upper bound to allow fuzzing. We'll most likely run out of + // stack space before hitting this limit. + static int kMaxArgc = 1000000; + RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc); + + // If there are too many arguments, allocate argv via malloc. + const int argv_small_size = 10; + Handle<Object> argv_small_buffer[argv_small_size]; + 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 = SmartArrayPointer<Handle<Object> >(argv); + } + + for (int i = 0; i < argc; ++i) { + argv[i] = handle(frame->GetParameter(i), isolate); + } + + Handle<Object> result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, + Execution::Call(isolate, proto_function, receiver, argc, argv, false)); + return *result; +} } } // namespace v8::internal diff --git a/deps/v8/src/runtime/runtime-collections.cc b/deps/v8/src/runtime/runtime-collections.cc index 45ac41c620..abdd056998 100644 --- a/deps/v8/src/runtime/runtime-collections.cc +++ b/deps/v8/src/runtime/runtime-collections.cc @@ -115,6 +115,22 @@ RUNTIME_FUNCTION(Runtime_SetIteratorNext) { } +// The array returned contains the following information: +// 0: HasMore flag +// 1: Iteration index +// 2: Iteration kind +RUNTIME_FUNCTION(Runtime_SetIteratorDetails) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0); + Handle<FixedArray> details = isolate->factory()->NewFixedArray(4); + details->set(0, isolate->heap()->ToBoolean(holder->HasMore())); + details->set(1, holder->index()); + details->set(2, holder->kind()); + return *isolate->factory()->NewJSArrayWithElements(details); +} + + RUNTIME_FUNCTION(Runtime_MapInitialize) { HandleScope scope(isolate); DCHECK(args.length() == 1); @@ -225,25 +241,47 @@ RUNTIME_FUNCTION(Runtime_MapIteratorClone) { } -RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { +// The array returned contains the following information: +// 0: HasMore flag +// 1: Iteration index +// 2: Iteration kind +RUNTIME_FUNCTION(Runtime_MapIteratorDetails) { HandleScope scope(isolate); DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); + Handle<FixedArray> details = isolate->factory()->NewFixedArray(4); + details->set(0, isolate->heap()->ToBoolean(holder->HasMore())); + details->set(1, holder->index()); + details->set(2, holder->kind()); + return *isolate->factory()->NewJSArrayWithElements(details); +} + + +RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { + HandleScope scope(isolate); + DCHECK(args.length() == 2); CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); + CONVERT_NUMBER_CHECKED(int, max_entries, Int32, args[1]); + RUNTIME_ASSERT(max_entries >= 0); + Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table())); + if (max_entries == 0 || max_entries > table->NumberOfElements()) { + max_entries = table->NumberOfElements(); + } Handle<FixedArray> entries = - isolate->factory()->NewFixedArray(table->NumberOfElements() * 2); + isolate->factory()->NewFixedArray(max_entries * 2); { DisallowHeapAllocation no_gc; - int number_of_non_hole_elements = 0; - for (int i = 0; i < table->Capacity(); i++) { + int count = 0; + for (int i = 0; count / 2 < max_entries && i < table->Capacity(); i++) { Handle<Object> key(table->KeyAt(i), isolate); if (table->IsKey(*key)) { - entries->set(number_of_non_hole_elements++, *key); + entries->set(count++, *key); Object* value = table->Lookup(key); - entries->set(number_of_non_hole_elements++, value); + entries->set(count++, value); } } - DCHECK_EQ(table->NumberOfElements() * 2, number_of_non_hole_elements); + DCHECK_EQ(max_entries * 2, count); } return *isolate->factory()->NewJSArrayWithElements(entries); } @@ -346,21 +384,28 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionSet) { RUNTIME_FUNCTION(Runtime_GetWeakSetValues) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK(args.length() == 2); CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); + CONVERT_NUMBER_CHECKED(int, max_values, Int32, args[1]); + RUNTIME_ASSERT(max_values >= 0); + Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table())); - Handle<FixedArray> values = - isolate->factory()->NewFixedArray(table->NumberOfElements()); + if (max_values == 0 || max_values > table->NumberOfElements()) { + max_values = table->NumberOfElements(); + } + Handle<FixedArray> values = isolate->factory()->NewFixedArray(max_values); + // Recompute max_values because GC could have removed elements from the table. + if (max_values > table->NumberOfElements()) { + max_values = table->NumberOfElements(); + } { DisallowHeapAllocation no_gc; - int number_of_non_hole_elements = 0; - for (int i = 0; i < table->Capacity(); i++) { + int count = 0; + for (int i = 0; count < max_values && i < table->Capacity(); i++) { Handle<Object> key(table->KeyAt(i), isolate); - if (table->IsKey(*key)) { - values->set(number_of_non_hole_elements++, *key); - } + if (table->IsKey(*key)) values->set(count++, *key); } - DCHECK_EQ(table->NumberOfElements(), number_of_non_hole_elements); + DCHECK_EQ(max_values, count); } return *isolate->factory()->NewJSArrayWithElements(values); } diff --git a/deps/v8/src/runtime/runtime-compiler.cc b/deps/v8/src/runtime/runtime-compiler.cc index 2e806facb2..ebd0c13f0f 100644 --- a/deps/v8/src/runtime/runtime-compiler.cc +++ b/deps/v8/src/runtime/runtime-compiler.cc @@ -47,10 +47,10 @@ RUNTIME_FUNCTION(Runtime_CompileOptimized) { DCHECK(args.length() == 2); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1); + DCHECK(isolate->use_crankshaft()); Handle<Code> unoptimized(function->shared()->code()); - if (!isolate->use_crankshaft() || - function->shared()->optimization_disabled() || + if (function->shared()->optimization_disabled() || isolate->DebuggerHasBreakPoints()) { // If the function is not optimizable or debugger is active continue // using the code from the full compiler. @@ -176,7 +176,7 @@ static bool IsSuitableForOnStackReplacement(Isolate* isolate, Handle<JSFunction> function, Handle<Code> current_code) { // Keep track of whether we've succeeded in optimizing. - if (!isolate->use_crankshaft() || !current_code->optimizable()) return false; + if (!current_code->optimizable()) return false; // If we are trying to do OSR when there are already optimized // activations of the function, it means (a) the function is directly or // indirectly recursive and (b) an optimized invocation has been @@ -347,9 +347,10 @@ bool CodeGenerationFromStringsAllowed(Isolate* isolate, RUNTIME_FUNCTION(Runtime_CompileString) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK(args.length() == 3); CONVERT_ARG_HANDLE_CHECKED(String, source, 0); CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1); + CONVERT_SMI_ARG_CHECKED(source_offset, 2); // Extract native context. Handle<Context> context(isolate->native_context()); @@ -375,6 +376,14 @@ RUNTIME_FUNCTION(Runtime_CompileString) { isolate, fun, Compiler::GetFunctionFromEval(source, outer_info, context, SLOPPY, restriction, RelocInfo::kNoPosition)); + if (function_literal_only) { + // The actual body is wrapped, which shifts line numbers. + Handle<Script> script(Script::cast(fun->shared()->script()), isolate); + if (script->line_offset() == 0) { + int line_num = Script::GetLineNumber(script, source_offset); + script->set_line_offset(Smi::FromInt(-line_num)); + } + } return *fun; } diff --git a/deps/v8/src/runtime/runtime-debug.cc b/deps/v8/src/runtime/runtime-debug.cc index 95ac77bb13..12c5a0d84f 100644 --- a/deps/v8/src/runtime/runtime-debug.cc +++ b/deps/v8/src/runtime/runtime-debug.cc @@ -136,8 +136,7 @@ RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) { isolate, element_or_char, Runtime::GetElementOrCharAt(isolate, obj, index)); details->set(0, *element_or_char); - details->set(1, - PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); + details->set(1, PropertyDetails(NONE, FIELD, 0).AsSmi()); return *isolate->factory()->NewJSArrayWithElements(details); } @@ -159,7 +158,7 @@ RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) { details->set(0, *value); // TODO(verwaest): Get rid of this random way of handling interceptors. PropertyDetails d = it.state() == LookupIterator::INTERCEPTOR - ? PropertyDetails(NONE, NORMAL, 0) + ? PropertyDetails(NONE, FIELD, 0) : it.property_details(); details->set(1, d.AsSmi()); details->set( @@ -214,7 +213,7 @@ RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) { SealHandleScope shs(isolate); DCHECK(args.length() == 1); CONVERT_PROPERTY_DETAILS_CHECKED(details, 0); - // TODO(verwaest): Depends on the type of details. + // TODO(verwaest): Works only for dictionary mode holders. return Smi::FromInt(details.dictionary_index()); } @@ -801,6 +800,29 @@ MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext( } +MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScriptScope( + Handle<GlobalObject> global) { + Isolate* isolate = global->GetIsolate(); + Handle<ScriptContextTable> script_contexts( + global->native_context()->script_context_table()); + + Handle<JSObject> script_scope = + isolate->factory()->NewJSObject(isolate->object_function()); + + for (int context_index = 0; context_index < script_contexts->used(); + context_index++) { + Handle<Context> context = + ScriptContextTable::GetContext(script_contexts, context_index); + Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension())); + if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context, + script_scope)) { + return MaybeHandle<JSObject>(); + } + } + return script_scope; +} + + MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope( Isolate* isolate, JavaScriptFrame* frame, int inlined_jsframe_index) { FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); @@ -986,6 +1008,35 @@ static bool SetClosureVariableValue(Isolate* isolate, Handle<Context> context, } +static bool SetBlockContextVariableValue(Handle<Context> block_context, + Handle<String> variable_name, + Handle<Object> new_value) { + DCHECK(block_context->IsBlockContext()); + Handle<ScopeInfo> scope_info(ScopeInfo::cast(block_context->extension())); + + return SetContextLocalValue(block_context->GetIsolate(), scope_info, + block_context, variable_name, new_value); +} + + +static bool SetScriptVariableValue(Handle<Context> context, + Handle<String> variable_name, + Handle<Object> new_value) { + Handle<ScriptContextTable> script_contexts( + context->global_object()->native_context()->script_context_table()); + ScriptContextTable::LookupResult lookup_result; + if (ScriptContextTable::Lookup(script_contexts, variable_name, + &lookup_result)) { + Handle<Context> script_context = ScriptContextTable::GetContext( + script_contexts, lookup_result.context_index); + script_context->set(lookup_result.slot_index, *new_value); + return true; + } + + return false; +} + + // Create a plain JSObject which materializes the scope for the specified // catch context. MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope( @@ -1073,6 +1124,7 @@ class ScopeIterator { ScopeTypeClosure, ScopeTypeCatch, ScopeTypeBlock, + ScopeTypeScript, ScopeTypeModule }; @@ -1084,6 +1136,7 @@ class ScopeIterator { function_(frame->function()), context_(Context::cast(frame->context())), nested_scope_chain_(4), + seen_script_scope_(false), failed_(false) { // Catch the case when the debugger stops in an internal function. Handle<SharedFunctionInfo> shared_info(function_->shared()); @@ -1147,7 +1200,7 @@ class ScopeIterator { scope_info->scope_type() != ARROW_SCOPE) { // Global or eval code. CompilationInfoWithZone info(script); - if (scope_info->scope_type() == GLOBAL_SCOPE) { + if (scope_info->scope_type() == SCRIPT_SCOPE) { info.MarkAsGlobal(); } else { DCHECK(scope_info->scope_type() == EVAL_SCOPE); @@ -1175,6 +1228,7 @@ class ScopeIterator { inlined_jsframe_index_(0), function_(function), context_(function->context()), + seen_script_scope_(false), failed_(false) { if (function->IsBuiltin()) { context_ = Handle<Context>(); @@ -1199,8 +1253,16 @@ class ScopeIterator { context_ = Handle<Context>(); return; } + if (scope_type == ScopeTypeScript) seen_script_scope_ = true; if (nested_scope_chain_.is_empty()) { - context_ = Handle<Context>(context_->previous(), isolate_); + if (scope_type == ScopeTypeScript) { + if (context_->IsScriptContext()) { + context_ = Handle<Context>(context_->previous(), isolate_); + } + CHECK(context_->IsNativeContext()); + } else { + context_ = Handle<Context>(context_->previous(), isolate_); + } } else { if (nested_scope_chain_.last()->HasContext()) { DCHECK(context_->previous() != NULL); @@ -1223,9 +1285,9 @@ class ScopeIterator { case MODULE_SCOPE: DCHECK(context_->IsModuleContext()); return ScopeTypeModule; - case GLOBAL_SCOPE: - DCHECK(context_->IsNativeContext()); - return ScopeTypeGlobal; + case SCRIPT_SCOPE: + DCHECK(context_->IsScriptContext() || context_->IsNativeContext()); + return ScopeTypeScript; case WITH_SCOPE: DCHECK(context_->IsWithContext()); return ScopeTypeWith; @@ -1241,7 +1303,9 @@ class ScopeIterator { } if (context_->IsNativeContext()) { DCHECK(context_->global_object()->IsGlobalObject()); - return ScopeTypeGlobal; + // If we are at the native context and have not yet seen script scope, + // fake it. + return seen_script_scope_ ? ScopeTypeGlobal : ScopeTypeScript; } if (context_->IsFunctionContext()) { return ScopeTypeClosure; @@ -1255,6 +1319,9 @@ class ScopeIterator { if (context_->IsModuleContext()) { return ScopeTypeModule; } + if (context_->IsScriptContext()) { + return ScopeTypeScript; + } DCHECK(context_->IsWithContext()); return ScopeTypeWith; } @@ -1265,6 +1332,9 @@ class ScopeIterator { switch (Type()) { case ScopeIterator::ScopeTypeGlobal: return Handle<JSObject>(CurrentContext()->global_object()); + case ScopeIterator::ScopeTypeScript: + return MaterializeScriptScope( + Handle<GlobalObject>(CurrentContext()->global_object())); case ScopeIterator::ScopeTypeLocal: // Materialize the content of the local scope into a JSObject. DCHECK(nested_scope_chain_.length() == 1); @@ -1303,9 +1373,12 @@ class ScopeIterator { case ScopeIterator::ScopeTypeClosure: return SetClosureVariableValue(isolate_, CurrentContext(), variable_name, new_value); + case ScopeIterator::ScopeTypeScript: + return SetScriptVariableValue(CurrentContext(), variable_name, + new_value); case ScopeIterator::ScopeTypeBlock: - // TODO(2399): should we implement it? - break; + return SetBlockContextVariableValue(CurrentContext(), variable_name, + new_value); case ScopeIterator::ScopeTypeModule: // TODO(2399): should we implement it? break; @@ -1329,7 +1402,8 @@ class ScopeIterator { // be an actual context. Handle<Context> CurrentContext() { DCHECK(!failed_); - if (Type() == ScopeTypeGlobal || nested_scope_chain_.is_empty()) { + if (Type() == ScopeTypeGlobal || Type() == ScopeTypeScript || + nested_scope_chain_.is_empty()) { return context_; } else if (nested_scope_chain_.last()->HasContext()) { return context_; @@ -1386,6 +1460,15 @@ class ScopeIterator { } break; + case ScopeIterator::ScopeTypeScript: + os << "Script:\n"; + CurrentContext() + ->global_object() + ->native_context() + ->script_context_table() + ->Print(os); + break; + default: UNREACHABLE(); } @@ -1400,6 +1483,7 @@ class ScopeIterator { Handle<JSFunction> function_; Handle<Context> context_; List<Handle<ScopeInfo> > nested_scope_chain_; + bool seen_script_scope_; bool failed_; void RetrieveScopeChain(Scope* scope, @@ -2083,8 +2167,9 @@ static MaybeHandle<Object> DebugEvaluate(Isolate* isolate, static Handle<JSObject> NewJSObjectWithNullProto(Isolate* isolate) { Handle<JSObject> result = isolate->factory()->NewJSObject(isolate->object_function()); - Handle<Map> new_map = Map::Copy(Handle<Map>(result->map())); - new_map->set_prototype(*isolate->factory()->null_value()); + Handle<Map> new_map = + Map::Copy(Handle<Map>(result->map()), "ObjectWithNullProto"); + new_map->SetPrototype(isolate->factory()->null_value()); JSObject::MigrateToMap(result, new_map); return result; } @@ -2163,6 +2248,7 @@ RUNTIME_FUNCTION(Runtime_DebugEvaluate) { // We iterate to find the function's context. If the function has no // context-allocated variables, we iterate until we hit the outer context. while (!function_context->IsFunctionContext() && + !function_context->IsScriptContext() && !function_context.is_identical_to(outer_context)) { inner_context = function_context; function_context = Handle<Context>(function_context->previous(), isolate); @@ -2645,7 +2731,9 @@ RUNTIME_FUNCTION(Runtime_GetScript) { // to a built-in function such as Array.forEach. RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) { DCHECK(args.length() == 1); - if (!isolate->debug()->is_active() || !isolate->debug()->StepInActive()) { + Debug* debug = isolate->debug(); + if (!debug->is_active() || !debug->IsStepping() || + debug->last_step_action() != StepIn) { return isolate->heap()->false_value(); } CONVERT_ARG_CHECKED(Object, callback, 0); diff --git a/deps/v8/src/runtime/runtime-generator.cc b/deps/v8/src/runtime/runtime-generator.cc index 9c2add7413..ff07acd304 100644 --- a/deps/v8/src/runtime/runtime-generator.cc +++ b/deps/v8/src/runtime/runtime-generator.cc @@ -135,16 +135,14 @@ RUNTIME_FUNCTION(Runtime_ResumeJSGeneratorObject) { } -RUNTIME_FUNCTION(Runtime_ThrowGeneratorStateError) { +RUNTIME_FUNCTION(Runtime_GeneratorClose) { HandleScope scope(isolate); DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); - int continuation = generator->continuation(); - const char* message = continuation == JSGeneratorObject::kGeneratorClosed - ? "generator_finished" - : "generator_running"; - Vector<Handle<Object> > argv = HandleVector<Object>(NULL, 0); - THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewError(message, argv)); + + generator->set_continuation(JSGeneratorObject::kGeneratorClosed); + + return isolate->heap()->undefined_value(); } diff --git a/deps/v8/src/runtime/runtime-literals.cc b/deps/v8/src/runtime/runtime-literals.cc index 23b5b199ae..8bbe0eeddb 100644 --- a/deps/v8/src/runtime/runtime-literals.cc +++ b/deps/v8/src/runtime/runtime-literals.cc @@ -17,53 +17,22 @@ namespace internal { static Handle<Map> ComputeObjectLiteralMap( Handle<Context> context, Handle<FixedArray> constant_properties, bool* is_result_from_cache) { - Isolate* isolate = context->GetIsolate(); int properties_length = constant_properties->length(); int number_of_properties = properties_length / 2; - // Check that there are only internal strings and array indices among keys. - int number_of_string_keys = 0; + for (int p = 0; p != properties_length; p += 2) { Object* key = constant_properties->get(p); uint32_t element_index = 0; - if (key->IsInternalizedString()) { - number_of_string_keys++; - } else if (key->ToArrayIndex(&element_index)) { + if (key->ToArrayIndex(&element_index)) { // An index key does not require space in the property backing store. number_of_properties--; - } else { - // Bail out as a non-internalized-string non-index key makes caching - // impossible. - // DCHECK to make sure that the if condition after the loop is false. - DCHECK(number_of_string_keys != number_of_properties); - break; - } - } - // If we only have internalized strings and array indices among keys then we - // can use the map cache in the native context. - const int kMaxKeys = 10; - if ((number_of_string_keys == number_of_properties) && - (number_of_string_keys < kMaxKeys)) { - // Create the fixed array with the key. - Handle<FixedArray> keys = - isolate->factory()->NewFixedArray(number_of_string_keys); - if (number_of_string_keys > 0) { - int index = 0; - for (int p = 0; p < properties_length; p += 2) { - Object* key = constant_properties->get(p); - if (key->IsInternalizedString()) { - keys->set(index++, key); - } - } - DCHECK(index == number_of_string_keys); } - *is_result_from_cache = true; - return isolate->factory()->ObjectLiteralMapFromCache(context, keys); } - *is_result_from_cache = false; - return Map::Create(isolate, number_of_properties); + Isolate* isolate = context->GetIsolate(); + return isolate->factory()->ObjectLiteralMapFromCache( + context, number_of_properties, is_result_from_cache); } - MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( Isolate* isolate, Handle<FixedArray> literals, Handle<FixedArray> constant_properties); @@ -109,7 +78,7 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( if (should_normalize) { // TODO(verwaest): We might not want to ever normalize here. JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, - length / 2); + length / 2, "Boilerplate"); } // TODO(verwaest): Support tracking representations in the boilerplate. for (int index = 0; index < length; index += 2) { @@ -166,9 +135,9 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( // constant function properties. if (should_transform && !has_function_literal) { JSObject::MigrateSlowToFast(boilerplate, - boilerplate->map()->unused_property_fields()); + boilerplate->map()->unused_property_fields(), + "FastLiteral"); } - return boilerplate; } diff --git a/deps/v8/src/runtime/runtime-object.cc b/deps/v8/src/runtime/runtime-object.cc index 74cb8cb293..407f237794 100644 --- a/deps/v8/src/runtime/runtime-object.cc +++ b/deps/v8/src/runtime/runtime-object.cc @@ -242,10 +242,8 @@ MaybeHandle<Object> Runtime::DefineObjectProperty(Handle<JSObject> js_object, } -RUNTIME_FUNCTION(Runtime_GetPrototype) { - HandleScope scope(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); +MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate, + Handle<Object> obj) { // 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); @@ -257,15 +255,26 @@ RUNTIME_FUNCTION(Runtime_GetPrototype) { isolate->ReportFailedAccessCheck( Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), v8::ACCESS_GET); - RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); - return isolate->heap()->undefined_value(); + RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); + return isolate->factory()->undefined_value(); } iter.AdvanceIgnoringProxies(); if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) { - return *PrototypeIterator::GetCurrent(iter); + return PrototypeIterator::GetCurrent(iter); } } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)); - return *PrototypeIterator::GetCurrent(iter); + return PrototypeIterator::GetCurrent(iter); +} + + +RUNTIME_FUNCTION(Runtime_GetPrototype) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0); + Handle<Object> result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, + Runtime::GetPrototype(isolate, obj)); + return *result; } @@ -469,7 +478,7 @@ RUNTIME_FUNCTION(Runtime_DisableAccessChecks) { bool needs_access_checks = old_map->is_access_check_needed(); if (needs_access_checks) { // Copy map so it won't interfere constructor's initial map. - Handle<Map> new_map = Map::Copy(old_map); + Handle<Map> new_map = Map::Copy(old_map, "DisableAccessChecks"); new_map->set_is_access_check_needed(false); JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map); } @@ -484,7 +493,7 @@ RUNTIME_FUNCTION(Runtime_EnableAccessChecks) { Handle<Map> old_map(object->map()); RUNTIME_ASSERT(!old_map->is_access_check_needed()); // Copy map so it won't interfere constructor's initial map. - Handle<Map> new_map = Map::Copy(old_map); + Handle<Map> new_map = Map::Copy(old_map, "EnableAccessChecks"); new_map->set_is_access_check_needed(true); JSObject::MigrateToMap(object, new_map); return isolate->heap()->undefined_value(); @@ -499,7 +508,8 @@ RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) { // Conservative upper limit to prevent fuzz tests from going OOM. RUNTIME_ASSERT(properties <= 100000); if (object->HasFastProperties() && !object->IsJSGlobalProxy()) { - JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); + JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties, + "OptimizeForAdding"); } return *object; } @@ -520,6 +530,21 @@ RUNTIME_FUNCTION(Runtime_ObjectFreeze) { } +RUNTIME_FUNCTION(Runtime_ObjectSeal) { + HandleScope scope(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); + + // %ObjectSeal is a fast path and these cases are handled elsewhere. + RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() && + !object->map()->is_observed() && !object->IsJSProxy()); + + Handle<Object> result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Seal(object)); + return *result; +} + + RUNTIME_FUNCTION(Runtime_GetProperty) { HandleScope scope(isolate); DCHECK(args.length() == 2); @@ -607,7 +632,7 @@ RUNTIME_FUNCTION(Runtime_KeyedGetProperty) { NameDictionary* dictionary = receiver->property_dictionary(); int entry = dictionary->FindEntry(key); if ((entry != NameDictionary::kNotFound) && - (dictionary->DetailsAt(entry).type() == NORMAL)) { + (dictionary->DetailsAt(entry).type() == FIELD)) { Object* value = dictionary->ValueAt(entry); if (!receiver->IsGlobalObject()) return value; value = PropertyCell::cast(value)->value(); @@ -790,7 +815,12 @@ RUNTIME_FUNCTION(Runtime_HasOwnProperty) { // Fast case: either the key is a real named property or it is not // an array index and there are no interceptors or hidden // prototypes. - Maybe<bool> maybe = JSObject::HasRealNamedProperty(js_obj, key); + Maybe<bool> maybe; + if (key_is_array_index) { + maybe = JSObject::HasOwnElement(js_obj, index); + } else { + maybe = JSObject::HasRealNamedProperty(js_obj, key); + } if (!maybe.has_value) return isolate->heap()->exception(); DCHECK(!isolate->has_pending_exception()); if (maybe.value) { @@ -980,31 +1010,27 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { Handle<JSObject> jsproto = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); jsproto->GetOwnPropertyNames(*names, next_copy_index, filter); - if (i > 0) { - // Names from hidden prototypes may already have been added - // for inherited function template instances. Count the duplicates - // and stub them out; the final copy pass at the end ignores holes. - for (int j = next_copy_index; - j < next_copy_index + own_property_count[i]; j++) { - Object* name_from_hidden_proto = names->get(j); + // Names from hidden prototypes may already have been added + // for inherited function template instances. Count the duplicates + // and stub them out; the final copy pass at the end ignores holes. + for (int j = next_copy_index; j < next_copy_index + own_property_count[i]; + j++) { + Object* name_from_hidden_proto = names->get(j); + if (isolate->IsInternallyUsedPropertyName(name_from_hidden_proto)) { + hidden_strings++; + } else { for (int k = 0; k < next_copy_index; k++) { - if (names->get(k) != isolate->heap()->hidden_string()) { - Object* name = names->get(k); - if (name_from_hidden_proto == name) { - names->set(j, isolate->heap()->hidden_string()); - hidden_strings++; - break; - } + Object* name = names->get(k); + if (name_from_hidden_proto == name) { + names->set(j, isolate->heap()->hidden_string()); + hidden_strings++; + break; } } } } next_copy_index += own_property_count[i]; - // Hidden properties only show up if the filter does not skip strings. - if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) { - hidden_strings++; - } iter.Advance(); } } @@ -1017,7 +1043,7 @@ RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) { int dest_pos = 0; for (int i = 0; i < total_property_count; i++) { Object* name = old_names->get(i); - if (name == isolate->heap()->hidden_string()) { + if (isolate->IsInternallyUsedPropertyName(name)) { hidden_strings--; continue; } @@ -1152,7 +1178,8 @@ RUNTIME_FUNCTION(Runtime_ToFastProperties) { DCHECK(args.length() == 1); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); if (object->IsJSObject() && !object->IsGlobalObject()) { - JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0); + JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0, + "RuntimeToFastProperties"); } return *object; } @@ -1357,16 +1384,6 @@ RUNTIME_FUNCTION(Runtime_GlobalProxy) { } -RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) { - SealHandleScope shs(isolate); - DCHECK(args.length() == 1); - CONVERT_ARG_CHECKED(Object, global, 0); - if (!global->IsJSGlobalObject()) return isolate->heap()->false_value(); - return isolate->heap()->ToBoolean( - !JSGlobalObject::cast(global)->IsDetached()); -} - - RUNTIME_FUNCTION(Runtime_LookupAccessor) { HandleScope scope(isolate); DCHECK(args.length() == 3); @@ -1398,9 +1415,8 @@ RUNTIME_FUNCTION(Runtime_LoadMutableDouble) { RUNTIME_ASSERT(field_index.outobject_array_index() < object->properties()->length()); } - Handle<Object> raw_value(object->RawFastPropertyAt(field_index), isolate); - RUNTIME_ASSERT(raw_value->IsMutableHeapNumber()); - return *Object::WrapForRead(isolate, raw_value, Representation::Double()); + return *JSObject::FastPropertyAt(object, Representation::Double(), + field_index); } @@ -1453,10 +1469,8 @@ RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) { RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); - bool fast = obj->HasFastProperties(); RETURN_FAILURE_ON_EXCEPTION( isolate, JSObject::DefineAccessor(obj, name, getter, setter, attr)); - if (fast) JSObject::MigrateSlowToFast(obj, 0); return isolate->heap()->undefined_value(); } @@ -1516,6 +1530,15 @@ RUNTIME_FUNCTION(Runtime_GetDataProperty) { } +RUNTIME_FUNCTION(Runtime_HasFastPackedElements) { + SealHandleScope shs(isolate); + DCHECK(args.length() == 1); + CONVERT_ARG_CHECKED(HeapObject, obj, 0); + return isolate->heap()->ToBoolean( + IsFastPackedElementsKind(obj->map()->elements_kind())); +} + + RUNTIME_FUNCTION(RuntimeReference_ValueOf) { SealHandleScope shs(isolate); DCHECK(args.length() == 1); diff --git a/deps/v8/src/runtime/runtime-observe.cc b/deps/v8/src/runtime/runtime-observe.cc index 4579136d9a..211922c5b7 100644 --- a/deps/v8/src/runtime/runtime-observe.cc +++ b/deps/v8/src/runtime/runtime-observe.cc @@ -5,6 +5,7 @@ #include "src/v8.h" #include "src/arguments.h" +#include "src/debug.h" #include "src/runtime/runtime-utils.h" namespace v8 { @@ -63,6 +64,18 @@ RUNTIME_FUNCTION(Runtime_DeliverObservationChangeRecords) { // we make a call inside a verbose TryCatch. catcher.SetVerbose(true); Handle<Object> argv[] = {argument}; + + // Allow stepping into the observer callback. + Debug* debug = isolate->debug(); + if (debug->is_active() && debug->IsStepping() && + debug->last_step_action() == StepIn) { + // Previous StepIn may have activated a StepOut if it was at the frame exit. + // In this case to be able to step into the callback again, we need to clear + // the step out first. + debug->ClearStepOut(); + debug->FloodWithOneShot(callback); + } + USE(Execution::Call(isolate, callback, isolate->factory()->undefined_value(), arraysize(argv), argv)); if (isolate->has_pending_exception()) { diff --git a/deps/v8/src/runtime/runtime-regexp.cc b/deps/v8/src/runtime/runtime-regexp.cc index b613f8a0e6..be9adfff41 100644 --- a/deps/v8/src/runtime/runtime-regexp.cc +++ b/deps/v8/src/runtime/runtime-regexp.cc @@ -8,7 +8,7 @@ #include "src/jsregexp-inl.h" #include "src/jsregexp.h" #include "src/runtime/runtime-utils.h" -#include "src/runtime/string-builder.h" +#include "src/string-builder.h" #include "src/string-search.h" namespace v8 { @@ -759,19 +759,6 @@ RUNTIME_FUNCTION(Runtime_StringSplit) { } -RUNTIME_FUNCTION(Runtime_RegExpCompile) { - HandleScope scope(isolate); - DCHECK(args.length() == 3); - CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0); - CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1); - CONVERT_ARG_HANDLE_CHECKED(String, flags, 2); - Handle<Object> result; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, - RegExpImpl::Compile(re, pattern, flags)); - return *result; -} - - RUNTIME_FUNCTION(Runtime_RegExpExecRT) { HandleScope scope(isolate); DCHECK(args.length() == 4); @@ -813,72 +800,110 @@ RUNTIME_FUNCTION(Runtime_RegExpConstructResult) { } -RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) { +static JSRegExp::Flags RegExpFlagsFromString(Handle<String> flags, + bool* success) { + uint32_t value = JSRegExp::NONE; + int length = flags->length(); + // A longer flags string cannot be valid. + if (length > 4) return JSRegExp::Flags(0); + for (int i = 0; i < length; i++) { + uint32_t flag = JSRegExp::NONE; + switch (flags->Get(i)) { + case 'g': + flag = JSRegExp::GLOBAL; + break; + case 'i': + flag = JSRegExp::IGNORE_CASE; + break; + case 'm': + flag = JSRegExp::MULTILINE; + break; + case 'y': + if (!FLAG_harmony_regexps) return JSRegExp::Flags(0); + flag = JSRegExp::STICKY; + break; + default: + return JSRegExp::Flags(0); + } + // Duplicate flag. + if (value & flag) return JSRegExp::Flags(0); + value |= flag; + } + *success = true; + return JSRegExp::Flags(value); +} + + +RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) { HandleScope scope(isolate); - DCHECK(args.length() == 6); + DCHECK(args.length() == 3); CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); CONVERT_ARG_HANDLE_CHECKED(String, source, 1); + CONVERT_ARG_HANDLE_CHECKED(String, flags_string, 2); + Factory* factory = isolate->factory(); // If source is the empty string we set it to "(?:)" instead as // suggested by ECMA-262, 5th, section 15.10.4.1. - if (source->length() == 0) source = isolate->factory()->query_colon_string(); - - CONVERT_ARG_HANDLE_CHECKED(Object, global, 2); - if (!global->IsTrue()) global = isolate->factory()->false_value(); - - CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3); - if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value(); - - CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4); - if (!multiline->IsTrue()) multiline = isolate->factory()->false_value(); + if (source->length() == 0) source = factory->query_colon_string(); + + bool success = false; + JSRegExp::Flags flags = RegExpFlagsFromString(flags_string, &success); + if (!success) { + Handle<FixedArray> element = factory->NewFixedArray(1); + element->set(0, *flags_string); + Handle<JSArray> args = factory->NewJSArrayWithElements(element); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewSyntaxError("invalid_regexp_flags", args)); + } - CONVERT_ARG_HANDLE_CHECKED(Object, sticky, 5); - if (!sticky->IsTrue()) sticky = isolate->factory()->false_value(); + 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()); Map* map = regexp->map(); Object* constructor = map->constructor(); if (!FLAG_harmony_regexps && constructor->IsJSFunction() && JSFunction::cast(constructor)->initial_map() == map) { // If we still have the original map, set in-object properties directly. - regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *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, *ignoreCase, + 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); - return *regexp; + } 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); + PropertyAttributes writable = + static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); + Handle<Object> zero(Smi::FromInt(0), isolate); + 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(); + } + JSObject::SetOwnPropertyIgnoreAttributes( + regexp, factory->last_index_string(), zero, writable).Check(); } - // 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); - PropertyAttributes writable = - static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); - Handle<Object> zero(Smi::FromInt(0), isolate); - Factory* factory = isolate->factory(); - JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->source_string(), - source, final).Check(); - JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->global_string(), - global, final).Check(); - JSObject::SetOwnPropertyIgnoreAttributes( - regexp, factory->ignore_case_string(), ignoreCase, final).Check(); - JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->multiline_string(), - multiline, final).Check(); - if (FLAG_harmony_regexps) { - JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->sticky_string(), - sticky, final).Check(); - } - JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->last_index_string(), - zero, writable).Check(); - return *regexp; + Handle<Object> result; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, RegExpImpl::Compile(regexp, source, flags)); + return *result; } diff --git a/deps/v8/src/runtime/runtime-scopes.cc b/deps/v8/src/runtime/runtime-scopes.cc index c935cdabef..2a0b435872 100644 --- a/deps/v8/src/runtime/runtime-scopes.cc +++ b/deps/v8/src/runtime/runtime-scopes.cc @@ -22,11 +22,27 @@ static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) { } +RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) { + HandleScope scope(isolate); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError("harmony_const_assign", HandleVector<Object>(NULL, 0))); +} + + // May throw a RedeclarationError. static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global, Handle<String> name, Handle<Object> value, PropertyAttributes attr, bool is_var, bool is_const, bool is_function) { + Handle<ScriptContextTable> script_contexts( + global->native_context()->script_context_table()); + ScriptContextTable::LookupResult lookup; + if (ScriptContextTable::Lookup(script_contexts, name, &lookup) && + IsLexicalVariableMode(lookup.mode)) { + return ThrowRedeclarationError(isolate, name); + } + // Do the lookup own properties only, see ES5 erratum. LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); @@ -189,7 +205,7 @@ RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) { HandleScope scope(isolate); DCHECK(args.length() == 4); - // Declarations are always made in a function, native, or global context. In + // Declarations are always made in a function, eval or script context. In // the case of eval code, the context passed is the context of the caller, // which may be some nested context and not the declaration context. CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0); @@ -298,9 +314,11 @@ RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) { // The declared const was configurable, and may have been deleted in the // meanwhile. If so, re-introduce the variable in the context extension. - DCHECK(context_arg->has_extension()); if (attributes == ABSENT) { - holder = handle(context_arg->extension(), isolate); + Handle<Context> declaration_context(context_arg->declaration_context()); + DCHECK(declaration_context->has_extension()); + holder = handle(declaration_context->extension(), isolate); + CHECK(holder->IsJSObject()); } else { // For JSContextExtensionObjects, the initializer can be run multiple times // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the @@ -347,7 +365,7 @@ static Handle<JSObject> NewSloppyArguments(Isolate* isolate, isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED); parameter_map->set_map(isolate->heap()->sloppy_arguments_elements_map()); - Handle<Map> map = Map::Copy(handle(result->map())); + Handle<Map> map = Map::Copy(handle(result->map()), "NewSloppyArguments"); map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS); result->set_map(*map); @@ -507,19 +525,61 @@ RUNTIME_FUNCTION(Runtime_NewClosure) { pretenure_flag); } +static Object* FindNameClash(Handle<ScopeInfo> scope_info, + Handle<GlobalObject> global_object, + Handle<ScriptContextTable> script_context) { + Isolate* isolate = scope_info->GetIsolate(); + for (int var = 0; var < scope_info->ContextLocalCount(); var++) { + Handle<String> name(scope_info->ContextLocalName(var)); + VariableMode mode = scope_info->ContextLocalMode(var); + ScriptContextTable::LookupResult lookup; + if (ScriptContextTable::Lookup(script_context, name, &lookup)) { + if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) { + return ThrowRedeclarationError(isolate, name); + } + } + + if (IsLexicalVariableMode(mode)) { + LookupIterator it(global_object, name, + LookupIterator::HIDDEN_SKIP_INTERCEPTOR); + Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); + if (!maybe.has_value) return isolate->heap()->exception(); + if ((maybe.value & DONT_DELETE) != 0) { + return ThrowRedeclarationError(isolate, name); + } + + GlobalObject::InvalidatePropertyCell(global_object, name); + } + } + return isolate->heap()->undefined_value(); +} + -RUNTIME_FUNCTION(Runtime_NewGlobalContext) { +RUNTIME_FUNCTION(Runtime_NewScriptContext) { HandleScope scope(isolate); DCHECK(args.length() == 2); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1); + Handle<GlobalObject> global_object(function->context()->global_object()); + Handle<Context> native_context(global_object->native_context()); + Handle<ScriptContextTable> script_context_table( + native_context->script_context_table()); + + Handle<String> clashed_name; + Object* name_clash_result = + FindNameClash(scope_info, global_object, script_context_table); + if (isolate->has_pending_exception()) return name_clash_result; + Handle<Context> result = - isolate->factory()->NewGlobalContext(function, scope_info); + isolate->factory()->NewScriptContext(function, scope_info); DCHECK(function->context() == isolate->context()); DCHECK(function->context()->global_object() == result->global_object()); - result->global_object()->set_global_context(*result); + + Handle<ScriptContextTable> new_script_context_table = + ScriptContextTable::Extend(script_context_table, result); + native_context->set_script_context_table(*new_script_context_table); return *result; } @@ -629,7 +689,7 @@ RUNTIME_FUNCTION(Runtime_PushModuleContext) { if (!args[1]->IsScopeInfo()) { // Module already initialized. Find hosting context and retrieve context. - Context* host = Context::cast(isolate->context())->global_context(); + Context* host = Context::cast(isolate->context())->script_context(); Context* context = Context::cast(host->get(index)); DCHECK(context->previous() == isolate->context()); isolate->set_context(context); @@ -651,7 +711,7 @@ RUNTIME_FUNCTION(Runtime_PushModuleContext) { isolate->set_context(*context); // Find hosting scope and initialize internal variable holding module there. - previous->global_context()->set(index, *context); + previous->script_context()->set(index, *context); return *context; } @@ -956,7 +1016,7 @@ RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) { HandleScope scope(isolate); if (raw_key->IsSymbol()) { Handle<Symbol> symbol = Handle<Symbol>::cast(raw_key); - if (symbol->Equals(isolate->native_context()->iterator_symbol())) { + if (Name::Equals(symbol, isolate->factory()->iterator_symbol())) { return isolate->native_context()->array_values_iterator(); } // Lookup in the initial Object.prototype object. diff --git a/deps/v8/src/runtime/runtime-strings.cc b/deps/v8/src/runtime/runtime-strings.cc index 9c74f4b501..df2210c635 100644 --- a/deps/v8/src/runtime/runtime-strings.cc +++ b/deps/v8/src/runtime/runtime-strings.cc @@ -8,7 +8,7 @@ #include "src/jsregexp-inl.h" #include "src/jsregexp.h" #include "src/runtime/runtime-utils.h" -#include "src/runtime/string-builder.h" +#include "src/string-builder.h" #include "src/string-search.h" namespace v8 { diff --git a/deps/v8/src/runtime/runtime-test.cc b/deps/v8/src/runtime/runtime-test.cc index 49959844bf..b4b90e2c58 100644 --- a/deps/v8/src/runtime/runtime-test.cc +++ b/deps/v8/src/runtime/runtime-test.cc @@ -60,9 +60,16 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) { (function->code()->kind() == Code::FUNCTION && function->code()->optimizable())); - // If the function is optimized, just return. + if (!isolate->use_crankshaft()) return isolate->heap()->undefined_value(); + + // If the function is already optimized, just return. if (function->IsOptimized()) return isolate->heap()->undefined_value(); + // If the function cannot optimized, just return. + if (function->shared()->optimization_disabled()) { + return isolate->heap()->undefined_value(); + } + function->MarkForOptimization(); Code* unoptimized = function->shared()->code(); @@ -75,7 +82,7 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) { *function, Code::kMaxLoopNestingMarker); } else if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) && isolate->concurrent_recompilation_enabled()) { - function->MarkForConcurrentOptimization(); + function->AttemptConcurrentOptimization(); } } @@ -87,6 +94,7 @@ RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) { HandleScope scope(isolate); DCHECK(args.length() == 1); CONVERT_ARG_CHECKED(JSFunction, function, 0); + function->shared()->set_disable_optimization_reason(kOptimizationDisabled); function->shared()->set_optimization_disabled(true); return isolate->heap()->undefined_value(); } @@ -163,7 +171,7 @@ RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) { RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) { HandleScope scope(isolate); DCHECK(args.length() == 0); - isolate->heap()->NotifyContextDisposed(); + isolate->heap()->NotifyContextDisposed(true); return isolate->heap()->undefined_value(); } diff --git a/deps/v8/src/runtime/runtime-uri.cc b/deps/v8/src/runtime/runtime-uri.cc index 16e80b5796..477071ac78 100644 --- a/deps/v8/src/runtime/runtime-uri.cc +++ b/deps/v8/src/runtime/runtime-uri.cc @@ -14,26 +14,6 @@ namespace v8 { namespace internal { -template <typename Char> -static INLINE(Vector<const Char> GetCharVector(Handle<String> string)); - - -template <> -Vector<const uint8_t> GetCharVector(Handle<String> string) { - String::FlatContent flat = string->GetFlatContent(); - DCHECK(flat.IsOneByte()); - return flat.ToOneByteVector(); -} - - -template <> -Vector<const uc16> GetCharVector(Handle<String> string) { - String::FlatContent flat = string->GetFlatContent(); - DCHECK(flat.IsTwoByte()); - return flat.ToUC16Vector(); -} - - class URIUnescape : public AllStatic { public: template <typename Char> @@ -72,7 +52,7 @@ MaybeHandle<String> URIUnescape::Unescape(Isolate* isolate, { DisallowHeapAllocation no_allocation; StringSearch<uint8_t, Char> search(isolate, STATIC_CHAR_VECTOR("%")); - index = search.Search(GetCharVector<Char>(source), 0); + index = search.Search(source->GetCharVector<Char>(), 0); if (index < 0) return source; } return UnescapeSlow<Char>(isolate, source, index); @@ -89,7 +69,7 @@ MaybeHandle<String> URIUnescape::UnescapeSlow(Isolate* isolate, int unescaped_length = 0; { DisallowHeapAllocation no_allocation; - Vector<const Char> vector = GetCharVector<Char>(string); + Vector<const Char> vector = string->GetCharVector<Char>(); for (int i = start_index; i < length; unescaped_length++) { int step; if (UnescapeChar(vector, i, length, &step) > @@ -112,7 +92,7 @@ MaybeHandle<String> URIUnescape::UnescapeSlow(Isolate* isolate, ->NewRawOneByteString(unescaped_length) .ToHandleChecked(); DisallowHeapAllocation no_allocation; - Vector<const Char> vector = GetCharVector<Char>(string); + Vector<const Char> vector = string->GetCharVector<Char>(); for (int i = start_index; i < length; dest_position++) { int step; dest->SeqOneByteStringSet(dest_position, @@ -125,7 +105,7 @@ MaybeHandle<String> URIUnescape::UnescapeSlow(Isolate* isolate, ->NewRawTwoByteString(unescaped_length) .ToHandleChecked(); DisallowHeapAllocation no_allocation; - Vector<const Char> vector = GetCharVector<Char>(string); + Vector<const Char> vector = string->GetCharVector<Char>(); for (int i = start_index; i < length; dest_position++) { int step; dest->SeqTwoByteStringSet(dest_position, @@ -221,7 +201,7 @@ MaybeHandle<String> URIEscape::Escape(Isolate* isolate, Handle<String> string) { { DisallowHeapAllocation no_allocation; - Vector<const Char> vector = GetCharVector<Char>(string); + Vector<const Char> vector = string->GetCharVector<Char>(); for (int i = 0; i < length; i++) { uint16_t c = vector[i]; if (c >= 256) { @@ -249,7 +229,7 @@ MaybeHandle<String> URIEscape::Escape(Isolate* isolate, Handle<String> string) { { DisallowHeapAllocation no_allocation; - Vector<const Char> vector = GetCharVector<Char>(string); + Vector<const Char> vector = string->GetCharVector<Char>(); for (int i = 0; i < length; i++) { uint16_t c = vector[i]; if (c >= 256) { diff --git a/deps/v8/src/runtime/runtime.cc b/deps/v8/src/runtime/runtime.cc index cd6f36c233..459ca50447 100644 --- a/deps/v8/src/runtime/runtime.cc +++ b/deps/v8/src/runtime/runtime.cc @@ -80,8 +80,7 @@ void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate, if (name == NULL) continue; Handle<NameDictionary> new_dict = NameDictionary::Add( dict, isolate->factory()->InternalizeUtf8String(name), - Handle<Smi>(Smi::FromInt(i), isolate), - PropertyDetails(NONE, NORMAL, Representation::None())); + Handle<Smi>(Smi::FromInt(i), isolate), PropertyDetails(NONE, FIELD, 0)); // The dictionary does not need to grow. CHECK(new_dict.is_identical_to(dict)); } diff --git a/deps/v8/src/runtime/runtime.h b/deps/v8/src/runtime/runtime.h index 5d6ccac709..9e6c495162 100644 --- a/deps/v8/src/runtime/runtime.h +++ b/deps/v8/src/runtime/runtime.h @@ -45,7 +45,6 @@ namespace internal { F(IsSloppyModeFunction, 1, 1) \ F(GetDefaultReceiver, 1, 1) \ \ - F(GetPrototype, 1, 1) \ F(SetPrototype, 2, 1) \ F(InternalSetPrototype, 2, 1) \ F(IsInPrototypeChain, 2, 1) \ @@ -155,9 +154,8 @@ namespace internal { F(RemPiO2, 1, 1) \ \ /* Regular expressions */ \ - F(RegExpCompile, 3, 1) \ + F(RegExpInitializeAndCompile, 3, 1) \ F(RegExpExecMultiple, 4, 1) \ - F(RegExpInitializeObject, 6, 1) \ \ /* JSON */ \ F(ParseJson, 1, 1) \ @@ -199,7 +197,8 @@ namespace internal { F(StoreToSuper_Strict, 4, 1) \ F(StoreToSuper_Sloppy, 4, 1) \ F(StoreKeyedToSuper_Strict, 4, 1) \ - F(StoreKeyedToSuper_Sloppy, 4, 1) + F(StoreKeyedToSuper_Sloppy, 4, 1) \ + F(DefaultConstructorSuperCall, 0, 1) #define RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \ @@ -250,11 +249,10 @@ namespace internal { F(DateCacheVersion, 0, 1) \ \ /* Globals */ \ - F(CompileString, 2, 1) \ + F(CompileString, 3, 1) \ \ /* Eval */ \ F(GlobalProxy, 1, 1) \ - F(IsAttachedGlobal, 1, 1) \ \ F(AddNamedProperty, 4, 1) \ F(AddPropertyForTemplate, 4, 1) \ @@ -277,6 +275,7 @@ namespace internal { F(LookupAccessor, 3, 1) \ \ /* ES5 */ \ + F(ObjectSeal, 1, 1) \ F(ObjectFreeze, 1, 1) \ \ /* Harmony modules */ \ @@ -301,30 +300,15 @@ namespace internal { F(GetConstructTrap, 1, 1) \ F(Fix, 1, 1) \ \ - /* Harmony sets */ \ - F(SetInitialize, 1, 1) \ - F(SetAdd, 2, 1) \ - F(SetHas, 2, 1) \ - F(SetDelete, 2, 1) \ - F(SetClear, 1, 1) \ - F(SetGetSize, 1, 1) \ - \ + /* ES6 collection iterators */ \ F(SetIteratorInitialize, 3, 1) \ F(SetIteratorClone, 1, 1) \ F(SetIteratorNext, 2, 1) \ - \ - /* Harmony maps */ \ - F(MapInitialize, 1, 1) \ - F(MapGet, 2, 1) \ - F(MapHas, 2, 1) \ - F(MapDelete, 2, 1) \ - F(MapClear, 1, 1) \ - F(MapSet, 3, 1) \ - F(MapGetSize, 1, 1) \ - \ + F(SetIteratorDetails, 1, 1) \ F(MapIteratorInitialize, 3, 1) \ F(MapIteratorClone, 1, 1) \ F(MapIteratorNext, 2, 1) \ + F(MapIteratorDetails, 1, 1) \ \ /* Harmony weak maps and sets */ \ F(WeakCollectionInitialize, 1, 1) \ @@ -333,8 +317,8 @@ namespace internal { F(WeakCollectionDelete, 2, 1) \ F(WeakCollectionSet, 3, 1) \ \ - F(GetWeakMapEntries, 1, 1) \ - F(GetWeakSetValues, 1, 1) \ + F(GetWeakMapEntries, 2, 1) \ + F(GetWeakSetValues, 2, 1) \ \ /* Harmony events */ \ F(EnqueueMicrotask, 1, 1) \ @@ -476,7 +460,7 @@ namespace internal { F(CreateJSGeneratorObject, 0, 1) \ F(SuspendJSGeneratorObject, 1, 1) \ F(ResumeJSGeneratorObject, 3, 1) \ - F(ThrowGeneratorStateError, 1, 1) \ + F(GeneratorClose, 1, 1) \ \ /* Arrays */ \ F(ArrayConstructor, -1, 1) \ @@ -498,12 +482,13 @@ namespace internal { F(ReThrow, 1, 1) \ F(ThrowReferenceError, 1, 1) \ F(ThrowNotDateError, 0, 1) \ + F(ThrowConstAssignError, 0, 1) \ F(StackGuard, 0, 1) \ F(Interrupt, 0, 1) \ F(PromoteScheduledException, 0, 1) \ \ /* Contexts */ \ - F(NewGlobalContext, 2, 1) \ + F(NewScriptContext, 2, 1) \ F(NewFunctionContext, 1, 1) \ F(PushWithContext, 2, 1) \ F(PushCatchContext, 3, 1) \ @@ -728,7 +713,24 @@ namespace internal { F(DoubleHi, 1, 1) \ F(DoubleLo, 1, 1) \ F(MathSqrtRT, 1, 1) \ - F(MathLogRT, 1, 1) + F(MathLogRT, 1, 1) \ + /* ES6 Collections */ \ + F(MapClear, 1, 1) \ + F(MapDelete, 2, 1) \ + F(MapGet, 2, 1) \ + F(MapGetSize, 1, 1) \ + F(MapHas, 2, 1) \ + F(MapInitialize, 1, 1) \ + F(MapSet, 3, 1) \ + F(SetAdd, 2, 1) \ + F(SetClear, 1, 1) \ + F(SetDelete, 2, 1) \ + F(SetGetSize, 1, 1) \ + F(SetHas, 2, 1) \ + F(SetInitialize, 1, 1) \ + /* Arrays */ \ + F(HasFastPackedElements, 1, 1) \ + F(GetPrototype, 1, 1) //--------------------------------------------------------------------------- @@ -828,6 +830,9 @@ class Runtime : public AllStatic { MUST_USE_RESULT static MaybeHandle<Object> GetObjectProperty( Isolate* isolate, Handle<Object> object, Handle<Object> key); + MUST_USE_RESULT static MaybeHandle<Object> GetPrototype( + Isolate* isolate, Handle<Object> object); + MUST_USE_RESULT static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key); diff --git a/deps/v8/src/runtime/string-builder.h b/deps/v8/src/runtime/string-builder.h deleted file mode 100644 index 890b7f6be1..0000000000 --- a/deps/v8/src/runtime/string-builder.h +++ /dev/null @@ -1,296 +0,0 @@ -// Copyright 2014 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8_RUNTIME_STRING_BUILDER_H_ -#define V8_RUNTIME_STRING_BUILDER_H_ - -namespace v8 { -namespace internal { - -const int kStringBuilderConcatHelperLengthBits = 11; -const int kStringBuilderConcatHelperPositionBits = 19; - -typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits> - StringBuilderSubstringLength; -typedef BitField<int, kStringBuilderConcatHelperLengthBits, - kStringBuilderConcatHelperPositionBits> - StringBuilderSubstringPosition; - - -template <typename sinkchar> -static inline void StringBuilderConcatHelper(String* special, sinkchar* sink, - FixedArray* fixed_array, - int array_length) { - DisallowHeapAllocation no_gc; - int position = 0; - for (int i = 0; i < array_length; i++) { - Object* element = fixed_array->get(i); - if (element->IsSmi()) { - // Smi encoding of position and length. - int encoded_slice = Smi::cast(element)->value(); - int pos; - int len; - if (encoded_slice > 0) { - // Position and length encoded in one smi. - pos = StringBuilderSubstringPosition::decode(encoded_slice); - len = StringBuilderSubstringLength::decode(encoded_slice); - } else { - // Position and length encoded in two smis. - Object* obj = fixed_array->get(++i); - DCHECK(obj->IsSmi()); - pos = Smi::cast(obj)->value(); - len = -encoded_slice; - } - String::WriteToFlat(special, sink + position, pos, pos + len); - position += len; - } else { - String* string = String::cast(element); - int element_length = string->length(); - String::WriteToFlat(string, sink + position, 0, element_length); - position += element_length; - } - } -} - - -// Returns the result length of the concatenation. -// On illegal argument, -1 is returned. -static inline int StringBuilderConcatLength(int special_length, - FixedArray* fixed_array, - int array_length, bool* one_byte) { - DisallowHeapAllocation no_gc; - int position = 0; - for (int i = 0; i < array_length; i++) { - int increment = 0; - Object* elt = fixed_array->get(i); - if (elt->IsSmi()) { - // Smi encoding of position and length. - int smi_value = Smi::cast(elt)->value(); - int pos; - int len; - if (smi_value > 0) { - // Position and length encoded in one smi. - pos = StringBuilderSubstringPosition::decode(smi_value); - len = StringBuilderSubstringLength::decode(smi_value); - } else { - // Position and length encoded in two smis. - len = -smi_value; - // Get the position and check that it is a positive smi. - i++; - if (i >= array_length) return -1; - Object* next_smi = fixed_array->get(i); - if (!next_smi->IsSmi()) return -1; - pos = Smi::cast(next_smi)->value(); - if (pos < 0) return -1; - } - DCHECK(pos >= 0); - DCHECK(len >= 0); - if (pos > special_length || len > special_length - pos) return -1; - increment = len; - } else if (elt->IsString()) { - String* element = String::cast(elt); - int element_length = element->length(); - increment = element_length; - if (*one_byte && !element->HasOnlyOneByteChars()) { - *one_byte = false; - } - } else { - return -1; - } - if (increment > String::kMaxLength - position) { - return kMaxInt; // Provoke throw on allocation. - } - position += increment; - } - return position; -} - - -class FixedArrayBuilder { - public: - explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity) - : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)), - length_(0), - has_non_smi_elements_(false) { - // Require a non-zero initial size. Ensures that doubling the size to - // extend the array will work. - DCHECK(initial_capacity > 0); - } - - explicit FixedArrayBuilder(Handle<FixedArray> backing_store) - : array_(backing_store), length_(0), has_non_smi_elements_(false) { - // Require a non-zero initial size. Ensures that doubling the size to - // extend the array will work. - DCHECK(backing_store->length() > 0); - } - - bool HasCapacity(int elements) { - int length = array_->length(); - int required_length = length_ + elements; - return (length >= required_length); - } - - void EnsureCapacity(int elements) { - int length = array_->length(); - int required_length = length_ + elements; - if (length < required_length) { - int new_length = length; - do { - new_length *= 2; - } while (new_length < required_length); - Handle<FixedArray> extended_array = - array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length); - array_->CopyTo(0, *extended_array, 0, length_); - array_ = extended_array; - } - } - - void Add(Object* value) { - DCHECK(!value->IsSmi()); - DCHECK(length_ < capacity()); - array_->set(length_, value); - length_++; - has_non_smi_elements_ = true; - } - - void Add(Smi* value) { - DCHECK(value->IsSmi()); - DCHECK(length_ < capacity()); - array_->set(length_, value); - length_++; - } - - Handle<FixedArray> array() { return array_; } - - int length() { return length_; } - - int capacity() { return array_->length(); } - - Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { - JSArray::SetContent(target_array, array_); - target_array->set_length(Smi::FromInt(length_)); - return target_array; - } - - - private: - Handle<FixedArray> array_; - int length_; - bool has_non_smi_elements_; -}; - - -class ReplacementStringBuilder { - public: - ReplacementStringBuilder(Heap* heap, Handle<String> subject, - int estimated_part_count) - : heap_(heap), - array_builder_(heap->isolate(), estimated_part_count), - subject_(subject), - character_count_(0), - is_one_byte_(subject->IsOneByteRepresentation()) { - // Require a non-zero initial size. Ensures that doubling the size to - // extend the array will work. - DCHECK(estimated_part_count > 0); - } - - static inline void AddSubjectSlice(FixedArrayBuilder* builder, int from, - int to) { - DCHECK(from >= 0); - int length = to - from; - DCHECK(length > 0); - if (StringBuilderSubstringLength::is_valid(length) && - StringBuilderSubstringPosition::is_valid(from)) { - int encoded_slice = StringBuilderSubstringLength::encode(length) | - StringBuilderSubstringPosition::encode(from); - builder->Add(Smi::FromInt(encoded_slice)); - } else { - // Otherwise encode as two smis. - builder->Add(Smi::FromInt(-length)); - builder->Add(Smi::FromInt(from)); - } - } - - - void EnsureCapacity(int elements) { array_builder_.EnsureCapacity(elements); } - - - void AddSubjectSlice(int from, int to) { - AddSubjectSlice(&array_builder_, from, to); - IncrementCharacterCount(to - from); - } - - - void AddString(Handle<String> string) { - int length = string->length(); - DCHECK(length > 0); - AddElement(*string); - if (!string->IsOneByteRepresentation()) { - is_one_byte_ = false; - } - IncrementCharacterCount(length); - } - - - MaybeHandle<String> ToString() { - Isolate* isolate = heap_->isolate(); - if (array_builder_.length() == 0) { - return isolate->factory()->empty_string(); - } - - Handle<String> joined_string; - if (is_one_byte_) { - Handle<SeqOneByteString> seq; - ASSIGN_RETURN_ON_EXCEPTION( - isolate, seq, - isolate->factory()->NewRawOneByteString(character_count_), String); - - DisallowHeapAllocation no_gc; - uint8_t* char_buffer = seq->GetChars(); - StringBuilderConcatHelper(*subject_, char_buffer, *array_builder_.array(), - array_builder_.length()); - joined_string = Handle<String>::cast(seq); - } else { - // Two-byte. - Handle<SeqTwoByteString> seq; - ASSIGN_RETURN_ON_EXCEPTION( - isolate, seq, - isolate->factory()->NewRawTwoByteString(character_count_), String); - - DisallowHeapAllocation no_gc; - uc16* char_buffer = seq->GetChars(); - StringBuilderConcatHelper(*subject_, char_buffer, *array_builder_.array(), - array_builder_.length()); - joined_string = Handle<String>::cast(seq); - } - return joined_string; - } - - - void IncrementCharacterCount(int by) { - if (character_count_ > String::kMaxLength - by) { - STATIC_ASSERT(String::kMaxLength < kMaxInt); - character_count_ = kMaxInt; - } else { - character_count_ += by; - } - } - - private: - void AddElement(Object* element) { - DCHECK(element->IsSmi() || element->IsString()); - DCHECK(array_builder_.capacity() > array_builder_.length()); - array_builder_.Add(element); - } - - Heap* heap_; - FixedArrayBuilder array_builder_; - Handle<String> subject_; - int character_count_; - bool is_one_byte_; -}; -} -} // namespace v8::internal - -#endif // V8_RUNTIME_STRING_BUILDER_H_ |