summaryrefslogtreecommitdiff
path: root/deps/v8/src/runtime
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2015-01-07 18:38:38 +0100
committerBen Noordhuis <info@bnoordhuis.nl>2015-01-07 22:11:18 +0100
commitdad73f645cde6920e79db956e7ef82ed640d7615 (patch)
tree7ba3f3fc7e0722c5f130065461b7c56f571af383 /deps/v8/src/runtime
parent53ba494537259b18b346dc6150d6a100c557e08f (diff)
downloadnode-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.cc163
-rw-r--r--deps/v8/src/runtime/runtime-classes.cc117
-rw-r--r--deps/v8/src/runtime/runtime-collections.cc77
-rw-r--r--deps/v8/src/runtime/runtime-compiler.cc17
-rw-r--r--deps/v8/src/runtime/runtime-debug.cc120
-rw-r--r--deps/v8/src/runtime/runtime-generator.cc12
-rw-r--r--deps/v8/src/runtime/runtime-literals.cc47
-rw-r--r--deps/v8/src/runtime/runtime-object.cc119
-rw-r--r--deps/v8/src/runtime/runtime-observe.cc13
-rw-r--r--deps/v8/src/runtime/runtime-regexp.cc139
-rw-r--r--deps/v8/src/runtime/runtime-scopes.cc80
-rw-r--r--deps/v8/src/runtime/runtime-strings.cc2
-rw-r--r--deps/v8/src/runtime/runtime-test.cc14
-rw-r--r--deps/v8/src/runtime/runtime-uri.cc32
-rw-r--r--deps/v8/src/runtime/runtime.cc3
-rw-r--r--deps/v8/src/runtime/runtime.h63
-rw-r--r--deps/v8/src/runtime/string-builder.h296
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_