Revision: 9269
Author: [email protected]
Date: Wed Sep 14 01:04:47 2011
Log: MIPS: port Remove in-loop tracking for call ICs.
port r9260 (af9cfd83).
Original commit message:
We passed this flag around in a lot of places and had differenc call
ICs based on it, but never did any real specialization based on its
value.
BUG=
TEST=
Review URL: http://codereview.chromium.org/7886028
Patch from Paul Lind <[email protected]>.
http://code.google.com/p/v8/source/detail?r=9269
Modified:
/branches/bleeding_edge/src/mips/full-codegen-mips.cc
/branches/bleeding_edge/src/mips/ic-mips.cc
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/v8natives.js
/branches/bleeding_edge/test/cctest/test-decls.cc
/branches/bleeding_edge/test/es5conform/es5conform.status
/branches/bleeding_edge/test/mjsunit/const-redecl.js
/branches/bleeding_edge/test/mjsunit/global-const-var-conflicts.js
/branches/bleeding_edge/test/mjsunit/regress/regress-1170.js
/branches/bleeding_edge/test/mjsunit/regress/regress-1213575.js
/branches/bleeding_edge/test/mjsunit/undeletable-functions.js
/branches/bleeding_edge/test/sputnik/sputnik.status
=======================================
--- /branches/bleeding_edge/src/mips/full-codegen-mips.cc Thu Sep 8
01:47:07 2011
+++ /branches/bleeding_edge/src/mips/full-codegen-mips.cc Wed Sep 14
01:04:47 2011
@@ -2042,9 +2042,8 @@
// Record source position for debugger.
SetSourcePosition(expr->position());
// Call the IC initialization code.
- InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
Handle<Code> ic =
- isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop,
mode);
+ isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
__ Call(ic, mode, expr->id());
RecordJSReturnSite(expr);
// Restore context register.
@@ -2075,9 +2074,8 @@
// Record source position for debugger.
SetSourcePosition(expr->position());
// Call the IC initialization code.
- InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
Handle<Code> ic =
- isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count,
in_loop);
+ isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
__ lw(a2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key.
__ Call(ic, RelocInfo::CODE_TARGET, expr->id());
RecordJSReturnSite(expr);
@@ -2098,8 +2096,7 @@
}
// Record source position for debugger.
SetSourcePosition(expr->position());
- InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
- CallFunctionStub stub(arg_count, in_loop, flags);
+ CallFunctionStub stub(arg_count, flags);
__ CallStub(&stub);
RecordJSReturnSite(expr);
// Restore context register.
@@ -2197,8 +2194,7 @@
}
// Record source position for debugger.
SetSourcePosition(expr->position());
- InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
- CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT);
+ CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT);
__ CallStub(&stub);
RecordJSReturnSite(expr);
// Restore context register.
@@ -3574,9 +3570,7 @@
__ li(a2, Operand(expr->name()));
RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
Handle<Code> ic =
- isolate()->stub_cache()->ComputeCallInitialize(arg_count,
- NOT_IN_LOOP,
- mode);
+ isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
__ Call(ic, mode, expr->id());
// Restore context register.
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
=======================================
--- /branches/bleeding_edge/src/mips/ic-mips.cc Mon Sep 12 03:50:50 2011
+++ /branches/bleeding_edge/src/mips/ic-mips.cc Wed Sep 14 01:04:47 2011
@@ -395,7 +395,6 @@
// Probe the stub cache.
Code::Flags flags = Code::ComputeFlags(kind,
- NOT_IN_LOOP,
MONOMORPHIC,
extra_ic_state,
NORMAL,
@@ -732,9 +731,7 @@
// -----------------------------------
// Probe the stub cache.
- Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC,
- NOT_IN_LOOP,
- MONOMORPHIC);
+ Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC);
Isolate::Current()->stub_cache()->GenerateProbe(
masm, flags, a0, a2, a3, t0, t1);
@@ -1395,10 +1392,8 @@
// -----------------------------------
// Get the receiver from the stack and probe the stub cache.
- Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
- NOT_IN_LOOP,
- MONOMORPHIC,
- strict_mode);
+ Code::Flags flags =
+ Code::ComputeFlags(Code::STORE_IC, MONOMORPHIC, strict_mode);
Isolate::Current()->stub_cache()->GenerateProbe(
masm, flags, a1, a2, a3, t0, t1);
=======================================
--- /branches/bleeding_edge/src/runtime.cc Tue Sep 13 05:53:28 2011
+++ /branches/bleeding_edge/src/runtime.cc Wed Sep 14 01:04:47 2011
@@ -1211,46 +1211,17 @@
LookupResult lookup;
global->Lookup(*name, &lookup);
if (lookup.IsProperty()) {
- // Determine if the property is local by comparing the holder
- // against the global object. The information will be used to
- // avoid throwing re-declaration errors when declaring
- // variables or constants that exist in the prototype chain.
- bool is_local = (*global == lookup.holder());
- // Get the property attributes and determine if the property is
- // read-only.
+ // We found an existing property. Unless it was an interceptor
+ // that claims the property is absent, skip this declaration.
+ if (lookup.type() != INTERCEPTOR) {
+ continue;
+ }
PropertyAttributes attributes =
global->GetPropertyAttribute(*name);
- bool is_read_only = (attributes & READ_ONLY) != 0;
- if (lookup.type() == INTERCEPTOR) {
- // If the interceptor says the property is there, we
- // just return undefined without overwriting the property.
- // Otherwise, we continue to setting the property.
- if (attributes != ABSENT) {
- // Check if the existing property conflicts with regards to
const.
- if (is_local && (is_read_only || is_const_property)) {
- const char* type = (is_read_only) ? "const" : "var";
- return ThrowRedeclarationError(isolate, type, name);
- };
- // The property already exists without conflicting: Go to
- // the next declaration.
- continue;
- }
- // Fall-through and introduce the absent property by using
- // SetProperty.
- } else {
- // For const properties, we treat a callback with this name
- // even in the prototype as a conflicting declaration.
- if (is_const_property && (lookup.type() == CALLBACKS)) {
- return ThrowRedeclarationError(isolate, "const", name);
- }
- // Otherwise, we check for locally conflicting declarations.
- if (is_local && (is_read_only || is_const_property)) {
- const char* type = (is_read_only) ? "const" : "var";
- return ThrowRedeclarationError(isolate, type, name);
- }
- // The property already exists without conflicting: Go to
- // the next declaration.
+ if (attributes != ABSENT) {
continue;
}
+ // Fall-through and introduce the absent property by using
+ // SetProperty.
}
} else {
is_function_declaration = true;
@@ -1266,20 +1237,6 @@
LookupResult lookup;
global->LocalLookup(*name, &lookup);
-
- // There's a local property that we need to overwrite because
- // we're either declaring a function or there's an interceptor
- // that claims the property is absent.
- //
- // Check for conflicting re-declarations. We cannot have
- // conflicting types in case of intercepted properties because
- // they are absent.
- if (lookup.IsProperty() &&
- (lookup.type() != INTERCEPTOR) &&
- (lookup.IsReadOnly() || is_const_property)) {
- const char* type = (lookup.IsReadOnly()) ? "const" : "var";
- return ThrowRedeclarationError(isolate, type, name);
- }
// Compute the property attributes. According to ECMA-262, section
// 13, page 71, the property must be read-only and
@@ -1465,64 +1422,32 @@
// to assign to the property.
// Note that objects can have hidden prototypes, so we need to traverse
// the whole chain of hidden prototypes to do a 'local' lookup.
- JSObject* real_holder = global;
+ Object* object = global;
LookupResult lookup;
- while (true) {
- real_holder->LocalLookup(*name, &lookup);
- if (lookup.IsProperty()) {
- // Determine if this is a redeclaration of something read-only.
- if (lookup.IsReadOnly()) {
- // If we found readonly property on one of hidden prototypes,
- // just shadow it.
- if (real_holder != isolate->context()->global()) break;
- return ThrowRedeclarationError(isolate, "const", name);
- }
-
- // Determine if this is a redeclaration of an intercepted read-only
- // property and figure out if the property exists at all.
- bool found = true;
- PropertyType type = lookup.type();
- if (type == INTERCEPTOR) {
- HandleScope handle_scope(isolate);
- Handle<JSObject> holder(real_holder);
- PropertyAttributes intercepted =
holder->GetPropertyAttribute(*name);
- real_holder = *holder;
- if (intercepted == ABSENT) {
- // The interceptor claims the property isn't there. We need to
- // make sure to introduce it.
- found = false;
- } else if ((intercepted & READ_ONLY) != 0) {
- // The property is present, but read-only. Since we're trying to
- // overwrite it with a variable declaration we must throw a
- // re-declaration error. However if we found readonly property
- // on one of hidden prototypes, just shadow it.
- if (real_holder != isolate->context()->global()) break;
- return ThrowRedeclarationError(isolate, "const", name);
+ while (object->IsJSObject() &&
+ JSObject::cast(object)->map()->is_hidden_prototype()) {
+ JSObject* raw_holder = JSObject::cast(object);
+ raw_holder->LocalLookup(*name, &lookup);
+ if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
+ HandleScope handle_scope(isolate);
+ Handle<JSObject> holder(raw_holder);
+ PropertyAttributes intercepted = holder->GetPropertyAttribute(*name);
+ // Update the raw pointer in case it's changed due to GC.
+ raw_holder = *holder;
+ if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
+ // Found an interceptor that's not read only.
+ if (assign) {
+ return raw_holder->SetProperty(
+ &lookup, *name, args[2], attributes, strict_mode);
+ } else {
+ return isolate->heap()->undefined_value();
}
}
-
- if (found && !assign) {
- // The global property is there and we're not assigning any value
- // to it. Just return.
- return isolate->heap()->undefined_value();
- }
-
- // Assign the value (or undefined) to the property.
- Object* value = (assign) ? args[2] :
isolate->heap()->undefined_value();
- return real_holder->SetProperty(
- &lookup, *name, value, attributes, strict_mode);
- }
-
- Object* proto = real_holder->GetPrototype();
- if (!proto->IsJSObject())
- break;
-
- if (!JSObject::cast(proto)->map()->is_hidden_prototype())
- break;
-
- real_holder = JSObject::cast(proto);
+ }
+ object = raw_holder->GetPrototype();
}
+ // Reload global in case the loop above performed a GC.
global = isolate->context()->global();
if (assign) {
return global->SetProperty(*name, args[2], attributes, strict_mode);
@@ -1560,20 +1485,16 @@
attributes);
}
- // Determine if this is a redeclaration of something not
+ // Determine if this is a re-initialization of something not
// read-only. In case the result is hidden behind an interceptor we
// need to ask it for the property attributes.
- if (!lookup.IsReadOnly()) {
- if (lookup.type() != INTERCEPTOR) {
- return ThrowRedeclarationError(isolate, "var", name);
- }
-
+ if (!lookup.IsReadOnly() && lookup.type() == INTERCEPTOR) {
PropertyAttributes intercepted = global->GetPropertyAttribute(*name);
- // Throw re-declaration error if the intercepted property is present
+ // Ignore the re-initialization if the intercepted property is present
// but not read-only.
if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
- return ThrowRedeclarationError(isolate, "var", name);
+ return isolate->heap()->undefined_value();
}
// Restore global object from context (in case of GC) and continue
@@ -1603,11 +1524,12 @@
if (type == FIELD) {
FixedArray* properties = global->properties();
int index = lookup.GetFieldIndex();
- if (properties->get(index)->IsTheHole()) {
+ if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
properties->set(index, *value);
}
} else if (type == NORMAL) {
- if (global->GetNormalizedProperty(&lookup)->IsTheHole()) {
+ if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
+ !lookup.IsReadOnly()) {
global->SetNormalizedProperty(&lookup, *value);
}
} else {
=======================================
--- /branches/bleeding_edge/src/v8natives.js Tue Sep 13 04:42:57 2011
+++ /branches/bleeding_edge/src/v8natives.js Wed Sep 14 01:04:47 2011
@@ -193,13 +193,14 @@
function SetUpGlobal() {
%CheckIsBootstrapping();
// ECMA 262 - 15.1.1.1.
- %SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE);
+ %SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE | READ_ONLY);
// ECMA-262 - 15.1.1.2.
- %SetProperty(global, "Infinity", 1/0, DONT_ENUM | DONT_DELETE);
+ %SetProperty(global, "Infinity", 1/0, DONT_ENUM | DONT_DELETE |
READ_ONLY);
// ECMA-262 - 15.1.1.3.
- %SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE);
+ %SetProperty(global, "undefined", void 0,
+ DONT_ENUM | DONT_DELETE | READ_ONLY);
// Set up non-enumerable function on the global object.
InstallFunctions(global, DONT_ENUM, $Array(
=======================================
--- /branches/bleeding_edge/test/cctest/test-decls.cc Wed Aug 3 02:53:14
2011
+++ /branches/bleeding_edge/test/cctest/test-decls.cc Wed Sep 14 01:04:47
2011
@@ -285,18 +285,18 @@
{ PresentPropertyContext context;
context.Check("const x; x",
+ 1, // access
0,
- 0,
- 1, // (re-)declaration
- EXPECT_EXCEPTION); // x has already been declared!
+ 2, // (re-)declaration + initialization
+ EXPECT_EXCEPTION); // x is not defined!
}
{ PresentPropertyContext context;
context.Check("const x = 0; x",
+ 1, // access
0,
- 0,
- 1, // (re-)declaration
- EXPECT_EXCEPTION); // x has already been declared!
+ 2, // (re-)declaration + initialization
+ EXPECT_EXCEPTION); // x is not defined!
}
}
@@ -429,18 +429,20 @@
{ AppearingPropertyContext context;
context.Check("const x; x",
- 0,
+ 1, // access
1, // declaration
2, // declaration + initialization
- EXPECT_EXCEPTION); // x has already been declared!
+ EXPECT_RESULT, Undefined());
}
{ AppearingPropertyContext context;
context.Check("const x = 0; x",
- 0,
+ 1, // access
1, // declaration
2, // declaration + initialization
- EXPECT_EXCEPTION); // x has already been declared!
+ EXPECT_RESULT, Undefined());
+ // Result is undefined because declaration succeeded but
+ // initialization to 0 failed (due to context behavior).
}
}
@@ -496,9 +498,9 @@
{ ReappearingPropertyContext context;
context.Check("const x; var x = 0",
0,
- 2, // var declaration + const initialization
+ 3, // const declaration+initialization, var
initialization
4, // 2 x declaration + 2 x initialization
- EXPECT_EXCEPTION); // x has already been declared!
+ EXPECT_RESULT, Undefined());
}
}
=======================================
--- /branches/bleeding_edge/test/es5conform/es5conform.status Thu Sep 1
04:28:10 2011
+++ /branches/bleeding_edge/test/es5conform/es5conform.status Wed Sep 14
01:04:47 2011
@@ -41,16 +41,6 @@
# We are compatible with Safari and Firefox.
chapter11/11.1/11.1.5: UNIMPLEMENTED
-# We do not have a global object called 'global' as required by tests.
-chapter15/15.1: FAIL_OK
-
-# NaN is writable. We are compatible with JSC.
-chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-178: FAIL_OK
-# Infinity is writable. We are compatible with JSC.
-chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-179: FAIL_OK
-# undefined is writable. We are compatible with JSC.
-chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-180: FAIL_OK
-
# Our Function object has an "arguments" property which is used as a
# non-property in the test.
chapter15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-183: FAIL_OK
=======================================
--- /branches/bleeding_edge/test/mjsunit/const-redecl.js Thu Sep 1
04:28:10 2011
+++ /branches/bleeding_edge/test/mjsunit/const-redecl.js Wed Sep 14
01:04:47 2011
@@ -98,7 +98,8 @@
var msg = s;
if (opt_e) { e = opt_e; msg += "; " + opt_e; }
assertEquals(expected, TestLocal(s,e), "local:'" + msg + "'");
- assertEquals(expected, TestGlobal(s,e), "global:'" + msg + "'");
+ // Redeclarations of global consts do not throw, they are silently
ignored.
+ assertEquals(42, TestGlobal(s, 42), "global:'" + msg + "'");
assertEquals(expected, TestContext(s,e), "context:'" + msg + "'");
}
@@ -218,3 +219,62 @@
// Test that const inside with behaves correctly.
TestAll(87, "with ({x:42}) { const x = 87; }", "x");
TestAll(undefined, "with ({x:42}) { const x; }", "x");
+
+
+// Additional tests for how various combinations of re-declarations affect
+// the values of the var/const in question.
+try {
+ eval("var undefined;");
+} catch (ex) {
+ assertUnreachable("undefined (1) has thrown");
+}
+
+var original_undef = undefined;
+var undefined = 1; // Should be silently ignored.
+assertEquals(original_undef, undefined, "undefined got overwritten");
+undefined = original_undef;
+
+var a; const a; const a = 1;
+assertEquals(1, a, "a has wrong value");
+a = 2;
+assertEquals(2, a, "a should be writable");
+
+var b = 1; const b = 2;
+assertEquals(2, b, "b has wrong value");
+
+var c = 1; const c = 2; const c = 3;
+assertEquals(3, c, "c has wrong value");
+
+const d = 1; const d = 2;
+assertEquals(1, d, "d has wrong value");
+
+const e = 1; var e = 2;
+assertEquals(1, e, "e has wrong value");
+
+const f = 1; const f;
+assertEquals(1, f, "f has wrong value");
+
+var g; const g = 1;
+assertEquals(1, g, "g has wrong value");
+g = 2;
+assertEquals(2, g, "g should be writable");
+
+const h; var h = 1;
+assertEquals(undefined,h, "h has wrong value");
+
+eval("Object.defineProperty(this, 'i', { writable: true });"
+ + "const i = 7;"
+ + "assertEquals(7, i, \"i has wrong value\");");
+
+var global = this;
+assertThrows(function() {
+ Object.defineProperty(global, 'j', { writable: true })
+}, TypeError);
+const j = 2; // This is what makes the function above throw, because the
+// const declaration gets hoisted and makes the property non-configurable.
+assertEquals(2, j, "j has wrong value");
+
+var k = 1; const k;
+// You could argue about the expected result here. For now, the winning
+// argument is that "const k;" is equivalent to "const k = undefined;".
+assertEquals(undefined, k, "k has wrong value");
=======================================
--- /branches/bleeding_edge/test/mjsunit/global-const-var-conflicts.js Tue
Dec 7 03:01:02 2010
+++ /branches/bleeding_edge/test/mjsunit/global-const-var-conflicts.js Wed
Sep 14 01:04:47 2011
@@ -26,7 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Check that dynamically introducing conflicting consts/vars
-// leads to exceptions.
+// is silently ignored (and does not lead to exceptions).
var caught = 0;
@@ -46,12 +46,12 @@
try { eval("const c"); } catch (e) { caught++; assertTrue(e instanceof
TypeError); }
assertTrue(typeof c == 'undefined');
try { eval("const c = 1"); } catch (e) { caught++; assertTrue(e instanceof
TypeError); }
-assertTrue(typeof c == 'undefined');
+assertEquals(1, c);
eval("var d = 0");
try { eval("const d"); } catch (e) { caught++; assertTrue(e instanceof
TypeError); }
-assertEquals(0, d);
+assertEquals(undefined, d);
try { eval("const d = 1"); } catch (e) { caught++; assertTrue(e instanceof
TypeError); }
-assertEquals(0, d);
-
-assertEquals(8, caught);
+assertEquals(1, d);
+
+assertEquals(0, caught);
=======================================
--- /branches/bleeding_edge/test/mjsunit/regress/regress-1170.js Tue May 31
01:08:42 2011
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-1170.js Wed Sep 14
01:04:47 2011
@@ -49,7 +49,7 @@
exception = true;
assertTrue(/TypeError/.test(e));
}
-assertTrue(exception);
+assertFalse(exception);
exception = false;
try {
=======================================
--- /branches/bleeding_edge/test/mjsunit/regress/regress-1213575.js Thu
Sep 1 04:28:10 2011
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-1213575.js Wed Sep
14 01:04:47 2011
@@ -25,9 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Make sure that a const definition always
-// conflicts with a defined setter. This avoid
-// trying to pass 'the hole' to the setter.
+// Make sure that a const definition does not try
+// to pass 'the hole' to a defined setter.
this.__defineSetter__('x', function(value) { assertTrue(false); });
@@ -38,4 +37,4 @@
assertTrue(e instanceof TypeError);
caught = true;
}
-assertTrue(caught);
+assertFalse(caught);
=======================================
--- /branches/bleeding_edge/test/mjsunit/undeletable-functions.js Wed Aug
3 02:53:14 2011
+++ /branches/bleeding_edge/test/mjsunit/undeletable-functions.js Wed Sep
14 01:04:47 2011
@@ -76,6 +76,8 @@
"execScript"];
CheckEcmaSemantics(this, array, "Global");
CheckReadOnlyAttr(this, "Infinity");
+CheckReadOnlyAttr(this, "NaN");
+CheckReadOnlyAttr(this, "undefined");
array = ["exec", "test", "toString", "compile"];
CheckEcmaSemantics(RegExp.prototype, array, "RegExp prototype");
@@ -189,7 +191,7 @@
assertFalse(deleted, "delete operator returned true: " + prop);
assertTrue(type.hasOwnProperty(prop), "not there after delete: " + prop);
type[prop] = "foo";
- assertEquals("foo", type[prop], "overwritable: " + prop);
+ assertEquals(old, type[prop], "overwritable: " + prop);
}
print("OK");
=======================================
--- /branches/bleeding_edge/test/sputnik/sputnik.status Fri Aug 19 04:02:41
2011
+++ /branches/bleeding_edge/test/sputnik/sputnik.status Wed Sep 14 01:04:47
2011
@@ -176,6 +176,14 @@
S15.5.4.14_A1_T3: FAIL_OK
S15.5.4.15_A1_T3: FAIL_OK
+# NaN, Infinity and undefined are read-only according to ES5.
+S15.1.1.1_A2_T1: FAIL_OK # NaN
+S15.1.1.1_A2_T2: FAIL_OK # NaN
+S15.1.1.2_A2_T1: FAIL_OK # Infinity
+# S15.1.1.2_A2_T2 would fail if it weren't bogus in r97. sputnik bug #45.
+S15.1.1.3_A2_T1: FAIL_OK # undefined
+S15.1.1.3_A2_T2: FAIL_OK # undefined
+
##################### SKIPPED TESTS #####################
# These tests take a looong time to run in debug mode.
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev