Hi, I have been plugging away at the block scope stuff. My current work is on https://bugs.webkit.org/show_bug.cgi?id=74708. Like some other patches, it uses catch clauses as the proof of concept, because there are so many tests around that area. It does lazy creation and tear-off if possible, and only in the case in which a scope has captured variables. I have two remaining things to fix before it is fully baked. One is static lookup of free variables (e.g. ResolveResult::Lexical variables). The issue is that with lazy scope creation ("reification") the depth in the scope chain cannot be computed statically. Let's say you are resolving "foo" in: (function () { var foo = 1; return function () { var bar = 3; function qux(x) { return bar+x; } return bar + foo; } })() Here, both functions will lazily create their activations. (I put in the qux to make sure the inner function has a lazy activation.) Here is their bytecode: Outer: 32 m_instructions; 256 bytes at 0xb10cf0; 1 parameter(s); 12 callee register(s); 4 variable(s) [ 0] enter [ 1] init_lazy_reg r0 [ 3] init_lazy_reg r2 [ 5] init_lazy_reg r1 [ 7] mov r3, Int32: 1(@k0) [ 10] create_activation r0 [ 12] new_func_exp r4, f0 [ 15] mov r5, Undefined(@k1) [ 18] call r4, 1, 12 [ 24] op_call_put_result r4 [ 27] tear_off_activation r0, r2 [ 30] ret r4 Constants: k0 = Int32: 1 k1 = Undefined Inner: 27 m_instructions; 216 bytes at 0xb0c930; 1 parameter(s); 6 callee register(s); 5 variable(s) [ 0] enter [ 1] init_lazy_reg r0 [ 3] init_lazy_reg r2 [ 5] init_lazy_reg r1 [ 7] init_lazy_reg r4 [ 9] mov r3, Int32: 3(@k0) [ 12] get_scoped_var r5, 3, 1 [ 17] add r5, r3, r5 [ 22] tear_off_activation r0, r2 [ 25] ret r5 Constants: k0 = Int32: 3 Note the get_scoped_var in the inner function, corresponding to the resolution of "foo". It indicates that "foo" can be found in the third register of the scope object one scope deep. However there might be an additional object on the scope chain, corresponding to the lazily created activation of the inner function. There is explicit code to account for skipping over an activation in the implementations of put_scoped_var and get_scoped_var. But with more lazily reified scopes that may or may not be on the scope chain (depending on whether the code path traversed a with, eval, or function expression), such an approach doesn't work. You can't determine the static depth from the top of the scope chain, because you'd like to avoid creating the entire scope chain if you can. I suggest that we change the users of scope chains (eval, with, and function expressions) to receive the scope chain register as a parameter. The compiler already has to handle lazy scope creation, so it's just as easy to put the scope in a temporary as it is to put it in the callframe. Free variable lookup will continue to use the register in the callframe. As a bonus, that code can be simpler because it doesn't have to check if the there is an activation or not. OK, that's one. The second issue is handling temporal dead zone errors. In ES6 it is a SyntaxError if you access the value of a let- or const-bound variable before it is initialized. In practice this means that in the general case, we mark uninitialized variables with a sentinel value (JSValue(), via init_lazy_reg). Access to let- or const-bound variables that need a barrier is preceded by a check that the variable is initialized. We can prove for some cases that no barrier is needed, and elide the barrier, but OK. My question is how to structure this check. Currently I have an assert_lazy_reg_init opcode that throws an error if the value isEmpty(). I guess we need to associate a name with that error too, so that opcode should take an identifier as a parameter as well. WDYT? Currently there is also an assert_lazy_reg_not_init opcode, but that was based on a misunderstanding -- you can only initialize const variables, not assign to them. Hence initialization doesn't need such a check. Finally, two more thoughts. One is that we can use op_reify_scope / op_tear_off_scope for parameters and locals in some cases, if a function does not have non-strict eval, as Gavin suggested. Also I hope to get a patch for "const" in today. The break-the-web aspect is a bit tricky, but we'll see how that goes. Thanks for comments! Andy -- http://wingolog.org/