"no strict"; directive

# Andrea Giammarchi (12 years ago)

I wonder if there is any plan to allow a chunk of code to disable for its own closure purpose a previously called "use strict"; directive.

This is about the ability to use, when not possible otherwise, some good old feature such caller which is impossible to replicate when use strict is in place.

I am talking about arguments.callee, I am talking about caller.

This could be useful to plug-in on demand the possibility to debug or enhance possibilities through code considered harmful but actually absolutely necessary in certain circumstances ( included the with statement ).

I know it's not new that someone wrote "don't use strict"; somewhere ... but this is not funny anymore in certain projects that would like to be included even in a script which logic is entirely under "use strict"; directive ( plug-ins etc )

# Oliver Hunt (12 years ago)

On Nov 15, 2012, at 11:44 AM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

I wonder if there is any plan to allow a chunk of code to disable for its own closure purpose a previously called "use strict"; directive.

This is about the ability to use, when not possible otherwise, some good old feature such caller which is impossible to replicate when use strict is in place.

I am talking about arguments.callee, I am talking about caller.

arguments.callee and .caller are not good features.

Being able to access your caller is a misfeature.

arguments.callee is simply unnecessary.

Also having the ability to lose strict semantics at arbitrary locations in the middle of other strict modes makes things even slower, and adds all sorts of weird semantic behaviours (eg. what would eval('"no strict"; var x;') do? -- this is hypothetical, just given as a trivial example of where things go weird)

# Andrea Giammarchi (12 years ago)

my typo ... I am NOT talking about callee, I am talking about caller which is NOT a misfeature specially when it comes to debug and stack trace.

# Andrea Giammarchi (12 years ago)

gotcha about eval ... but indeed eval makes things slower in any case, right?

# Oliver Hunt (12 years ago)

On Nov 15, 2012, at 11:59 AM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

gotcha about eval ... but indeed eval makes things slower in any case, right?

I wasn't commenting on the performance of eval, i was providing (and I stated this explicitly) a trivial case where the semantics immediately become weird.

wrt performance: Analysis to enforce strict mode restrictions is inherently more expensive than non-strict mode, but the moment you start allowing arbitrary entering an exiting of strict mode you are adding more cost, and for what reason?

You have given two specific features, neither of which is good, and are willing to take every other misfeature of pre-strict JS in order to get them. If you want misfeatures that aren't available in strict mode, and are willing to have your code be non-strict, why are you entering strict mode in the first place?

# Oliver Hunt (12 years ago)

On Nov 15, 2012, at 11:58 AM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

my typo ... I am NOT talking about callee, I am talking about caller which is NOT a misfeature specially when it comes to debug and stack trace.

The solution to debugging is to use a debugger, not to try and debug from within the language.

All modern JS engines provide a) a debugger and b) stack traces on exceptions.

Even if they weren't .caller is insufficient: it can't walk over strict, native, or global code that exists in the call stack, so at best you only get a crappy result.

Like I said in my prior email: If you're willing to toss out the improvements of strict mode just to get arguments.caller, you may as well stop using it in the first place.

# Andrea Giammarchi (12 years ago)

the debugger you mention is most likely using the with statement ...

Can we just stick with the answer if it is planned or not? I don't want to convince you that there are cases where non strict features are needed ... it is just like that and many times already discussed.

The eval is a non issue, the script cannot be evaluated in any case ... an eval('"use strict"') is a destructive non sense regardless and it should simply throw an error. A Function('"use strict";') is another story.

I have never mentioned arguments, neither caller, which would be part of arguments.callee and not arguments itself.

I can name function expressions, I always do, and the "no strict" is needed for more than a case.

Again, is there any real reason to not consider a "no strict" directive? The whole web is running no strict thanks to minifiers so I really would like to listen to real reasons over already discussed academic debates.

# Andreas Rossberg (12 years ago)

On 15 November 2012 20:58, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

I am talking about caller which is NOT a misfeature

Indeed, "misfeature" is putting it too mildly.

# Andrea Giammarchi (12 years ago)

thanks for your contribution to this thread, appreciated. I'd like a proper answer now if that is possible.

# Oliver Hunt (12 years ago)

On Nov 15, 2012, at 12:17 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

the debugger you mention is most likely using the with statement ...

No, the debugger is part of the virtual machine. I'm aware that the WebKit inspector currently has a rather annoying bug wrt executing code in strict mode, but that's a bug.

Can we just stick with the answer if it is planned or not? I don't want to convince you that there are cases where non strict features are needed ... it is just like that and many times already discussed.

Not planned.

Again, is there any real reason to not consider a "no strict" directive? The whole web is running no strict thanks to minifiers so I really would like to listen to real reasons over already discussed academic debates.

Because it would complicate the language, the implementation, and have negative performance consequences.

# Andrea Giammarchi (12 years ago)

funny, 'cause at least one use case I have implemented, is about improving performances at least 2X for 99% of OOP frameworks out there ... I guess you like function wrappers then to simulate caller when needed, right?

Anyway, thanks ... I'd like to hear the same from some TC39 guy if you don't mind and you are not already otherwise I'll stop here.

br

# Andreas Rossberg (12 years ago)

On 15 November 2012 21:20, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

thanks for your contribution to this thread, appreciated. I'd like a proper answer now if that is possible.

You already got rather strong answers from two members of TC39. It's safe to assume that the rest feels similar. To be clear: it's not only not planned, but it would happen only over the dead body of half of the committee. There were reasons why strict mode started ruling out 'caller' and 'with' in the first place.

# Andrea Giammarchi (12 years ago)

also, take a break if you have time and enjoy this talk: www.youtube.com/watch?v=MFtijdklZDo

# Andrea Giammarchi (12 years ago)

I believe with is much more problematic than caller for all Engines out there. A reference to "who is invoking" cannot be that bad ... is it? Anyway, even C and C++ can be compiled "insecurely" so my hope was that for some extreme, well explained, documented, and needed code, the "no strict" directve would have been allowed. Engines are easily switching already between strict and no strict so I don't see, today, this problem at all, included performance since as I have said, the web is running already "no strict" thanks to minification.

br

# Oliver Hunt (12 years ago)

On Nov 15, 2012, at 12:33 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

also, take a break if you have time and enjoy this talk: www.youtube.com/watch?v=MFtijdklZDo

On Thu, Nov 15, 2012 at 12:32 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote: funny, 'cause at least one use case I have implemented, is about improving performances at least 2X for 99% of OOP frameworks out there ... I guess you like function wrappers then to simulate caller when needed, right?

Anyway, thanks ... I'd like to hear the same from some TC39 guy if you don't mind and you are not already otherwise I'll stop here.

You mean a TC39 member like me?

If you have specific examples, you can file bugs on the various engines where the performance hit is excessive (2x obviously being excessive).

# Andrea Giammarchi (12 years ago)

function wrappers created to simulate caller are obviously slower. 2 calls, the wrap and the wrapped, 1 extra nested scope, and 2 callers, since these will run no strict in any case. A de-coupled entry point to reach a caller could easily speed up performance a lot ... then you have to explain to developers that even if they think they are writing with "use strict" they are not since after minification that directive will be most likely gone so they have zero gain except while writing/testing non production code before minification (here those tools you mentioned can be useful for strict behaviors, not after on real world, IMHO)

br

# Oliver Hunt (12 years ago)

Strict mode has substantial semantic impact, any minifier that is removing it is changing program behaviour, potentially dramatically. If you're okay with the minifier disabling strict mode you should not be developing with strict mode at all, as it will mean your development builds will potentially have different behaviour from what you're deploying, as an argument for "no strict", this makes no sense.

And yes adding an additional closure and call to every function is going to adversely impact performance, but why are you doing that in the first place? If you're using .caller for debugging it's unnecessary in production, so the performance hit won't be there when it matters.

So far you haven't given any real use-case where arguments.caller is a) better than the built in functionality, and b) actually necessary in production builds.

# Allen Wirfs-Brock (12 years ago)

On Nov 15, 2012, at 12:37 PM, Andrea Giammarchi wrote:

I believe with is much more problematic than caller for all Engines out there. A reference to "who is invoking" cannot be that bad ... is it?

Yes it is! It is a capability leak. It give a callee access to functions that would otherwise be inaccessible to the callee. Who knows what mischief can be accomplished by calling such functions.

# David Herman (12 years ago)

On Nov 15, 2012, at 12:17 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

Can we just stick with the answer if it is planned or not?

It's not. "use strict" cannot be disabled, by design.

# David Herman (12 years ago)

On Nov 15, 2012, at 12:32 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

Anyway, thanks ... I'd like to hear the same from some TC39 guy if you don't mind and you are not already otherwise I'll stop here.

Oliver works for Apple

# David Herman (12 years ago)

On Nov 15, 2012, at 1:04 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

On Nov 15, 2012, at 12:37 PM, Andrea Giammarchi wrote:

I believe with is much more problematic than caller for all Engines out there. A reference to "who is invoking" cannot be that bad ... is it?

Yes it is! It is a capability leak. It give a callee access to functions that would otherwise be inaccessible to the callee. Who knows what mischief can be accomplished by calling such functions.

What's more, it's totally inadequate as a stack walking tool. If any function appears twice in a call stack (most commonly in the presence of recursion), you can't walk the whole stack. You either have to detect the repeat and give up, or loop infinitely. So in addition to being a security, performance, and engineering nightmare, arguments.caller is pretty much useless.

# David Herman (12 years ago)

On Nov 15, 2012, at 1:15 PM, David Herman <dherman at mozilla.com> wrote:

On Nov 15, 2012, at 1:04 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:

On Nov 15, 2012, at 12:37 PM, Andrea Giammarchi wrote:

I believe with is much more problematic than caller for all Engines out there. A reference to "who is invoking" cannot be that bad ... is it?

Yes it is! It is a capability leak. It give a callee access to functions that would otherwise be inaccessible to the callee. Who knows what mischief can be accomplished by calling such functions.

What's more, it's totally inadequate as a stack walking tool. If any function appears twice in a call stack (most commonly in the presence of recursion), you can't walk the whole stack. You either have to detect the repeat and give up, or loop infinitely. So in addition to being a security, performance, and engineering nightmare, arguments.caller is pretty much useless.

And to be clear, it is a problem for engines: it prevents proper tail calls (or even tail call optimization).

# Andrea Giammarchi (12 years ago)

have to dig about the Engines problems, I assumed it was a matter of "hey, I am your parent caller" pointer and nothing else.

Said that, you want a use case, here: WebReflection/poo/blob/master/src/superable.js

This let you make any object superable so that you can access this.super() as it is specified in ES6 (without this. but that's not convenient to pollute the global scope with a "super" getter and without a context) without impacting performance at all unless the method is accessing that super. In latter case yes, you have a performance impact and it's going to be probably slower than other solutions but it's about having everything else at the same speed except when you do need super access and not every time you call a method.

More over, you don't need a central uniq entry point to share superable so that different libraries could extend each other without problems.

This is not possible if the code is under use strict directive, this is why I had to update also require_client to force all code to be evaluated without that directive once minified: WebReflection/require_client

About minifiers, Google Closure compiler and YUI are only two examples ... do you know anyone better than these two that by default does not change the "use strict" behavior? That would be nice to know, thanks.

br

# ๏̯͡๏ Jasvir Nagra (12 years ago)

Jasvir Nagra

On Thu, Nov 15, 2012 at 1:43 PM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:

have to dig about the Engines problems, I assumed it was a matter of "hey, I am your parent caller" pointer and nothing else.

Said that, you want a use case, here: WebReflection/poo/blob/master/src/superable.js

This let you make any object superable so that you can access this.super() as it is specified in ES6 (without this. but that's not convenient to pollute the global scope with a "super" getter and without a context) without impacting performance at all unless the method is accessing that super. In latter case yes, you have a performance impact and it's going to be probably slower than other solutions but it's about having everything else at the same speed except when you do need super access and not every time you call a method.

More over, you don't need a central uniq entry point to share superable so that different libraries could extend each other without problems.

This is not possible if the code is under use strict directive, this is why I had to update also require_client to force all code to be evaluated without that directive once minified: WebReflection/require_client

About minifiers, Google Closure compiler and YUI are only two examples ... do you know anyone better than these two that by default does not change the "use strict" behavior? That would be nice to know, thanks.

I am not sure why "by default" matters. Closure compiler takes a flag --language_in=ECMASCRIPT5_STRICT and preserves strictness.

br

# Andrea Giammarchi (12 years ago)

"by default" as if it's there there must be a reason since, as Oliver pointed, is changing program behavior once removed.

I would expect closure compiler to be smart enough to understand strictness and dafine it once in the most outer scope or grouping them but actually with gzip this is not such big problem.

Said that, I would rather force removal of "use strict" 'cause if there is explicit desire from the developer. Isn't it?

# Brendan Eich (12 years ago)

Oliver Hunt wrote:

Even if they weren't .caller is insufficient: it can't walk over strict, native, or global code that exists in the call stack, so at best you only get a crappy result.

Note that .caller references a function, not an activation, so it can't backtrace recursive call stacks.

# Brendan Eich (12 years ago)

Andrea Giammarchi wrote:

Said that, I would rather force removal of "use strict" 'cause if there is explicit desire from the developer. Isn't it?

What do you mean? "use strict" is not going away. It is used by some developers. I had a show of hands at JSConf.au, definitely a minority but significant.

You are barking up the wrong tree. And Angus's abuses of 'with' are unjustified. Yes, "be water". Yes, masters may break rules students must follow. None of that philosophizing justifies 'with' abusage or repealing/undoing "use strict".

# Andrea Giammarchi (12 years ago)

"use strict" is removed from code by default ... this is where it goes once minified: nowhere.

I would rather force a minifier explicitly to remove it rather than force it to keep it for ES5 ... also ES5 is not use strict so I don't get this Closure Compiler choice.

I don't see minified code with "use strict" that often

# Alex Russell (12 years ago)

On Nov 16, 2012, at 1:02 AM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

"use strict" is removed from code by default ... this is where it goes once minified: nowhere.

I would rather force a minifier explicitly to remove it rather than force it to keep it for ES5 ... also ES5 is not use strict so I don't get this Closure Compiler choice.

I don't see minified code with "use strict" that often

All this suggests is that we need to improve the state of play in tools. Sounds doable.

That said, you've gotten good answers that you don't like. It happens, and it's better than not getting an answer or getting a bad one.

The polyfill you're working on can be accomplished other ways (code.google.com/p/traceur-compiler). There's always a tax for emulating the new thing with the old, and this case that's caller. More to the point, it's a polyfill; once ES6 lands in engines, class syntax will give you super() for free, complete with whatever optimizations make sense.

If you have performance issues, I recommend what everyone else here has: write benchmarks and file bugs. Beyond that, I think this horse is both dead and beaten.

On Thu, Nov 15, 2012 at 4:40 PM, Brendan Eich <brendan at mozilla.com> wrote:

Andrea Giammarchi wrote:

Said that, I would rather force removal of "use strict" 'cause if there is explicit desire from the developer. Isn't it?

What do you mean? "use strict" is not going away. It is used by some developers. I had a show of hands at JSConf.au, definitely a minority but significant.

You are barking up the wrong tree. And Angus's abuses of 'with' are unjustified. Yes, "be water". Yes, masters may break rules students must follow. None of that philosophizing justifies 'with' abusage or repealing/undoing "use strict".

/be


es-discuss mailing list es-discuss at mozilla.org, mail.mozilla.org/listinfo/es-discuss

-- Alex Russell slightlyoff at google.com slightlyoff at chromium.org alex at dojotoolkit.org BE03 E88D EABB 2116 CC49 8259 CF78 E242 59C3 9723

# Andrea Giammarchi (12 years ago)

I am still a big fun of what made JS easy to use, develop, learn since born ... the ability to include a script in a HTML page and run it without being forced of using different tools in the middle before results or even requiring a web server at all.

I remember once I've read that scripting was cool 'cause no time wasted compiling ... those days are gone in modern JS development.

br

# Rick Waldron (12 years ago)

On Thu, Nov 15, 2012 at 8:02 PM, Andrea Giammarchi < andrea.giammarchi at gmail.com> wrote:

"use strict" is removed from code by default ... this is where it goes once minified: nowhere.

I would rather force a minifier explicitly to remove it rather than force it to keep it for ES5 ... also ES5 is not use strict so I don't get this Closure Compiler choice.

Is it just Closure Compiler or are there others you know of? Uglify.js doesn't remove "use strict".

# Andrea Giammarchi (12 years ago)

AFAIK YUI Compressor does too

# Alex Russell (12 years ago)

I'm a huge fan of that too -- you know I don't like compilers as the answer -- but that approach always comes with limits; and that's OK. What we add to the spec lives forever; not just through the transition. We owe it to ourselves and our users to introduce the least crazy we can while still solving the most pressing problems; and to do it with an eye toward living in the future were specing. Caller doesn't pass this smell test.

# Andrea Giammarchi (12 years ago)

neither does with so the day use strict will be the default 90% of tests frameworks will nicely break as well.

There are tons of libraries still based on ES3 and those "evil" things.

I am the first one to use always latest, and use strict too, but there are cases where those "evil" things cannot be replaced and maybe are useful and for good.

As long as there is a "no strict" behavior supported by engines I am good in any case but it's a pity we cannot have that solution today .. is the only one that makes sense out there, the only that does not suffer all other problems plus does not impact performance of each methods when super call is something actually not that common or not always needed when inheritance is in place.

I've solved this a while ago with a better approach, even better than the currently de-sugared TypeScript, but developers are lazy and this new solution would have made them happy in their laziness.

Thank everyone in any case for all inputs and thoughts and facts, I guess I am done here.

br

# Andrea Giammarchi (12 years ago)

P.S. Alex, just to be as clear as possible, one answer I did not like that much was that eval('"no strict"') nonsense ... that was not an answer 'cause problems are the same with eval('"use strict"') and we, JS developers, are not always noobs or dumb.

It happens, from time to time, that we know what we are talking about and why we need this or that thing.

It's nice when here we keep it easy and quite ... it's also rare, imho.

# Andrea Giammarchi (12 years ago)

@Oliver, if you need to retrieve the caller in order to know if it's strict or not, then everything I've read in this thread becomes kinda pointless :-( trac.webkit.org/browser/trunk/Source/JavaScriptCore/runtime/JSFunction.cpp#L184

It looks like there's no gain at all using strict and the goal here is "simply" to get rid of these calls exec->interpreter ()->retrievesomethingFromVMCode(exec, thisObj);

am I wrong? Can I ask when and if it's planned to get rid of this isStrictMode() method? This, as info, would be definitively valuable ( FF and Chrome guys welcome to answer to this as well, thanks )

# Jeff Walden (12 years ago)

On 11/16/2012 01:42 PM, Andrea Giammarchi wrote:

@Oliver, if you need to retrieve the caller in order to know if it's strict or not, then everything I've read in this thread becomes kinda pointless :-(

Not quite. You could imagine a system where you simply have to know if your caller is strict or not. If it is, then you don't need to track any of that info. If it isn't, then you'd need some system to compute the caller. But it's certainly not the case that you always have to keep the caller around regardless.

trac.webkit.org/browser/trunk/Source/JavaScriptCore/runtime/JSFunction.cpp#L184

It looks like there's no gain at all using strict and the goal here is "simply" to get rid of these calls exec->interpreter ()->retrievesomethingFromVMCode(exec, thisObj);

Just to note, knowing that it's impossible to access the caller also benefits inlining -- you don't have to be able to recompute the caller function (or all the inlined function's stack modifications) at any moment when you're in function code that's been inlined in a caller. I would provide you a link to a blog post I wrote a year or so ago with more details on this, but it's currently down. :-( Maybe I should spend the time to bring it back up now so I can pass that link along.

am I wrong? Can I ask when and if it's planned to get rid of this isStrictMode() method? This, as info, would be definitively valuable ( FF and Chrome guys welcome to answer to this as well, thanks )

I wouldn't speculate as to when any engine will take advantage of this -- SpiderMonkey that I work on, or any of the others. It's still somewhat early in the JS optimization race, so it's likely there's more low-hanging fruit to be picked in all the engines, that benefits all code and not just strict mode code, before this would happen. As SpiderMonkey particularly, I think we have enough things on our plates now that taking advantage of this particular optimization opportunity won't happen in the next year or so.

Taking advantage of this also has some interesting interactions with other functionality like debuggers, Error.stack, error messages, and so on. The simple thing, that's been done forever, is to just always track it. But there's no reason not to specialize, and optimize harder, in the cases where these complications can be worked around or set aside.

In the long run, however, something like this will happen. It would be short-sighted to take on the semantic nightmare mid-stream strict mode opt-out would present, simply because engines aren't immediately taking advantage of all the optimization opportunities strict mode presents.

# Andrea Giammarchi (12 years ago)

but I don't see caller being any better/worse than arguments and I believe arguments will stick around "forever" in any case ... so will caller, unless there's not some specific personal reason but the code just looks basically the same: find the rabbit and "ta-daaaaa"

Yes, it would be silly to create today something based on an assumption such "future browsers optimizations will come after ES6" but on the practical level we all know it's going to be like that, right? Or even ES7 ... thanks for your answer.

# Oliver Hunt (12 years ago)

On Nov 16, 2012, at 1:42 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

@Oliver, if you need to retrieve the caller in order to know if it's strict or not, then everything I've read in this thread becomes kinda pointless :-( trac.webkit.org/browser/trunk/Source/JavaScriptCore/runtime/JSFunction.cpp#L184

It looks like there's no gain at all using strict and the goal here is "simply" to get rid of these calls exec->interpreter ()->retrievesomethingFromVMCode(exec, thisObj);

am I wrong? Can I ask when and if it's planned to get rid of this isStrictMode() method? This, as info, would be definitively valuable ( FF and Chrome guys welcome to answer to this as well, thanks )

Okay, so there are two issues:

  1. calling someFunction.caller when someFunction is itself strict

  2. calling someFunction.caller when someFunction.caller is strict

  3. is trivial: before we do any work we check whether someFunction is strict and throw if appropriate

  4. is weird -- this code post-dates my original strict mode implementation, presumably it exists due to someone adding a test for it in test262.

I'm not sure of what the value of the restriction in (2) is meant to be, I'm sure MarkM or Waldemar could say for sure, but I assume it's part of the early failure desires of strict mode. My personal bias in favour of code that continues to run all the time means I would rather return null (after all null is already a possible result).

Okay, that aside you seem to be misunderstanding what the cost model is here. Calling isStrictMode() is obviously trivial (there's a bool flag that says whether a function is strict).

But that's not the cost we're concerned about. There's a lot of complexity in the engine that is required in order to support .caller, and a lot of runtime costs involved in storing the things that are necessary for recovering it.

This is the algorithm that .caller has to use is basically: GetCaller(function) stackFrame = topStackFrame while (stackFrame) { callerFrame = stackFrame.callerFrame if (stackFrame.callee == function) { if (!callerFrame || !isFunction(callerFrame.callee)) return null return callerFrame.callee } stackFrame = callerFrame } return null

So this is expensive on its own and prevents tailcall optimisations (because a tailcall directly breaks .caller).

The other problems are that trying to retrieve callerFrame is not free, it requires undoing inlining and a variety of other optimisations, recreating a correct call stack (not cheap) and potentially disables those optimisations again in the future.

Again the cost here is not checking for strict mode it's:

  • The cost of walking the stack
  • The cost of storing information required to determine what the actual function object is so we can give you the caller function, rather than the internal type that contains the function metadata (even if you never use .caller)
  • The cost of deoptimising code when .caller is actually used
  • The opportunity cost of completely preventing certain classes of optimisation (again: even if you never use .caller)

Strict mode disables .caller because it is a misfeature, however we're still required to support it for non-strict code hence the very large amounts of code needed for it continues to exist.

# Jeff Walden (12 years ago)

On 11/16/2012 02:11 PM, Andrea Giammarchi wrote:

but I don't see caller being any better/worse than arguments and I believe arguments will stick around "forever" in any case ... so will caller, unless there's not some specific personal reason but the code just looks basically the same: find the rabbit and "ta-daaaaa"

The arguments keyword is statically detectable (or can be hedged against in the much-worse possible use of eval), which makes it far better. fun.arguments and fun.caller are about equally bad. And to the extent there are "correct" semantics for fun.arguments, engines break those daily whenever optimization opportunities present themselves.

In the longer run the code will not look "basically the same", so arguing from what the code looks like now, in any engine, is not especially convincing.

but on the practical level we all know it's going to be like that, right?

I don't understand what you're saying/implying here. Could you spell it out more clearly, please?

# Andrea Giammarchi (12 years ago)

I didn't misunderstand the cost ... I have said it's actually indeed pointless to say it costs something since the simple check, that isStrict() is performed at the end, when the rest of the logic has been moved already. Thanks for all other infos

# Oliver Hunt (12 years ago)

On Nov 16, 2012, at 2:11 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

but I don't see caller being any better/worse than arguments and I believe arguments will stick around "forever" in any case ... so will caller, unless there's not some specific personal reason but the code just looks basically the same: find the rabbit and "ta-daaaaa"

Yes, it would be silly to create today something based on an assumption such "future browsers optimizations will come after ES6" but on the practical level we all know it's going to be like that, right? Or even ES7 ... thanks for your answer.

Not understanding how features need to be/are implemented (or an unwillingness to investigate) isn't a good basis for making statements like this.

What you seem to be (willfully) ignoring is that someFunction.caller requires a stack walk. That is what it is defined as doing.

|arguments| is a magic local variable - there is no stack walk involved, only the local call frame matters, there is no stack reconstruction necessary (in the sane use cases any way - insane use cases trigger dramatic costs, and someFunction.arguments has all the problems on someFunction.caller, with a few additional costs thrown in for good measure).

# Andrea Giammarchi (12 years ago)

what I am saying: arguments won't disappear in 5+ years, neither will caller ... is my crystal ball correct?

# Andrea Giammarchi (12 years ago)

so dropping retrieveSomethingFromVMCode which I believe is one reason methods with arguments/caller access cannot be optimized runtime properly is not a performance/"use strict" goal ? So now I am confused ... gonna dig there too ...

# Jeff Walden (12 years ago)

On 11/16/2012 02:37 PM, Andrea Giammarchi wrote:

what I am saying: arguments won't disappear in 5+ years, neither will caller ... is my crystal ball correct?

It's not necessary for these things to disappear completely for us to derive value from these decisions. It's only necessary for good code, that wants to be performant, to not use them.

# Andrea Giammarchi (12 years ago)

love this answer,

# Andrea Giammarchi (12 years ago)

back in the topic ... about evaluation: Function('return this')(); returns the global object with or without use strict around. This is actually nice, since this one was a security problem introduced when somebody decided that this without an explicit context should have been undefined. Now it is possible to retrieve the global object as long as Function is the original constructor. Said that, I believe this is a bug in every browser. (Webkit, FF, Chrome suffering)

Please do not fix, thanks :-)

# Mark S. Miller (12 years ago)

How does Function('return this;') differ from (1,eval)('this') ? In both cases, if Function/eval is the original one, it executes its arguments non-strictly. This is unfortunate but all the alternatives were worse. SES replaces both Function and eval with safe variants that (among other things) enforce that the argument is executed as strict code.

# Andrea Giammarchi (12 years ago)

Mark, who said that's different ? Why SES solves this and evaluation in the global scope does not consider the "use strict" directive?

This is good news if known, it's a won't fix then: might be useful

# Oliver Hunt (12 years ago)

I don't think you understand the semantics here -- the Function constructor is defined as taking a string (ignoring the parameters for now) and returning a function as though the function was defined in the global scope. No functions change behaviour based on the strictness of their caller. The only way to make a string execute as javascript inside the scope of another function is to use the eval operator. These are fundamentally different concepts.

To put it another way, if the Function constructors behaviour was dependent on the strictness of its caller, i would expect: document.write("<script>/code here/</"+"script>");

to produce an script element that was already in strict mode.

You really need to read the spec, as you seem to be misunderstanding some very fundamental concepts.

# Andrea Giammarchi (12 years ago)

you hear Mark? drop that SES solution. Is good to evaluate in the same scope and context with a directive disabled inline and please read specs! ( sorry I could not resist but Oliver you are fun, I am going to read specs now :-) )

# Oliver Hunt (12 years ago)

On Nov 16, 2012, at 3:38 PM, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

you hear Mark? drop that SES solution. Is good to evaluate in the same scope and context with a directive disabled inline and please read specs! ( sorry I could not resist but Oliver you are fun, I am going to read specs now :-) )

I'm not sure where you got that from, if you felt I was being offensive I apologise, but I'm serious, you need to read the spec; There are very real, and very important semantic differences between using eval as an operator, and calling any other function. Likewise there are very important behavioural differences between accessing the arguments value inside a function body, and accessing the caller property of a function object. There are major semantic differences between the concepts of a function object, a function's environment record, and the function code itself. To meaningfully discuss the behaviour and semantics of these things (and their interactions with strict mode) you need to understand all of these concepts and how they relate.

# Andrea Giammarchi (12 years ago)

sure, but I believe Mark did before me and SES fixed this issue indeed. I understand it's different behind the scene, I don't understand why "use strict" , which aim is to make code more secure, better, faster, can be easily deactivated like that. I am talking about 3rd parts libraries that could decide to run non strict inside whatever "use strict" environment due that Function/(1,eval) door.

If this is not risky then I am missing what is this "use strict" about since there were already linters to tell us what's good and what's not on code level, I am sorry if I don't understand.

br

# Oliver Hunt (12 years ago)

Sstrict mode isn't meant to make JS secure (it just isn't possible to do so in a non-break-the-web way, that's why SES exists and isn't just folded into the language).

Strict mode tries to remove as many foot guns as possible, and make as many probable errors fail as early as possible in an attempt to rectify old bugs from the early days of JS (accidental creation of globals, bizzaro behaviour when assigning to arguments, etc). Killing off with() had significant security benefits, but the bigger win is that with() has really crazy that makes it impossible to reason about code in any meaningful way.

SES on the other hand sets things up so that you can include untrusted 3rd party content in verifiably safe ways, something that strict mode does nothing to address. Strict mode helps SES a lot by making it possible to have essentially static control over all the otherwise unsafe things that can be done normally.

# Andreas Rossberg (12 years ago)

On 16 November 2012 22:01, Andrea Giammarchi <andrea.giammarchi at gmail.com> wrote:

P.S. Alex, just to be as clear as possible, one answer I did not like that much was that eval('"no strict"') nonsense ... that was not an answer 'cause problems are the same with eval('"use strict"')

No, they are not. You apparently didn't understand Oliver's answer, but chose to call it "nonsense" without even trying. Not a good basis for making a convincing argument.

# Andrea Giammarchi (12 years ago)

it's about changing behavior inline, both cases should throw an error. I won't try, I am just saying what I think should happen.

Said that, I am off this thread, I have clarified already everything I needed to clarify and I am OK with everything anyone will say here.

Happy Monday everybody :-)

br