Left: | ||
Right: |
OLD | NEW |
---|---|
1 // Copyright (C) 2011 Google Inc. | 1 // Copyright (C) 2011 Google Inc. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
177 * Given the sourceText for a strict Program, | 177 * Given the sourceText for a strict Program, |
178 * atLeastFreeVarNames(sourceText) returns a Record whose | 178 * atLeastFreeVarNames(sourceText) returns a Record whose |
179 * enumerable own property names must include the names of all the | 179 * enumerable own property names must include the names of all the |
180 * free variables occuring in sourceText. It can include as | 180 * free variables occuring in sourceText. It can include as |
181 * many other strings as is convenient so long as it includes | 181 * many other strings as is convenient so long as it includes |
182 * these. The value of each of these properties should be | 182 * these. The value of each of these properties should be |
183 * {@code true}. TODO(erights): On platforms with Proxies | 183 * {@code true}. TODO(erights): On platforms with Proxies |
184 * (currently only Firefox 4 and after), use {@code | 184 * (currently only Firefox 4 and after), use {@code |
185 * with(aProxy) {...}} to intercept free variables rather than | 185 * with(aProxy) {...}} to intercept free variables rather than |
186 * atLeastFreeVarNames. | 186 * atLeastFreeVarNames. |
187 * @param opt_mitigateGotchas ::F([string], Record(any)) | undefined | |
188 * Given the sourceText for a strict Program, if provided, | |
189 * opt_mitigateGotchas(sourceText, options) returns rewritten | |
190 * program with the same semantics as the original but with as | |
191 * many of the gotchas removed as possible. {@code options} is | |
192 * a record of which gotcha-rewriting-stages to use or omit. | |
193 * Passing no option performs the default. | |
187 * @param extensions ::F([], Record(any)]) A function returning a | 194 * @param extensions ::F([], Record(any)]) A function returning a |
188 * record whose own properties will be copied onto cajaVM. This | 195 * record whose own properties will be copied onto cajaVM. This |
189 * is used for the optional components which bring SES to | 196 * is used for the optional components which bring SES to |
190 * feature parity with the ES5/3 runtime at the price of larger | 197 * feature parity with the ES5/3 runtime at the price of larger |
191 * code size. At the time that {@code startSES} calls {@code | 198 * code size. At the time that {@code startSES} calls {@code |
192 * extensions}, {@code cajaVM} exists but should not yet be | 199 * extensions}, {@code cajaVM} exists but should not yet be |
193 * used. In particular, {@code extensions} should not call | 200 * used. In particular, {@code extensions} should not call |
194 * {@code cajaVM.def} during this setup, because def would then | 201 * {@code cajaVM.def} during this setup, because def would then |
195 * freeze priordials before startSES cleans them (removes | 202 * freeze priordials before startSES cleans them (removes |
196 * non-whitelisted properties). The methods that | 203 * non-whitelisted properties). The methods that |
197 * {@code extensions} contributes can, of course, use | 204 * {@code extensions} contributes can, of course, use |
198 * {@code cajaVM}, since those methods will only be called once | 205 * {@code cajaVM}, since those methods will only be called once |
199 * {@code startSES} finishes. | 206 * {@code startSES} finishes. |
200 */ | 207 */ |
201 ses.startSES = function(global, | 208 ses.startSES = function(global, |
202 whitelist, | 209 whitelist, |
203 atLeastFreeVarNames, | 210 atLeastFreeVarNames, |
211 opt_mitigateGotchas, | |
204 extensions) { | 212 extensions) { |
205 "use strict"; | 213 "use strict"; |
206 | 214 |
207 /////////////// KLUDGE SWITCHES /////////////// | 215 /////////////// KLUDGE SWITCHES /////////////// |
208 | 216 |
209 ///////////////////////////////// | 217 ///////////////////////////////// |
210 // The following are only the minimal kludges needed for the current | 218 // The following are only the minimal kludges needed for the current |
211 // Firefox or the current Chrome Beta. At the time of | 219 // Firefox or the current Chrome Beta. At the time of |
212 // this writing, these are Firefox 4.0 and Chrome 12.0.742.5 dev | 220 // this writing, these are Firefox 4.0 and Chrome 12.0.742.5 dev |
213 // As these move forward, kludges can be removed until we simply | 221 // As these move forward, kludges can be removed until we simply |
(...skipping 28 matching lines...) Expand all Loading... | |
242 | 250 |
243 var hop = Object.prototype.hasOwnProperty; | 251 var hop = Object.prototype.hasOwnProperty; |
244 | 252 |
245 var getProto = Object.getPrototypeOf; | 253 var getProto = Object.getPrototypeOf; |
246 var defProp = Object.defineProperty; | 254 var defProp = Object.defineProperty; |
247 var gopd = Object.getOwnPropertyDescriptor; | 255 var gopd = Object.getOwnPropertyDescriptor; |
248 var gopn = Object.getOwnPropertyNames; | 256 var gopn = Object.getOwnPropertyNames; |
249 var keys = Object.keys; | 257 var keys = Object.keys; |
250 var freeze = Object.freeze; | 258 var freeze = Object.freeze; |
251 var create = Object.create; | 259 var create = Object.create; |
260 var mitigateGotchas = opt_mitigateGotchas || function (s) { return '' + s; }; | |
252 | 261 |
253 /** | 262 /** |
254 * Use to tamper proof a function which is not intended to ever be | 263 * Use to tamper proof a function which is not intended to ever be |
255 * used as a constructor, since it nulls out the function's | 264 * used as a constructor, since it nulls out the function's |
256 * prototype first. | 265 * prototype first. |
257 */ | 266 */ |
258 function constFunc(func) { | 267 function constFunc(func) { |
259 func.prototype = null; | 268 func.prototype = null; |
260 return freeze(func); | 269 return freeze(func); |
261 } | 270 } |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
525 } | 534 } |
526 // if it were possible to know that the getter call was on | 535 // if it were possible to know that the getter call was on |
527 // behalf of a typeof expression, we'd return the string | 536 // behalf of a typeof expression, we'd return the string |
528 // "undefined" here instead. Unfortunately, without | 537 // "undefined" here instead. Unfortunately, without |
529 // parsing or proxies, that isn't possible. | 538 // parsing or proxies, that isn't possible. |
530 throw new ReferenceError('"' + name + '" blocked by Caja'); | 539 throw new ReferenceError('"' + name + '" blocked by Caja'); |
531 }, | 540 }, |
532 set: function scopedSet(newValue) { | 541 set: function scopedSet(newValue) { |
533 if (name in imports) { | 542 if (name in imports) { |
534 imports[name] = newValue; | 543 imports[name] = newValue; |
535 return newValue; | 544 return; |
536 } | 545 } |
537 throw new TypeError('Cannot set "' + name + '"'); | 546 throw new TypeError('Cannot set "' + name + '"'); |
538 }, | 547 }, |
539 enumerable: false | 548 enumerable: false |
540 }; | 549 }; |
541 } | 550 } |
542 desc.enumerable = false; | 551 desc.enumerable = false; |
543 defProp(scopeObject, name, desc); | 552 defProp(scopeObject, name, desc); |
544 }); | 553 }); |
545 return freeze(scopeObject); | 554 return freeze(scopeObject); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
620 * exprSrc} in a virtual global environment whose {@code this} is | 629 * exprSrc} in a virtual global environment whose {@code this} is |
621 * bound to that {@code imports}, and whose free variables | 630 * bound to that {@code imports}, and whose free variables |
622 * refer only to the properties of that {@code imports}. | 631 * refer only to the properties of that {@code imports}. |
623 * | 632 * |
624 * <p>When SES is provided primitively, it should provide an | 633 * <p>When SES is provided primitively, it should provide an |
625 * analogous {@code compileProgram} function that accepts a | 634 * analogous {@code compileProgram} function that accepts a |
626 * Program and return a function that evaluates it to the | 635 * Program and return a function that evaluates it to the |
627 * Program's completion value. Unfortunately, this is not | 636 * Program's completion value. Unfortunately, this is not |
628 * practical as a library without some non-standard support from | 637 * practical as a library without some non-standard support from |
629 * the platform such as a parser API that provides an AST. | 638 * the platform such as a parser API that provides an AST. |
639 * TODO(jasvir): Now that we're parsing, we can provide compileProgram. | |
630 * | 640 * |
631 * <p>Thanks to Mike Samuel and Ankur Taly for this trick of using | 641 * <p>Thanks to Mike Samuel and Ankur Taly for this trick of using |
632 * {@code with} together with RegExp matching to intercept free | 642 * {@code with} together with RegExp matching to intercept free |
633 * variable access without parsing. | 643 * variable access without parsing. |
634 */ | 644 */ |
635 function compileExpr(exprSrc, opt_sourcePosition) { | 645 function compileExpr(exprSrc, opt_sourcePosition) { |
646 exprSrc = mitigateGotchas(exprSrc); | |
647 if (exprSrc[exprSrc.length - 1] === ';') { | |
kpreid2
2013/01/02 18:59:16
Please add rationale comment.
*If* this is becaus
Jasvir
2013/01/02 19:42:59
Done.
| |
648 exprSrc = exprSrc.substr(0, exprSrc.length - 1); | |
649 } | |
636 var wrapperSrc = securableWrapperSrc(exprSrc, opt_sourcePosition); | 650 var wrapperSrc = securableWrapperSrc(exprSrc, opt_sourcePosition); |
637 var wrapper = unsafeEval(wrapperSrc); | 651 var wrapper = unsafeEval(wrapperSrc); |
638 var freeNames = atLeastFreeVarNames(exprSrc); | 652 var freeNames = atLeastFreeVarNames(exprSrc); |
639 var result = makeCompiledExpr(wrapper, freeNames); | 653 var result = makeCompiledExpr(wrapper, freeNames); |
640 return freeze(result); | 654 return freeze(result); |
641 } | 655 } |
642 | 656 |
643 | 657 |
644 var directivePattern = (/^['"](?:\w|\s)*['"]$/m); | 658 var directivePattern = (/^['"](?:\w|\s)*['"]$/m); |
645 | 659 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
695 * similarly recognize the {@code "load"} syntax of <a href= | 709 * similarly recognize the {@code "load"} syntax of <a href= |
696 * "http://wiki.ecmascript.org/doku.php?id=strawman:simple_modules#syntax" | 710 * "http://wiki.ecmascript.org/doku.php?id=strawman:simple_modules#syntax" |
697 * >Sam and Dave's module proposal for ES-Harmony</a>. However, | 711 * >Sam and Dave's module proposal for ES-Harmony</a>. However, |
698 * since browsers do not currently accept this syntax, | 712 * since browsers do not currently accept this syntax, |
699 * {@code getRequirements} above would also have to extract these | 713 * {@code getRequirements} above would also have to extract these |
700 * from the text to be compiled. | 714 * from the text to be compiled. |
701 */ | 715 */ |
702 function compileModule(modSrc, opt_sourcePosition) { | 716 function compileModule(modSrc, opt_sourcePosition) { |
703 // Note the EOL after modSrc to prevent trailing line comment in modSrc | 717 // Note the EOL after modSrc to prevent trailing line comment in modSrc |
704 // eliding the rest of the wrapper. | 718 // eliding the rest of the wrapper. |
705 var exprSrc = '(function() {' + modSrc + '\n}).call(this)'; | 719 var exprSrc = '(function() {' + mitigateGotchas(modSrc) + '\n}).call(this) '; |
kpreid2
2013/01/02 18:59:16
long line
Jasvir
2013/01/02 19:42:59
Done.
| |
706 | 720 |
707 // Follow the pattern in compileExpr | 721 // Follow the pattern in compileExpr |
708 var wrapperSrc = securableWrapperSrc(exprSrc, opt_sourcePosition); | 722 var wrapperSrc = securableWrapperSrc(exprSrc, opt_sourcePosition); |
709 var wrapper = unsafeEval(wrapperSrc); | 723 var wrapper = unsafeEval(wrapperSrc); |
710 var freeNames = atLeastFreeVarNames(exprSrc); | 724 var freeNames = atLeastFreeVarNames(exprSrc); |
711 var moduleMaker = makeCompiledExpr(wrapper, freeNames); | 725 var moduleMaker = makeCompiledExpr(wrapper, freeNames); |
712 | 726 |
713 moduleMaker.requirements = getRequirements(modSrc); | 727 moduleMaker.requirements = getRequirements(modSrc); |
714 return freeze(moduleMaker); | 728 return freeze(moduleMaker); |
715 } | 729 } |
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1313 ses.logger.reportMax(); | 1327 ses.logger.reportMax(); |
1314 | 1328 |
1315 if (ses.ok(ses['severities'][ses.maxAcceptableSeverityName])) { | 1329 if (ses.ok(ses['severities'][ses.maxAcceptableSeverityName])) { |
1316 // We succeeded. Enable safe Function, eval, and compile* to work. | 1330 // We succeeded. Enable safe Function, eval, and compile* to work. |
1317 dirty = false; | 1331 dirty = false; |
1318 ses.logger.log('initSES succeeded.'); | 1332 ses.logger.log('initSES succeeded.'); |
1319 } else { | 1333 } else { |
1320 ses.logger.error('initSES failed.'); | 1334 ses.logger.error('initSES failed.'); |
1321 } | 1335 } |
1322 }; | 1336 }; |
OLD | NEW |