Home | History | Annotate | Download | only in mjsunit
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 assertEquals(void 0, eval());
     29 assertEquals(4, eval(4));
     30 
     31 function f() { return 'The f function'; };
     32 assertTrue(f === eval(f));
     33 
     34 function g(x, y) { return 4; };
     35 
     36 count = 0;
     37 assertEquals(4, eval('2 + 2', count++));
     38 assertEquals(1, count);
     39 
     40 try {
     41   eval('hest 7 &*^*&^');
     42   assertUnreachable('Did not throw on syntax error.');
     43 } catch (e) {
     44   assertEquals('SyntaxError', e.name);
     45 }
     46 
     47 
     48 // eval has special evaluation order for consistency with other browsers.
     49 global_eval = eval;
     50 assertEquals(void 0, eval(eval("var eval = function f(x) { return 'hest';}")))
     51 eval = global_eval;
     52 
     53 // Test eval with different number of parameters.
     54 global_eval = eval;
     55 eval = function(x, y) { return x + y; };
     56 assertEquals(4, eval(2, 2));
     57 eval = global_eval;
     58 
     59 // Test that un-aliased eval reads from local context.
     60 foo = 0;
     61 result =
     62   (function() {
     63     var foo = 2;
     64     return eval('foo');
     65   })();
     66 assertEquals(2, result);
     67 
     68 // Test that un-aliased eval writes to local context.
     69 foo = 0;
     70 result =
     71   (function() {
     72     var foo = 1;
     73     eval('foo = 2');
     74     return foo;
     75   })();
     76 assertEquals(2, result);
     77 assertEquals(0, foo);
     78 
     79 // Test that un-aliased eval has right receiver.
     80 function MyObject() { this.self = eval('this'); }
     81 var o = new MyObject();
     82 assertTrue(o === o.self);
     83 
     84 // Test that aliased eval reads from global context.
     85 var e = eval;
     86 foo = 0;
     87 result =
     88   (function() {
     89     var foo = 2;
     90     return e('foo');
     91   })();
     92 assertEquals(0, result);
     93 
     94 // Test that aliased eval writes to global context.
     95 var e = eval;
     96 foo = 0;
     97 (function() { e('var foo = 2;'); })();
     98 assertEquals(2, foo);
     99 
    100 // Test that aliased eval has right receiver.
    101 function MyOtherObject() { this.self = e('this'); }
    102 var o = new MyOtherObject();
    103 assertTrue(this === o.self);
    104 
    105 // Try to cheat the 'aliased eval' detection.
    106 var x = this;
    107 foo = 0;
    108 result =
    109   (function() {
    110     var foo = 2;
    111     // Should be non-direct call.
    112     return x.eval('foo');
    113   })();
    114 assertEquals(0, result);
    115 
    116 foo = 0;
    117 result =
    118   (function() {
    119     var foo = 2;
    120     // Should be non-direct call.
    121     return (1,eval)('foo');
    122   })();
    123 assertEquals(0, result);
    124 
    125 foo = 0;
    126 result =
    127   (function() {
    128     var eval = function(x) { return x; };
    129     var foo = eval(2);
    130     // Should be non-direct call.
    131     return e('foo');
    132   })();
    133 assertEquals(0, result);
    134 
    135 foo = 0;
    136 result =
    137   (function() {
    138     var foo = 2;
    139     // Should be direct call.
    140     with ({ eval : e }) {
    141       return eval('foo');
    142     }
    143   })();
    144 assertEquals(2, result);
    145 
    146 result =
    147   (function() {
    148     var eval = function(x) { return 2 * x; };
    149     return (function() { return eval(2); })();
    150   })();
    151 assertEquals(4, result);
    152 
    153 result =
    154   (function() {
    155     eval("var eval = function(s) { return this; }");
    156     return eval("42");  // Should return the global object
    157   })();
    158 assertEquals(this, result);
    159 
    160 (function() {
    161   var obj = { f: function(eval) { return eval("this"); } };
    162   result = obj.f(eval);
    163   assertEquals(obj, result);
    164 })();
    165 
    166 (function() {
    167   var obj = { f: function(eval) { arguments; return eval("this"); } };
    168   result = obj.f(eval);
    169   assertEquals(obj, result);
    170 })();
    171 
    172 eval = function(x) { return 2 * x; };
    173 result =
    174   (function() {
    175     return (function() { return eval(2); })();
    176   })();
    177 assertEquals(4, result);
    178 
    179 
    180 
    181 
    182 // Regression test: calling a function named eval found in a context that is
    183 // not the global context should get the global object as receiver.
    184 result =
    185     (function () {
    186       var eval = function (x) { return this; };
    187       with ({}) { return eval('ignore'); }
    188     })();
    189 assertEquals(this, result);
    190