Merged r12485, r12486, r12491, r12494, r12495 into trunk branch.
Fix edge case of extension with NULL as source string.
Fixed CHECK failure in LCodeGen::DoWrapReceiver when --deopt-every-n-times flag is present
Correctly initialize regexp global cache.
Ensure correct enumeration indices in the dict
Fix API check for length of external arrays.
BUG=chromium:144649,chromium:148389,chromium:148378,chromium:148376,chromium:148896
R=yangguo@chromium.org,mstarzinger@chromium.org,verwaest@chromium.org
Review URL: https://codereview.chromium.org/10907233
git-svn-id: http://v8.googlecode.com/svn/trunk@12514 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/api.cc b/src/api.cc
index 8b323b2..dcbc894 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -541,7 +541,9 @@
source_(source, source_length_),
dep_count_(dep_count),
deps_(deps),
- auto_enable_(false) { }
+ auto_enable_(false) {
+ CHECK(source != NULL || source_length_ == 0);
+}
v8::Handle<Primitive> Undefined() {
@@ -3402,7 +3404,7 @@
ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- if (!ApiCheck(length <= i::ExternalPixelArray::kMaxLength,
+ if (!ApiCheck(length >= 0 && length <= i::ExternalPixelArray::kMaxLength,
"v8::Object::SetIndexedPropertiesToPixelData()",
"length exceeds max acceptable value")) {
return;
@@ -3458,7 +3460,7 @@
ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- if (!ApiCheck(length <= i::ExternalArray::kMaxLength,
+ if (!ApiCheck(length >= 0 && length <= i::ExternalArray::kMaxLength,
"v8::Object::SetIndexedPropertiesToExternalArrayData()",
"length exceeds max acceptable value")) {
return;
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 33efdd8..2b42b13 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -2946,12 +2946,12 @@
FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
__ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset),
1 << SharedFunctionInfo::kStrictModeBitWithinByte);
- __ j(not_equal, &receiver_ok, Label::kNear);
+ __ j(not_equal, &receiver_ok); // A near jump is not sufficient here!
// Do not transform the receiver to object for builtins.
__ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset),
1 << SharedFunctionInfo::kNativeBitWithinByte);
- __ j(not_equal, &receiver_ok, Label::kNear);
+ __ j(not_equal, &receiver_ok);
// Normal function. Replace undefined or null with global receiver.
__ cmp(receiver, factory()->null_value());
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index ae25432..e59170d 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -706,16 +706,17 @@
RegExpImpl::GlobalCache::GlobalCache(Handle<JSRegExp> regexp,
Handle<String> subject,
bool is_global,
- Isolate* isolate) {
+ Isolate* isolate)
+ : register_array_(NULL),
+ register_array_size_(0),
+ regexp_(regexp),
+ subject_(subject) {
#ifdef V8_INTERPRETED_REGEXP
bool interpreted = true;
#else
bool interpreted = false;
#endif // V8_INTERPRETED_REGEXP
- regexp_ = regexp;
- subject_ = subject;
-
if (regexp_->TypeTag() == JSRegExp::ATOM) {
static const int kAtomRegistersPerMatch = 2;
registers_per_match_ = kAtomRegistersPerMatch;
diff --git a/src/objects.cc b/src/objects.cc
index 57882a4..45d108b 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -487,11 +487,20 @@
set_properties(StringDictionary::cast(dict));
return value;
}
- // Preserve enumeration index.
+
+ PropertyDetails original_details = property_dictionary()->DetailsAt(entry);
+ int enumeration_index;
+ // Preserve the enumeration index unless the property was deleted.
+ if (original_details.IsDeleted()) {
+ enumeration_index = property_dictionary()->NextEnumerationIndex();
+ property_dictionary()->SetNextEnumerationIndex(enumeration_index + 1);
+ } else {
+ enumeration_index = original_details.dictionary_index();
+ ASSERT(enumeration_index > 0);
+ }
+
details = PropertyDetails(
- details.attributes(),
- details.type(),
- property_dictionary()->DetailsAt(entry).dictionary_index());
+ details.attributes(), details.type(), enumeration_index);
if (IsGlobalObject()) {
JSGlobalPropertyCell* cell =
diff --git a/src/objects.h b/src/objects.h
index 9b33a43..45a2ac0 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -7386,7 +7386,7 @@
#ifdef V8_HOST_CAN_READ_UNALIGNED
ASSERT(kMaxAsciiCharCode == 0x7F);
const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80;
- while (chars <= limit - sizeof(uintptr_t)) {
+ while (chars + sizeof(uintptr_t) <= limit) {
if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) {
return false;
}
diff --git a/src/version.cc b/src/version.cc
index de99d57..628665c 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 13
#define BUILD_NUMBER 7
-#define PATCH_LEVEL 0
+#define PATCH_LEVEL 1
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index f7d8d80..7fac9fd 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -4671,6 +4671,18 @@
}
+THREADED_TEST(NullExtensions) {
+ v8::HandleScope handle_scope;
+ v8::RegisterExtension(new Extension("nulltest", NULL));
+ const char* extension_names[] = { "nulltest" };
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Handle<Context> context = Context::New(&extensions);
+ Context::Scope lock(context);
+ v8::Handle<Value> result = Script::Compile(v8_str("1+3"))->Run();
+ CHECK_EQ(result, v8::Integer::New(4));
+}
+
+
static const char* kEmbeddedExtensionSource =
"function Ret54321(){return 54321;}~~@@$"
"$%% THIS IS A SERIES OF NON-NULL-TERMINATED STRINGS.";
@@ -14011,6 +14023,41 @@
}
+void ExternalArrayLimitTestHelper(v8::ExternalArrayType array_type, int size) {
+ v8::Handle<v8::Object> obj = v8::Object::New();
+ v8::V8::SetFatalErrorHandler(StoringErrorCallback);
+ last_location = last_message = NULL;
+ obj->SetIndexedPropertiesToExternalArrayData(NULL, array_type, size);
+ CHECK(!obj->HasIndexedPropertiesInExternalArrayData());
+ CHECK_NE(NULL, last_location);
+ CHECK_NE(NULL, last_message);
+}
+
+
+TEST(ExternalArrayLimits) {
+ v8::HandleScope scope;
+ LocalContext context;
+ ExternalArrayLimitTestHelper(v8::kExternalByteArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalByteArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalUnsignedByteArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalUnsignedByteArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalShortArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalShortArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalUnsignedShortArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalUnsignedShortArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalIntArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalIntArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalUnsignedIntArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalUnsignedIntArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalFloatArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalFloatArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalDoubleArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalDoubleArray, 0xffffffff);
+ ExternalArrayLimitTestHelper(v8::kExternalPixelArray, 0x40000000);
+ ExternalArrayLimitTestHelper(v8::kExternalPixelArray, 0xffffffff);
+}
+
+
THREADED_TEST(ScriptContextDependence) {
v8::HandleScope scope;
LocalContext c1;
diff --git a/test/cctest/test-strings.cc b/test/cctest/test-strings.cc
index 4557100..5a9ccbb 100644
--- a/test/cctest/test-strings.cc
+++ b/test/cctest/test-strings.cc
@@ -11,6 +11,7 @@
#include "api.h"
#include "factory.h"
+#include "objects.h"
#include "cctest.h"
#include "zone-inl.h"
@@ -708,3 +709,9 @@
v8::Local<v8::String> expected = v8_str("ascii\x80only\x80string\x80");
CHECK(expected->Equals(result));
}
+
+
+TEST(IsAscii) {
+ CHECK(String::IsAscii(static_cast<char*>(NULL), 0));
+ CHECK(String::IsAscii(static_cast<uc16*>(NULL), 0));
+}
diff --git a/test/mjsunit/regress/regress-148378.js b/test/mjsunit/regress/regress-148378.js
new file mode 100644
index 0000000..d37cea1
--- /dev/null
+++ b/test/mjsunit/regress/regress-148378.js
@@ -0,0 +1,38 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"a".replace(/a/g, function() { return "c"; });
+
+function test() {
+ try {
+ test();
+ } catch(e) {
+ "b".replace(/(b)/g, function() { return "c"; });
+ }
+}
+
+test();
diff --git a/test/mjsunit/regress/regress-crbug-148376.js b/test/mjsunit/regress/regress-crbug-148376.js
new file mode 100644
index 0000000..55bb5f1
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-148376.js
@@ -0,0 +1,35 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+function defineSetter(o) {
+ o.__defineSetter__('property', function() {});
+}
+
+defineSetter(Object.prototype);
+property = 0;
+defineSetter(this);
+var keys = Object.keys(this);