Push version 1.2.8 to trunk.
Optimized math on ARM platforms.
Fixed two crash bugs in the handling of getters and setters.
Improved the debugger support by adding scope chain information.
Improved the profiler support by compressing log data transmitted to clients.
Improved overall performance.
git-svn-id: http://v8.googlecode.com/svn/trunk@2181 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/test/mjsunit/array-sort.js b/test/mjsunit/array-sort.js
index ef75dcc..a082abc 100644
--- a/test/mjsunit/array-sort.js
+++ b/test/mjsunit/array-sort.js
@@ -214,6 +214,30 @@
TestNonArrayLongerLength(Math.pow(2,32) - 1);
+function TestNonArrayWithAccessors() {
+ // Regression test for issue 346, more info at URL
+ // http://code.google.com/p/v8/issues/detail?id=346
+ // Reported by nth10sd, test based on this report.
+ var x = {};
+ x[0] = 42;
+ x.__defineGetter__("1", function(){return this.foo;});
+ x.__defineSetter__("1", function(val){this.foo = val;});
+ x[1] = 49
+ x[3] = 37;
+ x.length = 4;
+ Array.prototype.sort.call(x);
+ // Behavior of sort with accessors is undefined. This accessor is
+ // well-behaved (acts like a normal property), so it should work.
+ assertEquals(4, x.length, "sortaccessors length");
+ assertEquals(37, x[0], "sortaccessors first");
+ assertEquals(42, x[1], "sortaccessors second");
+ assertEquals(49, x[2], "sortaccessors third")
+ assertFalse(3 in x, "sortaccessors fourth");
+}
+
+TestNonArrayWithAccessors();
+
+
function TestInheritedElementSort(depth) {
var length = depth * 2 + 3;
var obj = {length: length};
@@ -268,7 +292,7 @@
assertEquals(i, y[i], name + "value" + i);
}
for (var i = 10; i < length; i++) {
- assertEquals(x.hasOwnProperty(i), y.hasOwnProperty(i),
+ assertEquals(x.hasOwnProperty(i), y.hasOwnProperty(i),
name + "hasundef" + i);
assertEquals(undefined, y[i], name+"undefined"+i);
if (x.hasOwnProperty(i)) {
@@ -282,7 +306,7 @@
TestSparseInheritedElementSort(1000);
function TestSpecialCasesInheritedElementSort() {
-
+
var x = {
1:"d1",
2:"c1",
@@ -309,11 +333,11 @@
}
};
Array.prototype.sort.call(x);
-
+
var name = "SpecialInherit-";
-
+
assertEquals(10000, x.length, name + "length");
- var sorted = ["a2", "a3", "b1", "b2", "c1", "c2", "d1", "d2", "e3",
+ var sorted = ["a2", "a3", "b1", "b2", "c1", "c2", "d1", "d2", "e3",
undefined, undefined, undefined];
for (var i = 0; i < sorted.length; i++) {
assertTrue(x.hasOwnProperty(i), name + "has" + i)
@@ -321,7 +345,6 @@
}
assertFalse(x.hasOwnProperty(sorted.length), name + "haspost");
assertFalse(sorted.length in x, name + "haspost2");
-
assertTrue(x.hasOwnProperty(10), name + "hasundefined10");
assertEquals(undefined, x[10], name + "undefined10");
assertTrue(x.hasOwnProperty(100), name + "hasundefined100");
@@ -332,11 +355,8 @@
assertEquals(undefined, x[2000], name + "undefined2000");
assertTrue(x.hasOwnProperty(8000), name + "hasundefined8000");
assertEquals(undefined, x[8000], name + "undefined8000");
-
assertFalse(x.hasOwnProperty(12000), name + "has12000");
assertEquals("XX", x[12000], name + "XX12000");
-
}
TestSpecialCasesInheritedElementSort();
-
diff --git a/test/mjsunit/big-object-literal.js b/test/mjsunit/big-object-literal.js
index 0099ce9..8417951 100644
--- a/test/mjsunit/big-object-literal.js
+++ b/test/mjsunit/big-object-literal.js
@@ -84,7 +84,7 @@
}
// The sizes to test.
-var sizes = [1, 2, 100, 200, 400];
+var sizes = [1, 2, 100, 200, 350];
// Run the test.
for (var i = 0; i < sizes.length; i++) {
diff --git a/test/mjsunit/debug-scopes.js b/test/mjsunit/debug-scopes.js
new file mode 100644
index 0000000..7b477e1
--- /dev/null
+++ b/test/mjsunit/debug-scopes.js
@@ -0,0 +1,660 @@
+// Copyright 2008 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.
+
+// Flags: --expose-debug-as debug
+// The functions used for testing backtraces. They are at the top to make the
+// testing of source line/column easier.
+
+
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+var name;
+var listener_delegate;
+var listener_called;
+var exception;
+var begin_test_count = 0;
+var end_test_count = 0;
+var break_count = 0;
+
+
+// Debug event listener which delegates.
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Break) {
+ break_count++;
+ listener_called = true;
+ listener_delegate(exec_state)
+ }
+ } catch (e) {
+ exception = e;
+ }
+}
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+
+// Initialize for a noew test.
+function BeginTest(name) {
+ test_name = name;
+ listener_delegate = null;
+ listener_called = false;
+ exception = null;
+ begin_test_count++;
+}
+
+
+// Check result of a test.
+function EndTest() {
+ assertTrue(listener_called, "listerner not called for " + test_name);
+ assertNull(exception, test_name)
+ end_test_count++;
+}
+
+
+// Check that the scope chain contains the expected types of scopes.
+function CheckScopeChain(scopes, exec_state) {
+ assertEquals(scopes.length, exec_state.frame().scopeCount());
+ for (var i = 0; i < scopes.length; i++) {
+ var scope = exec_state.frame().scope(i);
+ assertTrue(scope.isScope());
+ assertEquals(scopes[i], scope.scopeType());
+
+ // Check the global object when hitting the global scope.
+ if (scopes[i] == debug.ScopeType.Global) {
+ assertEquals(this, scope.scopeObject().value());
+ }
+ }
+
+ // Get the debug command processor.
+ var dcp = exec_state.debugCommandProcessor();
+
+ // Send a scopes request and check the result.
+ var json;
+ request_json = '{"seq":0,"type":"request","command":"scopes"}'
+ var response_json = dcp.processDebugJSONRequest(request_json);
+ var response = JSON.parse(response_json);
+ assertEquals(scopes.length, response.body.scopes.length);
+ for (var i = 0; i < scopes.length; i++) {
+ assertEquals(i, response.body.scopes[i].index);
+ assertEquals(scopes[i], response.body.scopes[i].type);
+ if (scopes[i] == debug.ScopeType.Local ||
+ scopes[i] == debug.ScopeType.Closure) {
+ assertTrue(response.body.scopes[i].object.ref < 0);
+ } else {
+ assertTrue(response.body.scopes[i].object.ref >= 0);
+ }
+ var found = false;
+ for (var j = 0; j < response.refs.length && !found; j++) {
+ found = response.refs[j].handle == response.body.scopes[i].object.ref;
+ }
+ assertTrue(found, "Scope object " + response.body.scopes[i].object.ref + " not found");
+ }
+}
+
+
+// Check that the content of the scope is as expected. For functions just check
+// that there is a function.
+function CheckScopeContent(content, number, exec_state) {
+ var scope = exec_state.frame().scope(number)
+ var count = 0;
+ for (var p in content) {
+ var property_mirror = scope.scopeObject().property(p);
+ assertFalse(property_mirror.isUndefined(), 'property ' + p + ' not found in scope');
+ if (typeof(content[p]) === 'function') {
+ assertTrue(property_mirror.value().isFunction());
+ } else {
+ assertEquals(content[p], property_mirror.value().value(), 'property ' + p + ' has unexpected value');
+ }
+ count++;
+ }
+
+ // 'arguments' and might be exposed in the local and closure scope. Just
+ // ignore this.
+ var scope_size = scope.scopeObject().properties().length;
+ if (!scope.scopeObject().property('arguments').isUndefined()) {
+ scope_size--;
+ }
+ if (count != scope_size) {
+ print('Names found in scope:');
+ var names = scope.scopeObject().propertyNames();
+ for (var i = 0; i < names.length; i++) {
+ print(names[i]);
+ }
+ }
+ assertEquals(count, scope_size);
+
+ // Get the debug command processor.
+ var dcp = exec_state.debugCommandProcessor();
+
+ // Send a scope request for information on a single scope and check the
+ // result.
+ request_json = '{"seq":0,"type":"request","command":"scope","arguments":{"number":'
+ request_json += scope.scopeIndex();
+ request_json += '}}'
+ var response_json = dcp.processDebugJSONRequest(request_json);
+ var response = JSON.parse(response_json);
+ assertEquals(scope.scopeType(), response.body.type);
+ assertEquals(number, response.body.index);
+ if (scope.scopeType() == debug.ScopeType.Local ||
+ scope.scopeType() == debug.ScopeType.Closure) {
+ assertTrue(response.body.object.ref < 0);
+ } else {
+ assertTrue(response.body.object.ref >= 0);
+ }
+ var found = false;
+ for (var i = 0; i < response.refs.length && !found; i++) {
+ found = response.refs[i].handle == response.body.object.ref;
+ }
+ assertTrue(found, "Scope object " + response.body.object.ref + " not found");
+}
+
+
+// Simple empty local scope.
+BeginTest("Local 1");
+
+function local_1() {
+ debugger;
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({}, 0, exec_state);
+}
+local_1()
+EndTest();
+
+
+// Local scope with a parameter.
+BeginTest("Local 2");
+
+function local_2(a) {
+ debugger;
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1}, 0, exec_state);
+}
+local_2(1)
+EndTest();
+
+
+// Local scope with a parameter and a local variable.
+BeginTest("Local 3");
+
+function local_3(a) {
+ var x = 3;
+ debugger;
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,x:3}, 0, exec_state);
+}
+local_3(1)
+EndTest();
+
+
+// Local scope with parameters and local variables.
+BeginTest("Local 4");
+
+function local_4(a, b) {
+ var x = 3;
+ var y = 4;
+ debugger;
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
+}
+local_4(1, 2)
+EndTest();
+
+
+// Empty local scope with use of eval.
+BeginTest("Local 5");
+
+function local_5() {
+ eval('');
+ debugger;
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({}, 0, exec_state);
+}
+local_5()
+EndTest();
+
+
+// Local introducing local variable using eval.
+BeginTest("Local 6");
+
+function local_6() {
+ eval('var i = 5');
+ debugger;
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({i:5}, 0, exec_state);
+}
+local_6()
+EndTest();
+
+
+// Local scope with parameters, local variables and local variable introduced
+// using eval.
+BeginTest("Local 7");
+
+function local_7(a, b) {
+ var x = 3;
+ var y = 4;
+ eval('var i = 5');
+ eval('var j = 6');
+ debugger;
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state);
+}
+local_7(1, 2)
+EndTest();
+
+
+// Single empty with block.
+BeginTest("With 1");
+
+function with_1() {
+ with({}) {
+ debugger;
+ }
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.With,
+ debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({}, 0, exec_state);
+}
+with_1()
+EndTest();
+
+
+// Nested empty with blocks.
+BeginTest("With 2");
+
+function with_2() {
+ with({}) {
+ with({}) {
+ debugger;
+ }
+ }
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.With,
+ debug.ScopeType.With,
+ debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({}, 0, exec_state);
+ CheckScopeContent({}, 1, exec_state);
+}
+with_2()
+EndTest();
+
+
+// With block using an in-place object literal.
+BeginTest("With 3");
+
+function with_3() {
+ with({a:1,b:2}) {
+ debugger;
+ }
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.With,
+ debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,b:2}, 0, exec_state);
+}
+with_3()
+EndTest();
+
+
+// Nested with blocks using in-place object literals.
+BeginTest("With 4");
+
+function with_4() {
+ with({a:1,b:2}) {
+ with({a:2,b:1}) {
+ debugger;
+ }
+ }
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.With,
+ debug.ScopeType.With,
+ debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:2,b:1}, 0, exec_state);
+ CheckScopeContent({a:1,b:2}, 1, exec_state);
+}
+with_4()
+EndTest();
+
+
+// Nested with blocks using existing object.
+BeginTest("With 5");
+
+var with_object = {c:3,d:4};
+function with_5() {
+ with(with_object) {
+ with(with_object) {
+ debugger;
+ }
+ }
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.With,
+ debug.ScopeType.With,
+ debug.ScopeType.Local,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent(with_object, 0, exec_state);
+ CheckScopeContent(with_object, 1, exec_state);
+ assertEquals(exec_state.frame().scope(0).scopeObject(), exec_state.frame().scope(1).scopeObject());
+ assertEquals(with_object, exec_state.frame().scope(1).scopeObject().value());
+}
+with_5()
+EndTest();
+
+
+// Simple closure formed by returning an inner function referering the outer
+// functions arguments.
+BeginTest("Closure 1");
+
+function closure_1(a) {
+ function f() {
+ debugger;
+ return a;
+ };
+ return f;
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1}, 1, exec_state);
+}
+closure_1(1)()
+EndTest();
+
+
+// Simple closure formed by returning an inner function referering the outer
+// functions arguments. Due to VM optimizations parts of the actual closure is
+// missing from the debugger information.
+BeginTest("Closure 2");
+
+function closure_2(a, b) {
+ var x = a + 2;
+ var y = b + 2;
+ function f() {
+ debugger;
+ return a + x;
+ };
+ return f;
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,x:3}, 1, exec_state);
+}
+closure_2(1, 2)()
+EndTest();
+
+
+// Simple closure formed by returning an inner function referering the outer
+// functions arguments. Using all arguments and locals from the outer function
+// in the inner function makes these part of the debugger information on the
+// closure.
+BeginTest("Closure 3");
+
+function closure_3(a, b) {
+ var x = a + 2;
+ var y = b + 2;
+ function f() {
+ debugger;
+ return a + b + x + y;
+ };
+ return f;
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state);
+}
+closure_3(1, 2)()
+EndTest();
+
+
+
+// Simple closure formed by returning an inner function referering the outer
+// functions arguments. Using all arguments and locals from the outer function
+// in the inner function makes these part of the debugger information on the
+// closure. Use the inner function as well...
+BeginTest("Closure 4");
+
+function closure_4(a, b) {
+ var x = a + 2;
+ var y = b + 2;
+ function f() {
+ debugger;
+ if (f) {
+ return a + b + x + y;
+ }
+ };
+ return f;
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state);
+}
+closure_4(1, 2)()
+EndTest();
+
+
+
+// Simple closure formed by returning an inner function referering the outer
+// functions arguments. In the presence of eval all arguments and locals
+// (including the inner function itself) from the outer function becomes part of
+// the debugger infformation on the closure.
+BeginTest("Closure 5");
+
+function closure_5(a, b) {
+ var x = 3;
+ var y = 4;
+ function f() {
+ eval('');
+ debugger;
+ return 1;
+ };
+ return f;
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state);
+}
+closure_5(1, 2)()
+EndTest();
+
+
+// Two closures. Due to optimizations only the parts actually used are provided
+// through the debugger information.
+BeginTest("Closure 6");
+function closure_6(a, b) {
+ function f(a, b) {
+ var x = 3;
+ var y = 4;
+ return function() {
+ var x = 3;
+ var y = 4;
+ debugger;
+ some_global = a;
+ return f;
+ }
+ }
+ return f(a, b);
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({a:1}, 1, exec_state);
+ CheckScopeContent({f:function(){}}, 2, exec_state);
+}
+closure_6(1, 2)()
+EndTest();
+
+
+// Two closures. In the presence of eval all information is provided as the
+// compiler cannot determine which parts are used.
+BeginTest("Closure 7");
+function closure_7(a, b) {
+ var x = 3;
+ var y = 4;
+ eval('var i = 5');
+ eval('var j = 6');
+ function f(a, b) {
+ var x = 3;
+ var y = 4;
+ eval('var i = 5');
+ eval('var j = 6');
+ return function() {
+ debugger;
+ some_global = a;
+ return f;
+ }
+ }
+ return f(a, b);
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Local,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({}, 0, exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 1, exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 2, exec_state);
+}
+closure_7(1, 2)()
+EndTest();
+
+
+// Test a mixture of scopes.
+BeginTest("The full monty");
+function the_full_monty(a, b) {
+ var x = 3;
+ var y = 4;
+ eval('var i = 5');
+ eval('var j = 6');
+ function f(a, b) {
+ var x = 9;
+ var y = 10;
+ eval('var i = 11');
+ eval('var j = 12');
+ with ({j:13}){
+ return function() {
+ var x = 14;
+ with ({a:15}) {
+ with ({b:16}) {
+ debugger;
+ some_global = a;
+ return f;
+ }
+ }
+ }
+ }
+ }
+ return f(a, b);
+}
+
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.With,
+ debug.ScopeType.With,
+ debug.ScopeType.Local,
+ debug.ScopeType.With,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Closure,
+ debug.ScopeType.Global], exec_state);
+ CheckScopeContent({b:16}, 0, exec_state);
+ CheckScopeContent({a:15}, 1, exec_state);
+ CheckScopeContent({x:14}, 2, exec_state);
+ CheckScopeContent({j:13}, 3, exec_state);
+ CheckScopeContent({a:1,b:2,x:9,y:10,i:11,j:12}, 4, exec_state);
+ CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6,f:function(){}}, 5, exec_state);
+}
+the_full_monty(1, 2)()
+EndTest();
+
+// Test global scope.
+BeginTest("Global");
+listener_delegate = function(exec_state) {
+ CheckScopeChain([debug.ScopeType.Global], exec_state);
+}
+debugger;
+EndTest();
+
+assertEquals(begin_test_count, break_count, 'one or more tests did not enter the debugger');
+assertEquals(begin_test_count, end_test_count, 'one or more tests did not have its result checked');
diff --git a/test/mjsunit/debug-sourceinfo.js b/test/mjsunit/debug-sourceinfo.js
index 36e9f03..b62a742 100644
--- a/test/mjsunit/debug-sourceinfo.js
+++ b/test/mjsunit/debug-sourceinfo.js
@@ -38,6 +38,23 @@
return 1;
}
};
+function d(x) {
+ x = 1 ;
+ x = 2 ;
+ x = 3 ;
+ x = 4 ;
+ x = 5 ;
+ x = 6 ;
+ x = 7 ;
+ x = 8 ;
+ x = 9 ;
+ x = 10;
+ x = 11;
+ x = 12;
+ x = 13;
+ x = 14;
+ x = 15;
+}
// Get the Debug object exposed from the debug context global object.
Debug = debug.Debug
@@ -45,22 +62,42 @@
// This is the number of comment lines above the first test function.
var comment_lines = 29;
+// This is the last position in the entire file (note: this equals
+// file size of <debug-sourceinfo.js> - 1, since starting at 0).
+var last_position = 14072;
+// This is the last line of entire file (note: starting at 0).
+var last_line = 345;
+// This is the last column of last line (note: starting at 0 and +2, due
+// to trailing <CR><LF>).
+var last_column = 48;
+
// This magic number is the length or the first line comment (actually number
// of characters before 'function a(...'.
var comment_line_length = 1726;
var start_a = 10 + comment_line_length;
var start_b = 37 + comment_line_length;
var start_c = 71 + comment_line_length;
+var start_d = 163 + comment_line_length;
+
+// The position of the first line of d(), i.e. "x = 1 ;".
+var start_code_d = start_d + 7;
+// The line # of the first line of d() (note: starting at 0).
+var start_line_d = 41;
+var line_length_d = 11;
+var num_lines_d = 15;
assertEquals(start_a, Debug.sourcePosition(a));
assertEquals(start_b, Debug.sourcePosition(b));
assertEquals(start_c, Debug.sourcePosition(c));
+assertEquals(start_d, Debug.sourcePosition(d));
var script = Debug.findScript(a);
assertTrue(script.data === Debug.findScript(b).data);
assertTrue(script.data === Debug.findScript(c).data);
+assertTrue(script.data === Debug.findScript(d).data);
assertTrue(script.source === Debug.findScript(b).source);
assertTrue(script.source === Debug.findScript(c).source);
+assertTrue(script.source === Debug.findScript(d).source);
// Test that when running through source positions the position, line and
// column progresses as expected.
@@ -89,6 +126,19 @@
column = location.column;
}
+// Every line of d() is the same length. Verify we can loop through all
+// positions and find the right line # for each.
+var p = start_code_d;
+for (line = 0; line < num_lines_d; line++) {
+ for (column = 0; column < line_length_d; column++) {
+ var location = script.locationFromPosition(p);
+ assertEquals(p, location.position);
+ assertEquals(start_line_d + line, location.line);
+ assertEquals(column, location.column);
+ p++;
+ }
+}
+
// Test first position.
assertEquals(0, script.locationFromPosition(0).position);
assertEquals(0, script.locationFromPosition(0).line);
@@ -99,21 +149,26 @@
assertEquals(0, script.locationFromPosition(1).line);
assertEquals(1, script.locationFromPosition(1).column);
-// Test first position in finction a.
+// Test first position in function a().
assertEquals(start_a, script.locationFromPosition(start_a).position);
assertEquals(0, script.locationFromPosition(start_a).line - comment_lines);
assertEquals(10, script.locationFromPosition(start_a).column);
-// Test first position in finction b.
+// Test first position in function b().
assertEquals(start_b, script.locationFromPosition(start_b).position);
assertEquals(1, script.locationFromPosition(start_b).line - comment_lines);
assertEquals(13, script.locationFromPosition(start_b).column);
-// Test first position in finction b.
+// Test first position in function c().
assertEquals(start_c, script.locationFromPosition(start_c).position);
assertEquals(4, script.locationFromPosition(start_c).line - comment_lines);
assertEquals(12, script.locationFromPosition(start_c).column);
+// Test first position in function d().
+assertEquals(start_d, script.locationFromPosition(start_d).position);
+assertEquals(11, script.locationFromPosition(start_d).line - comment_lines);
+assertEquals(10, script.locationFromPosition(start_d).column);
+
// Test first line.
assertEquals(0, script.locationFromLine().position);
assertEquals(0, script.locationFromLine().line);
@@ -122,17 +177,17 @@
assertEquals(0, script.locationFromLine(0).line);
assertEquals(0, script.locationFromLine(0).column);
-// Test first line column 1
+// Test first line column 1.
assertEquals(1, script.locationFromLine(0, 1).position);
assertEquals(0, script.locationFromLine(0, 1).line);
assertEquals(1, script.locationFromLine(0, 1).column);
-// Test first line offset 1
+// Test first line offset 1.
assertEquals(1, script.locationFromLine(0, 0, 1).position);
assertEquals(0, script.locationFromLine(0, 0, 1).line);
assertEquals(1, script.locationFromLine(0, 0, 1).column);
-// Test offset function a
+// Test offset function a().
assertEquals(start_a, script.locationFromLine(void 0, void 0, start_a).position);
assertEquals(0, script.locationFromLine(void 0, void 0, start_a).line - comment_lines);
assertEquals(10, script.locationFromLine(void 0, void 0, start_a).column);
@@ -143,27 +198,27 @@
assertEquals(0, script.locationFromLine(0, 0, start_a).line - comment_lines);
assertEquals(10, script.locationFromLine(0, 0, start_a).column);
-// Test second line offset function a
+// Test second line offset function a().
assertEquals(start_a + 14, script.locationFromLine(1, 0, start_a).position);
assertEquals(1, script.locationFromLine(1, 0, start_a).line - comment_lines);
assertEquals(0, script.locationFromLine(1, 0, start_a).column);
-// Test second line column 2 offset function a
+// Test second line column 2 offset function a().
assertEquals(start_a + 14 + 2, script.locationFromLine(1, 2, start_a).position);
assertEquals(1, script.locationFromLine(1, 2, start_a).line - comment_lines);
assertEquals(2, script.locationFromLine(1, 2, start_a).column);
-// Test offset function b
+// Test offset function b().
assertEquals(start_b, script.locationFromLine(0, 0, start_b).position);
assertEquals(1, script.locationFromLine(0, 0, start_b).line - comment_lines);
assertEquals(13, script.locationFromLine(0, 0, start_b).column);
-// Test second line offset function b
+// Test second line offset function b().
assertEquals(start_b + 6, script.locationFromLine(1, 0, start_b).position);
assertEquals(2, script.locationFromLine(1, 0, start_b).line - comment_lines);
assertEquals(0, script.locationFromLine(1, 0, start_b).column);
-// Test second line column 11 offset function b
+// Test second line column 11 offset function b().
assertEquals(start_b + 6 + 11, script.locationFromLine(1, 11, start_b).position);
assertEquals(2, script.locationFromLine(1, 11, start_b).line - comment_lines);
assertEquals(11, script.locationFromLine(1, 11, start_b).column);
@@ -187,6 +242,21 @@
assertEquals(52 + start_c, Debug.findFunctionSourceLocation(c, 4, 0).position);
assertEquals(69 + start_c, Debug.findFunctionSourceLocation(c, 5, 0).position);
assertEquals(76 + start_c, Debug.findFunctionSourceLocation(c, 6, 0).position);
+assertEquals(0 + start_d, Debug.findFunctionSourceLocation(d, 0, 0).position);
+assertEquals(7 + start_d, Debug.findFunctionSourceLocation(d, 1, 0).position);
+for (i = 1; i <= num_lines_d; i++) {
+ assertEquals(7 + (i * line_length_d) + start_d, Debug.findFunctionSourceLocation(d, (i + 1), 0).position);
+}
+assertEquals(175 + start_d, Debug.findFunctionSourceLocation(d, 17, 0).position);
+
+// Make sure invalid inputs work properly.
+assertEquals(0, script.locationFromPosition(-1).line);
+assertEquals(null, script.locationFromPosition(last_position + 1));
+
+// Test last position.
+assertEquals(last_position, script.locationFromPosition(last_position).position);
+assertEquals(last_line, script.locationFromPosition(last_position).line);
+assertEquals(last_column, script.locationFromPosition(last_position).column);
// Test source line and restriction. All the following tests start from line 1
// column 2 in function b, which is the call to c.
diff --git a/test/mjsunit/sin-cos.js b/test/mjsunit/sin-cos.js
new file mode 100644
index 0000000..ae02451
--- /dev/null
+++ b/test/mjsunit/sin-cos.js
@@ -0,0 +1,45 @@
+// Copyright 2009 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.
+
+// Test Math.sin and Math.cos.
+
+var input_sin = [0, Math.PI / 2];
+var input_cos = [0, Math.PI];
+
+var output_sin = input_sin.map(Math.sin);
+var output_cos = input_cos.map(Math.cos);
+
+var expected_sin = [0, 1];
+var expected_cos = [1, -1];
+
+assertArrayEquals(expected_sin, output_sin, "sine");
+assertArrayEquals(expected_cos, output_cos, "cosine");
+
+// By accident, the slow case for sine and cosine were both sine at
+// some point. This is a regression test for that issue.
+var x = Math.pow(2, 70);
+assertTrue(Math.sin(x) != Math.cos(x));