Bug 1342483 - Add JSScript::needsBodyEnvironment draft
authorTed Campbell <tcampbell@mozilla.com>
Fri, 03 Mar 2017 10:03:06 -0500
changeset 493198 21a259aa0f24
parent 490433 1bc2ad020aee
child 493199 9f86c75d616f
child 493200 46167a2732ac
push id47681
push userbmo:tcampbell@mozilla.com
push dateFri, 03 Mar 2017 15:19:23 +0000
bugs1342483
milestone54.0a1
Bug 1342483 - Add JSScript::needsBodyEnvironment MozReview-Commit-ID: ETGQtw2sIGJ
js/src/frontend/BytecodeEmitter.cpp
js/src/jsscript.h
js/src/vm/Scope.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -300,27 +300,16 @@ class TryFinallyControl : public Bytecod
         emittingSubroutine_ = true;
     }
 
     bool emittingSubroutine() const {
         return emittingSubroutine_;
     }
 };
 
-static bool
-ScopeKindIsInBody(ScopeKind kind)
-{
-    return kind == ScopeKind::Lexical ||
-           kind == ScopeKind::SimpleCatch ||
-           kind == ScopeKind::Catch ||
-           kind == ScopeKind::With ||
-           kind == ScopeKind::FunctionBodyVar ||
-           kind == ScopeKind::ParameterExpressionVar;
-}
-
 static inline void
 MarkAllBindingsClosedOver(LexicalScope::Data& data)
 {
     BindingName* names = data.names;
     for (uint32_t i = 0; i < data.length; i++)
         names[i] = BindingName(names[i].name(), true);
 }
 
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -1629,16 +1629,25 @@ class JSScript : public js::gc::TenuredC
         for (uint32_t i = 0; i < scopes()->length; i++) {
             js::Scope* scope = getScope(i);
             if (scope->kind() == js::ScopeKind::FunctionBodyVar)
                 return &scope->as<js::VarScope>();
         }
         MOZ_CRASH("Function extra body var scope not found");
     }
 
+    bool needsBodyEnvironment() const {
+        for (uint32_t i = 0; i < scopes()->length; i++) {
+            js::Scope* scope = getScope(i);
+            if (ScopeKindIsInBody(scope->kind()) && scope->hasEnvironment())
+                return true;
+        }
+        return false;
+    }
+
     inline js::LexicalScope* maybeNamedLambdaScope() const;
 
     js::Scope* enclosingScope() const {
         return outermostScope()->enclosing();
     }
 
   private:
     bool makeTypes(JSContext* cx);
--- a/js/src/vm/Scope.h
+++ b/js/src/vm/Scope.h
@@ -78,16 +78,27 @@ enum class ScopeKind : uint8_t
 };
 
 static inline bool
 ScopeKindIsCatch(ScopeKind kind)
 {
     return kind == ScopeKind::SimpleCatch || kind == ScopeKind::Catch;
 }
 
+static inline bool
+ScopeKindIsInBody(ScopeKind kind)
+{
+    return kind == ScopeKind::Lexical ||
+           kind == ScopeKind::SimpleCatch ||
+           kind == ScopeKind::Catch ||
+           kind == ScopeKind::With ||
+           kind == ScopeKind::FunctionBodyVar ||
+           kind == ScopeKind::ParameterExpressionVar;
+}
+
 const char* BindingKindString(BindingKind kind);
 const char* ScopeKindString(ScopeKind kind);
 
 class BindingName
 {
     // A JSAtom* with its low bit used as a tag for whether it is closed over
     // (i.e., exists in the environment shape).
     uintptr_t bits_;