| OLD | NEW |
| 1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 | 42 |
| 43 function TestLocal(s,e) { | 43 function TestLocal(s,e) { |
| 44 try { | 44 try { |
| 45 return eval("(function(){" + s + ";return " + e + "})")(); | 45 return eval("(function(){" + s + ";return " + e + "})")(); |
| 46 } catch (x) { | 46 } catch (x) { |
| 47 return CheckException(x); | 47 return CheckException(x); |
| 48 } | 48 } |
| 49 } | 49 } |
| 50 | 50 |
| 51 | 51 |
| 52 // NOTE: TestGlobal usually only tests the given string in the context | |
| 53 // of a global object in dictionary mode. This is because we use | |
| 54 // delete to get rid of any added properties. | |
| 55 function TestGlobal(s,e) { | |
| 56 // Collect the global properties before the call. | |
| 57 var properties = []; | |
| 58 for (var key in this) properties.push(key); | |
| 59 // Compute the result. | |
| 60 var result; | |
| 61 try { | |
| 62 var code = s + (e ? "; $$$result=" + e : ""); | |
| 63 if (this.execScript) { | |
| 64 execScript(code); | |
| 65 } else { | |
| 66 this.eval(code); | |
| 67 } | |
| 68 // Avoid issues if $$$result is not defined by | |
| 69 // reading it through this. | |
| 70 result = this.$$$result; | |
| 71 } catch (x) { | |
| 72 result = CheckException(x); | |
| 73 } | |
| 74 // Get rid of any introduced global properties before | |
| 75 // returning the result. | |
| 76 for (var key in this) { | |
| 77 if (properties.indexOf(key) == -1) delete this[key]; | |
| 78 } | |
| 79 return result; | |
| 80 } | |
| 81 | |
| 82 | |
| 83 function TestContext(s,e) { | 52 function TestContext(s,e) { |
| 84 try { | 53 try { |
| 85 // Use a with-statement to force the system to do dynamic | 54 // Use a with-statement to force the system to do dynamic |
| 86 // declarations of the introduced variables or constants. | 55 // declarations of the introduced variables or constants. |
| 87 with ({}) { | 56 with ({}) { |
| 88 return eval(s + ";" + e); | 57 return eval(s + ";" + e); |
| 89 } | 58 } |
| 90 } catch (x) { | 59 } catch (x) { |
| 91 return CheckException(x); | 60 return CheckException(x); |
| 92 } | 61 } |
| 93 } | 62 } |
| 94 | 63 |
| 95 | 64 |
| 96 function TestAll(expected,s,opt_e) { | 65 function TestAll(expected,s,opt_e) { |
| 97 var e = ""; | 66 var e = ""; |
| 98 var msg = s; | 67 var msg = s; |
| 99 if (opt_e) { e = opt_e; msg += "; " + opt_e; } | 68 if (opt_e) { e = opt_e; msg += "; " + opt_e; } |
| 100 assertEquals(expected, TestLocal(s,e), "local:'" + msg + "'"); | 69 assertEquals(expected, TestLocal(s,e), "local:'" + msg + "'"); |
| 101 // Redeclarations of global consts do not throw, they are silently ignored. | |
| 102 assertEquals(42, TestGlobal(s, 42), "global:'" + msg + "'"); | |
| 103 assertEquals(expected, TestContext(s,e), "context:'" + msg + "'"); | 70 assertEquals(expected, TestContext(s,e), "context:'" + msg + "'"); |
| 104 } | 71 } |
| 105 | 72 |
| 106 | 73 |
| 107 function TestConflict(def0, def1) { | 74 function TestConflict(def0, def1) { |
| 108 // No eval. | 75 // No eval. |
| 109 TestAll("TypeError", def0 +'; ' + def1); | 76 TestAll("TypeError", def0 +'; ' + def1); |
| 110 // Eval everything. | 77 // Eval everything. |
| 111 TestAll("TypeError", 'eval("' + def0 + '; ' + def1 + '")'); | 78 TestAll("TypeError", 'eval("' + def0 + '; ' + def1 + '")'); |
| 112 // Eval first definition. | 79 // Eval first definition. |
| 113 TestAll("TypeError", 'eval("' + def0 +'"); ' + def1); | 80 TestAll("TypeError", 'eval("' + def0 +'"); ' + def1); |
| 114 // Eval second definition. | 81 // Eval second definition. |
| 115 TestAll("TypeError", def0 + '; eval("' + def1 + '")'); | 82 TestAll("TypeError", def0 + '; eval("' + def1 +'")'); |
| 116 // Eval both definitions separately. | 83 // Eval both definitions separately. |
| 117 TestAll("TypeError", 'eval("' + def0 +'"); eval("' + def1 + '")'); | 84 TestAll("TypeError", 'eval("' + def0 +'"); eval("' + def1 + '")'); |
| 118 } | 85 } |
| 119 | 86 |
| 120 | 87 |
| 121 // Test conflicting definitions. | 88 // Test conflicting definitions. |
| 122 TestConflict("const x", "var x"); | 89 TestConflict("const x", "var x"); |
| 123 TestConflict("const x = 0", "var x"); | 90 TestConflict("const x = 0", "var x"); |
| 124 TestConflict("const x", "var x = 0"); | 91 TestConflict("const x", "var x = 0"); |
| 125 TestConflict("const x = 0", "var x = 0"); | 92 TestConflict("const x = 0", "var x = 0"); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 eval("var undefined;"); | 194 eval("var undefined;"); |
| 228 } catch (ex) { | 195 } catch (ex) { |
| 229 assertUnreachable("undefined (1) has thrown"); | 196 assertUnreachable("undefined (1) has thrown"); |
| 230 } | 197 } |
| 231 | 198 |
| 232 var original_undef = undefined; | 199 var original_undef = undefined; |
| 233 var undefined = 1; // Should be silently ignored. | 200 var undefined = 1; // Should be silently ignored. |
| 234 assertEquals(original_undef, undefined, "undefined got overwritten"); | 201 assertEquals(original_undef, undefined, "undefined got overwritten"); |
| 235 undefined = original_undef; | 202 undefined = original_undef; |
| 236 | 203 |
| 237 var a; const a; const a = 1; | 204 const e = 1; eval('var e = 2'); |
| 238 assertEquals(1, a, "a has wrong value"); | |
| 239 a = 2; | |
| 240 assertEquals(2, a, "a should be writable"); | |
| 241 | |
| 242 var b = 1; const b = 2; | |
| 243 assertEquals(2, b, "b has wrong value"); | |
| 244 | |
| 245 var c = 1; const c = 2; const c = 3; | |
| 246 assertEquals(3, c, "c has wrong value"); | |
| 247 | |
| 248 const d = 1; const d = 2; | |
| 249 assertEquals(1, d, "d has wrong value"); | |
| 250 | |
| 251 const e = 1; var e = 2; | |
| 252 assertEquals(1, e, "e has wrong value"); | 205 assertEquals(1, e, "e has wrong value"); |
| 253 | 206 |
| 254 const f = 1; const f; | 207 const h; eval('var h = 1'); |
| 255 assertEquals(1, f, "f has wrong value"); | 208 assertEquals(undefined, h, "h has wrong value"); |
| 256 | |
| 257 var g; const g = 1; | |
| 258 assertEquals(1, g, "g has wrong value"); | |
| 259 g = 2; | |
| 260 assertEquals(2, g, "g should be writable"); | |
| 261 | |
| 262 const h; var h = 1; | |
| 263 assertEquals(undefined,h, "h has wrong value"); | |
| 264 | 209 |
| 265 eval("Object.defineProperty(this, 'i', { writable: true });" | 210 eval("Object.defineProperty(this, 'i', { writable: true });" |
| 266 + "const i = 7;" | 211 + "const i = 7;" |
| 267 + "assertEquals(7, i, \"i has wrong value\");"); | 212 + "assertEquals(7, i, \"i has wrong value\");"); |
| 268 | 213 |
| 269 var global = this; | 214 var global = this; |
| 270 assertThrows(function() { | 215 Object.defineProperty(global, 'j', { value: 100, writable: true }); |
| 271 Object.defineProperty(global, 'j', { writable: true }) | 216 assertEquals(100, j); |
| 272 }, TypeError); | 217 // The const declaration stays configurable, so the declaration above goes |
| 273 const j = 2; // This is what makes the function above throw, because the | 218 // through even though the const declaration is hoisted above. |
| 274 // const declaration gets hoisted and makes the property non-configurable. | 219 const j = 2; |
| 275 assertEquals(2, j, "j has wrong value"); | 220 assertEquals(2, j, "j has wrong value"); |
| 276 | 221 |
| 277 var k = 1; const k; | 222 var k = 1; |
| 278 // You could argue about the expected result here. For now, the winning | 223 try { eval('const k'); } catch(e) { } |
| 279 // argument is that "const k;" is equivalent to "const k = undefined;". | 224 assertEquals(1, k, "k has wrong value"); |
| 280 assertEquals(undefined, k, "k has wrong value"); | 225 try { eval('const k = 10'); } catch(e) { } |
| 226 assertEquals(1, k, "k has wrong value"); |
| OLD | NEW |