[ES6]. Implement Annex B.3.3 function hoisting rules for eval
authorgskachkov@gmail.com <gskachkov@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 18 Apr 2017 19:35:50 +0000 (19:35 +0000)
committergskachkov@gmail.com <gskachkov@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 18 Apr 2017 19:35:50 +0000 (19:35 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163208

Reviewed by Saam Barati.

JSTests:

* stress/eval-func-decl-block-scoping-reassign.js: Added.
(assert):
(throw.new.Error.f):
(throw.new.Error):
* stress/eval-func-decl-block-with-remove.js: Added.
(assert):
(foo.boo):
(foo):
* stress/eval-func-decl-block-with-var-and-remove.js: Added.
(assert):
(assertThrow):
(foo):
(boo):
(joo):
(koo):
* stress/eval-func-decl-block-with-var-sinthesize.js: Added.
(assert):
(assertThrow):
(foo):
(boo):
(hoo):
(joo):
(koo):
* stress/eval-func-decl-in-block-scope-and-bind-to-top-eval-scope.js: Added.
* stress/eval-func-decl-in-eval-within-block-with-let.js: Added.
(assert):
(assertThrow):
(foo):
(boo):
(goo):
* stress/eval-func-decl-in-eval-within-with-scope.js: Added.
(assert):
(assertThrow):
(foo):
(boo):
(boo.let.val2):
(boo.let.val3):
* stress/eval-func-decl-in-frozen-global.js: Added.
(assert):
(assertThrow):
(throw.new.Error):
(Object.freeze):
* stress/eval-func-decl-in-global-of-eval.js: Added.
(assert):
(assertThrow):
(bar):
(baz):
(foobar):
* stress/eval-func-decl-in-global.js: Added.
(assert):
(assertThrow):
* stress/eval-func-decl-in-if.js: Added.
(assert):
* stress/eval-func-decl-within-eval-with-reassign-to-var.js: Added.
(assert):
(assertThrow):
(foo):
(boo):
(foobar):
(hoo):
(joo):
(koo):
(loo):
* stress/eval-func-decl-within-eval-without-reassign-to-let.js: Added.
(assert):
(assertThrow):
(foo):
(boo):
(goo):
* stress/variable-under-tdz-eval-tricky.js:
(assert):
* test262.yaml:

Source/JavaScriptCore:

Current patch implements Annex B.3.3 that is related to
hoisting of function declaration in eval.
https://tc39.github.io/ecma262/#sec-web-compat-evaldeclarationinstantiation
Function declaration in eval should create variable with
function name in function scope where eval is invoked
or bind to variable if it declared outside of the eval.
If variable is created it can be removed by 'delete a;' command.
If eval is invoke in block scope that contains let/const
variable with the same name as function declaration
we do not bind. This patch leads to the following behavior:
'''
function foo() {
   {
     print(boo); // undefined
     eval('{ function boo() {}}');
     print(boo); // function boo() {}
   }
   print(boo); // function boo() {}
}

function foobar() {
  {
    let boo = 10;
    print(boo); // 10;
    eval('{ function boo() {}}');
    print(boo); // 10;
  }
  print(boo) // 10
}

function bar() {
   {
      var boo = 10;
      print(boo); // 10
      eval('{ function boo() {} }');
      print(boo); // function boo() {}
   }
   print(boo); // function boo() {}
}

function bas() {
    {
         let boo = 10;
         eval(' { function boo() {} } ');
         print(boo); // 10
    }
    print(boo); //Reference Error
}
'''

Current implementation relies on already implemented
'hoist function in sloppy mode' feature, with small changes.
In short it works in following way: during hoisting of function
with name S in eval, we are looking for first scope that
contains space for variable with name S and if this scope
has var type we bind function there

To implement this feature was added bytecode ops:
op_resolve_scope_for_hoisting_func_decl_in_eval - get variable scope
or return undefined if variable can't be binded there.

There is a corner case, hoist function in eval within catch block,
that is not covered by this patch, and will be fixed in
https://bugs.webkit.org/show_bug.cgi?id=168184

* bytecode/BytecodeDumper.cpp:
(JSC::BytecodeDumper<Block>::dumpBytecode):
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finalizeLLIntInlineCaches):
* bytecode/EvalCodeBlock.h:
(JSC::EvalCodeBlock::functionHoistingCandidate):
(JSC::EvalCodeBlock::numFunctionHoistingCandidates):
* bytecode/UnlinkedEvalCodeBlock.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::hoistSloppyModeFunctionIfNecessary):
(JSC::BytecodeGenerator::emitResolveScopeForHoistingFuncDeclInEval):
* bytecompiler/BytecodeGenerator.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNode.h:
(JSC::DFG::Node::hasIdentifier):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileResolveScopeForHoistingFuncDeclInEval):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileResolveScopeForHoistingFuncDeclInEval):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_resolve_scope_for_hoisting_func_decl_in_eval):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::emit_op_resolve_scope_for_hoisting_func_decl_in_eval):
* llint/LowLevelInterpreter.asm:
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseFunctionDeclarationStatement):
* parser/Parser.h:
(JSC::Scope::getSloppyModeHoistedFunctions):
(JSC::Parser::declareFunction):
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/EvalExecutable.h:
(JSC::EvalExecutable::numFunctionHoistingCandidates):
(JSC::EvalExecutable::numTopLevelFunctionDecls):
(JSC::EvalExecutable::numberOfFunctionDecls): Deleted.
* runtime/JSScope.cpp:
(JSC::JSScope::resolve):
(JSC::JSScope::resolveScopeForHoistingFuncDeclInEval):
* runtime/JSScope.h:

LayoutTests:

* inspector/runtime/evaluate-CommandLineAPI-expected.txt:
* inspector/runtime/evaluate-CommandLineAPI.html:
* js/parser-syntax-check-expected.txt:
* js/script-tests/parser-syntax-check.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@215476 268f45cc-cd09-0410-ab3c-d52691b4dbfc

62 files changed:
JSTests/ChangeLog
JSTests/stress/eval-func-decl-block-scoping-reassign.js [new file with mode: 0644]
JSTests/stress/eval-func-decl-block-with-remove.js [new file with mode: 0644]
JSTests/stress/eval-func-decl-block-with-var-and-remove.js [new file with mode: 0644]
JSTests/stress/eval-func-decl-block-with-var-sinthesize.js [new file with mode: 0644]
JSTests/stress/eval-func-decl-in-block-scope-and-bind-to-top-eval-scope.js [new file with mode: 0644]
JSTests/stress/eval-func-decl-in-eval-within-block-with-let.js [new file with mode: 0644]
JSTests/stress/eval-func-decl-in-eval-within-with-scope.js [new file with mode: 0644]
JSTests/stress/eval-func-decl-in-frozen-global.js [new file with mode: 0644]
JSTests/stress/eval-func-decl-in-global-of-eval.js [new file with mode: 0644]
JSTests/stress/eval-func-decl-in-global.js [new file with mode: 0644]
JSTests/stress/eval-func-decl-in-if.js [new file with mode: 0644]
JSTests/stress/eval-func-decl-within-eval-with-reassign-to-var.js [new file with mode: 0644]
JSTests/stress/eval-func-decl-within-eval-without-reassign-to-let.js [new file with mode: 0644]
JSTests/stress/variable-under-tdz-eval-tricky.js
JSTests/test262.yaml
LayoutTests/ChangeLog
LayoutTests/inspector/runtime/evaluate-CommandLineAPI-expected.txt
LayoutTests/inspector/runtime/evaluate-CommandLineAPI.html
LayoutTests/js/parser-syntax-check-expected.txt
LayoutTests/js/script-tests/parser-syntax-check.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/BytecodeDumper.cpp
Source/JavaScriptCore/bytecode/BytecodeList.json
Source/JavaScriptCore/bytecode/BytecodeUseDef.h
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/bytecode/EvalCodeBlock.h
Source/JavaScriptCore/bytecode/UnlinkedEvalCodeBlock.h
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGCapabilities.cpp
Source/JavaScriptCore/dfg/DFGClobberize.h
Source/JavaScriptCore/dfg/DFGDoesGC.cpp
Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Source/JavaScriptCore/dfg/DFGNode.h
Source/JavaScriptCore/dfg/DFGNodeType.h
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/dfg/DFGOperations.h
Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
Source/JavaScriptCore/dfg/DFGSafeToExecute.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
Source/JavaScriptCore/ftl/FTLCapabilities.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/jit/JIT.cpp
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITOperations.h
Source/JavaScriptCore/jit/JITPropertyAccess.cpp
Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/parser/Parser.cpp
Source/JavaScriptCore/parser/Parser.h
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/CommonSlowPaths.h
Source/JavaScriptCore/runtime/EvalExecutable.h
Source/JavaScriptCore/runtime/JSScope.cpp
Source/JavaScriptCore/runtime/JSScope.h

index 76a193f..e444ee9 100644 (file)
@@ -1,3 +1,83 @@
+2017-04-18  Oleksandr Skachkov  <gskachkov@gmail.com>
+
+        [ES6]. Implement Annex B.3.3 function hoisting rules for eval
+        https://bugs.webkit.org/show_bug.cgi?id=163208
+
+        Reviewed by Saam Barati.
+
+        * stress/eval-func-decl-block-scoping-reassign.js: Added.
+        (assert):
+        (throw.new.Error.f):
+        (throw.new.Error):
+        * stress/eval-func-decl-block-with-remove.js: Added.
+        (assert):
+        (foo.boo):
+        (foo):
+        * stress/eval-func-decl-block-with-var-and-remove.js: Added.
+        (assert):
+        (assertThrow):
+        (foo):
+        (boo):
+        (joo):
+        (koo):
+        * stress/eval-func-decl-block-with-var-sinthesize.js: Added.
+        (assert):
+        (assertThrow):
+        (foo):
+        (boo):
+        (hoo):
+        (joo):
+        (koo):
+        * stress/eval-func-decl-in-block-scope-and-bind-to-top-eval-scope.js: Added.
+        * stress/eval-func-decl-in-eval-within-block-with-let.js: Added.
+        (assert):
+        (assertThrow):
+        (foo):
+        (boo):
+        (goo):
+        * stress/eval-func-decl-in-eval-within-with-scope.js: Added.
+        (assert):
+        (assertThrow):
+        (foo):
+        (boo):
+        (boo.let.val2):
+        (boo.let.val3):
+        * stress/eval-func-decl-in-frozen-global.js: Added.
+        (assert):
+        (assertThrow):
+        (throw.new.Error):
+        (Object.freeze):
+        * stress/eval-func-decl-in-global-of-eval.js: Added.
+        (assert):
+        (assertThrow):
+        (bar):
+        (baz):
+        (foobar):
+        * stress/eval-func-decl-in-global.js: Added.
+        (assert):
+        (assertThrow):
+        * stress/eval-func-decl-in-if.js: Added.
+        (assert):
+        * stress/eval-func-decl-within-eval-with-reassign-to-var.js: Added.
+        (assert):
+        (assertThrow):
+        (foo):
+        (boo):
+        (foobar):
+        (hoo):
+        (joo):
+        (koo):
+        (loo):
+        * stress/eval-func-decl-within-eval-without-reassign-to-let.js: Added.
+        (assert):
+        (assertThrow):
+        (foo):
+        (boo):
+        (goo):
+        * stress/variable-under-tdz-eval-tricky.js:
+        (assert):
+        * test262.yaml:
+
 2017-04-18  Filip Pizlo  <fpizlo@apple.com>
 
         wasm/function-tests/memory-multiagent times out sometimes
diff --git a/JSTests/stress/eval-func-decl-block-scoping-reassign.js b/JSTests/stress/eval-func-decl-block-scoping-reassign.js
new file mode 100644 (file)
index 0000000..4da1c78
--- /dev/null
@@ -0,0 +1,18 @@
+var assert = function (result, expected, message) {
+  if (result !== expected) {
+    throw new Error('Error in assert. Expected "' + expected + '" but was "' + result + '":' + message );
+  }
+};
+
+{
+  function f() {
+    return 'first declaration';
+  }
+}
+
+eval(
+  '{ function f() { return "second declaration"; } }'
+);
+
+assert(typeof f, 'function', ' #1');
+assert(f(), 'second declaration', ' #2');
\ No newline at end of file
diff --git a/JSTests/stress/eval-func-decl-block-with-remove.js b/JSTests/stress/eval-func-decl-block-with-remove.js
new file mode 100644 (file)
index 0000000..03aa6b0
--- /dev/null
@@ -0,0 +1,17 @@
+var assert = function (result, expected, message) {
+  if (result !== expected) {
+    throw new Error('Error in assert. Expected "' + expected + '" but was "' + result + '":' + message );
+  }
+};
+
+function foo() {
+    function boo() { 
+        return typeof a; 
+    }
+    eval("{ assert(boo(), 'undefined'); delete a; assert(boo(), 'undefined'); function a() { return 'text-a'; } assert(boo(), 'function');} ");
+}
+foo(); 
+
+for (let i = 0; i < 10000; i++) {
+    foo();
+}
\ No newline at end of file
diff --git a/JSTests/stress/eval-func-decl-block-with-var-and-remove.js b/JSTests/stress/eval-func-decl-block-with-var-and-remove.js
new file mode 100644 (file)
index 0000000..443a395
--- /dev/null
@@ -0,0 +1,84 @@
+var assert = function (result, expected, message) {
+    if (result !== expected) {
+        throw new Error('Error in assert. Expected "' + expected + '" but was "' + result + '":' + message );
+    }
+};
+
+var assertThrow = function (cb, expected) {
+    let error = null;
+    try {
+        cb();
+    } catch(e) {
+        error = e;  
+    }
+    if (error === null) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was not thrown."');
+    }
+    if (error.toString() !== expected) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was "' + error + '"');
+    }
+};
+
+function foo() {
+    {   
+        assertThrow(() => f, "ReferenceError: Can't find variable: f");
+        eval('eval(" { function f() { }; } ")');
+        assert(typeof f, "function");
+    }
+    assert(typeof f, "function", "#1");
+    delete f;
+    assertThrow(() => f, "ReferenceError: Can't find variable: f", "#1");
+}
+
+for (var i = 0; i < 10000; i++) {
+    foo();
+    assertThrow(() => f, "ReferenceError: Can't find variable: f");
+}
+
+function boo() {
+    {
+        assert(typeof l, "undefined", "#5");
+        eval('{ var l = 15; eval(" { function l() { }; } ")}');
+        assert(typeof l, "function", "#3");
+    }
+    assert(typeof l, 'function', "#4");
+    delete l;
+    assertThrow(() => f, "ReferenceError: Can't find variable: f");
+}
+
+for (var i = 0; i < 10000; i++){
+    boo();
+    assertThrow(() => f, "ReferenceError: Can't find variable: f");
+}
+
+function joo() {
+    {
+        assert(typeof h, "undefined" );
+        eval('eval(" if (true){ function h() { }; } ")');
+        assert(typeof h, "function" );
+    }
+    assert(typeof h, "function", "#10");
+    delete h;
+    assertThrow(() => h, "ReferenceError: Can't find variable: h");
+}
+
+for (var i = 0; i < 10000; i++){
+    joo();
+    assertThrow(() => h, "ReferenceError: Can't find variable: h");
+}
+
+function koo() {
+    {
+        var k = 20;
+        eval('var k = 15; eval(" if (true){ function k() { }; } ")');
+        assert(typeof k, "function" );
+    }
+    assert(typeof k, "function", "#12");
+    delete k;
+    assert(typeof k, "function", "#12");
+}
+
+for (var i = 0; i < 10000; i++){
+    koo();
+    assertThrow(() => k, "ReferenceError: Can't find variable: k");
+}
diff --git a/JSTests/stress/eval-func-decl-block-with-var-sinthesize.js b/JSTests/stress/eval-func-decl-block-with-var-sinthesize.js
new file mode 100644 (file)
index 0000000..2a92ce8
--- /dev/null
@@ -0,0 +1,90 @@
+var assert = function (result, expected, message) {
+    if (result !== expected) {
+        throw new Error('Error in assert. Expected "' + expected + '" but was "' + result + '":' + message );
+    }
+};
+
+var assertThrow = function (cb, expected) {
+    let error = null;
+    try {
+        cb();
+    } catch(e) {
+        error = e;  
+    }
+    if (error === null) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was not thrown."');
+    }
+    if (error.toString() !== expected) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was "' + error + '"');
+    }
+};
+
+function foo() {
+    {   
+        assertThrow(() => f, "ReferenceError: Can't find variable: f");
+        eval('eval(" { function f() { }; } ")');
+        assert(typeof f, "function");
+    }
+    assert(typeof f, "function");
+}
+
+for (var i = 0; i < 10000; i++){
+    foo();
+    assertThrow(() => f, "ReferenceError: Can't find variable: f");
+}
+
+function boo() {
+    {
+        assertThrow(() => l, "ReferenceError: Can't find variable: l");
+        eval('{ var l = 15; eval(" { function l() { }; } ")}');
+        assert(typeof l, "function", "#3");
+    }
+    assert(typeof l, 'function', "#4");
+}
+
+for (var i = 0; i < 10000; i++){
+    boo();
+    assertThrow(() => l, "ReferenceError: Can't find variable: l");
+}
+
+function hoo() {
+    {
+        assertThrow(() => h, "ReferenceError: Can't find variable: h");
+        eval('eval(" if (false){ function h() { }; } ");');
+        assert(h, undefined, '');
+    }
+    assert(h, undefined, '');
+}
+
+for (var i = 0; i < 10000; i++){
+    hoo();
+    assertThrow(() => h, "ReferenceError: Can't find variable: h");
+}
+
+function joo() {
+    {
+        assertThrow(() => h, "ReferenceError: Can't find variable: h");
+        eval('eval(" if (true){ function h() { }; } ")');
+        assert(typeof h, "function" );
+    }
+    assert(typeof h, "function", "#10");
+}
+
+for (var i = 0; i < 10000; i++){
+    joo();
+    assertThrow(() => h, "ReferenceError: Can't find variable: h");
+}
+
+function koo() {
+    {
+        var k = 20;
+        eval('var k = 15; eval(" if (true){ function k() { }; } ")');
+        assert(typeof k, "function" );
+    }
+    assert(typeof k, "function", "#12");
+}
+
+for (var i = 0; i < 10000; i++){
+    koo();
+    assertThrow(() => k, "ReferenceError: Can't find variable: k");
+}
diff --git a/JSTests/stress/eval-func-decl-in-block-scope-and-bind-to-top-eval-scope.js b/JSTests/stress/eval-func-decl-in-block-scope-and-bind-to-top-eval-scope.js
new file mode 100644 (file)
index 0000000..f97ee3a
--- /dev/null
@@ -0,0 +1,14 @@
+var init1;
+
+(function() {
+  eval(
+    '\
+    init1 = f;\
+    {\
+      function f() {}\
+    }{ function f() {  } }'
+  );
+}());
+
+if (init1 !== undefined)
+  throw new Error('Wrong binding of the function.');
\ No newline at end of file
diff --git a/JSTests/stress/eval-func-decl-in-eval-within-block-with-let.js b/JSTests/stress/eval-func-decl-in-eval-within-block-with-let.js
new file mode 100644 (file)
index 0000000..a378fb9
--- /dev/null
@@ -0,0 +1,61 @@
+var assert = function (result, expected, message) {
+    if (result !== expected) {
+        throw new Error('Error in assert. Expected "' + expected + '" but was "' + result + '":' + message );
+    }
+};
+
+var assertThrow = function (cb, expected) {
+    let error = null;
+    try {
+        cb();
+    } catch(e) {
+        error = e;  
+    }
+    if (error === null) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was not thrown."');
+    }
+    if (error.toString() !== expected) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was "' + error + '"');
+    }
+}
+
+function foo() {
+    {
+        let f = 20;
+        eval(" { function f() { value = 20; }; }");
+        assert(f, 20);
+    }
+    assertThrow(() => f, "ReferenceError: Can't find variable: f");
+}
+
+
+for (var i = 0; i < 10000; i++){
+    foo();
+    assertThrow(() => f, "ReferenceError: Can't find variable: f");
+}
+
+function boo() {
+    {
+        var l = 20;
+        eval(" { function l() { value = 20; }; }");
+        assert(typeof l, 'function');
+    }
+    assert(typeof l, 'function');
+}
+
+for (var i = 0; i < 10000; i++){
+    boo();
+    assertThrow(() => l, "ReferenceError: Can't find variable: l");
+}
+
+function goo() {
+    {
+        let g = 20;
+        eval(" for(var j=0; j < 10000; j++){ function g() { }; } ");
+        assert(typeof g, 'number');
+    }
+    assertThrow(() => g, "ReferenceError: Can't find variable: g");
+}
+
+goo();
+assertThrow(() => g, "ReferenceError: Can't find variable: g");
diff --git a/JSTests/stress/eval-func-decl-in-eval-within-with-scope.js b/JSTests/stress/eval-func-decl-in-eval-within-with-scope.js
new file mode 100644 (file)
index 0000000..b47b278
--- /dev/null
@@ -0,0 +1,111 @@
+var assert = function (result, expected, message) {
+    if (result !== expected) {
+        throw new Error('Error in assert. Expected "' + expected + '" but was "' + result + '":' + message );
+    }
+};
+
+var assertThrow = function (cb, expected) {
+    let error = null;
+    try {
+        cb();
+    } catch(e) {
+        error = e;  
+    }
+    if (error === null) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was not thrown."');
+    }
+    if (error.toString() !== expected) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was "' + error + '"');
+    }
+};
+
+function foo(withScope, firstAssertValue,  secondAssertValue) {
+    with (withScope) {
+        eval("{ function f() { } }");
+        assert(typeof f, firstAssertValue, f);
+    }
+    assert(typeof f, secondAssertValue);
+}
+
+function boo(withScope, firstAssertValue,  secondAssertValue) {
+    with (withScope) {
+        eval(" for(var i = 0; i < 10000; i++ ){ if (i > 0) { function f() { }; } } ");
+        assert(typeof f, firstAssertValue);
+    }
+    assert(typeof f, secondAssertValue);
+}
+{ 
+    for (var i = 0; i < 10000; i++) {
+        foo({}, 'function', 'function');
+        assertThrow(() => f, "ReferenceError: Can't find variable: f");
+    }
+
+    boo({}, 'function', 'function');
+}
+{
+    for (var i = 0; i < 10000; i++) {
+        foo({f : 10}, 'number', 'function');
+        assertThrow(() => f, "ReferenceError: Can't find variable: f");
+    }
+    boo({f : 10}, 'number', 'function');
+
+    for (var i = 0; i < 10000; i++) {
+        foo({f : {}}, 'object', 'function');
+        assertThrow(() => f, "ReferenceError: Can't find variable: f");
+    }
+    boo({f : {}}, 'object', 'function');
+}
+{
+    for (var i = 0; i < 10000; i++) {
+        foo(12345, 'function', 'function');
+        assertThrow(() => f, "ReferenceError: Can't find variable: f");
+    }
+    boo(12345, 'function', 'function');
+
+    for (var i = 0; i < 10000; i++) {
+        let val  = 12345;
+        val.f = 10;
+        foo(val, 'function', 'function');
+        assertThrow(() => f, "ReferenceError: Can't find variable: f");
+    }
+    let x  = 12345;
+    x.f = 10;
+    boo(x, 'function', 'function');
+}
+{
+
+    for (var i = 0; i < 10000; i++) {
+        foo('12345', 'function', 'function');
+        assertThrow(() => f, "ReferenceError: Can't find variable: f");
+    }
+    boo('12345', 'function', 'function');
+
+    for (var i = 0; i < 10000; i++) {
+        let val  = '12345';
+        val.f = 10;
+        foo(val, 'function', 'function');
+        assertThrow(() => f, "ReferenceError: Can't find variable: f");
+    }
+    let z  = '12345';
+    z.f = 10;
+    boo(z, 'function', 'function');
+}
+{
+    for (var i = 0; i < 10000; i++) {
+        foo(function () {}, 'function', 'function');
+        assertThrow(() => f, "ReferenceError: Can't find variable: f");
+    }
+
+    boo(function () {}, 'function', 'function');
+
+    for (var i = 0; i < 10000; i++) {
+        let val2 = function () {};
+        val2.f = 10;
+        foo(val2, 'number', 'function');
+        assertThrow(() => f, "ReferenceError: Can't find variable: f");
+    }
+
+    let val3 = function () {};
+    val3.f = 10;
+    boo(val3, 'number', 'function');
+}
\ No newline at end of file
diff --git a/JSTests/stress/eval-func-decl-in-frozen-global.js b/JSTests/stress/eval-func-decl-in-frozen-global.js
new file mode 100644 (file)
index 0000000..961a448
--- /dev/null
@@ -0,0 +1,48 @@
+var assert = function (result, expected, message) {
+  if (result !== expected) {
+    throw new Error('Error in assert. Expected "' + expected + '" but was "' + result + '":' + message );
+  }
+};
+
+var assertThrow = function (cb, errorText) {
+    var error = null;
+    try {
+        cb();
+    } catch (e) {
+         error = e.toString();
+    }
+    if (error === null) 
+        throw new Error('Expected error');
+    if (error !== errorText)
+        throw new Error('Expected error ' + errorText + ' but was ' + error);
+};
+
+{ 
+  eval('{ function foo() {} }');
+  assert(this.hasOwnProperty("foo"), true);
+  assert(typeof foo, 'function');
+}
+
+Object.defineProperty(this, "globalNonWritable", {
+  value: false,
+  configurable: true,
+  writable: false,
+  enumerable: true
+});
+eval("{function globalNonWritable() { return 1; }}");
+var globalNonWritableDescriptor
+    = Object.getOwnPropertyDescriptor(this, "globalNonWritable");
+assert(globalNonWritableDescriptor.enumerable, true);
+
+Object.freeze(this);
+{
+  var error = false;
+  try {
+    eval('{ function boo() {} }');
+  } catch (e) {
+    error = true;
+  }
+  assert(this.hasOwnProperty("boo"), false);
+  assert(error, false);
+  assertThrow(() => boo, 'ReferenceError: Can\'t find variable: boo');
+}
diff --git a/JSTests/stress/eval-func-decl-in-global-of-eval.js b/JSTests/stress/eval-func-decl-in-global-of-eval.js
new file mode 100644 (file)
index 0000000..fe19346
--- /dev/null
@@ -0,0 +1,66 @@
+var assert = function (result, expected, message) {
+    if (result !== expected) {
+        throw new Error('Error in assert. Expected "' + expected + '" but was "' + result + '":' + message );
+    }
+};
+
+var assertThrow = function (cb, expected) {
+    let error = null;
+    try {
+        cb();
+    } catch(e) {
+        error = e;  
+    }
+    if (error === null) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was not thrown."');
+    }
+    if (error.toString() !== expected) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was "' + error + '"');
+    }
+}
+
+
+function bar() {
+    {
+        let f = 20;
+        let value = 10; 
+        eval("function f() { value = 20; }; f();");
+    }
+}
+
+
+for (var i = 0; i < 10000; i++){
+    assertThrow(() => bar(), "SyntaxError: Can't create duplicate variable in eval: 'f'");
+    assertThrow(() => f, "ReferenceError: Can't find variable: f");
+}
+
+function baz() {
+    {
+        var l = 20;
+        var value = 10;
+        eval("function l() { value = 20; }; l();");
+        assert(typeof l, 'function');
+        assert(value, 20);
+    }
+    assert(typeof l, 'function');
+}
+
+for (var i = 0; i < 10000; i++){
+    baz();
+    assertThrow(() => l, "ReferenceError: Can't find variable: l");
+}
+
+function foobar() {
+    {
+        let g = 20;
+        let value = 10;
+        eval("function l() { value = 30; }; l();");
+        assert(typeof g, 'number');
+        assert(value, 30);
+    }
+    assertThrow(() => g, "ReferenceError: Can't find variable: g");
+}
+
+foobar();
+assertThrow(() => g, "ReferenceError: Can't find variable: g");
+
diff --git a/JSTests/stress/eval-func-decl-in-global.js b/JSTests/stress/eval-func-decl-in-global.js
new file mode 100644 (file)
index 0000000..36e1f48
--- /dev/null
@@ -0,0 +1,37 @@
+var assert = function (result, expected, message) {
+    if (result !== expected) {
+        throw new Error('Error in assert. Expected "' + expected + '" but was "' + result + '":' + message );
+    }
+};
+
+var assertThrow = function (cb, expected) {
+    let error = null;
+    try {
+        cb();
+    } catch(e) {
+        error = e;  
+    }
+    if (error === null) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was not thrown."');
+    }
+    if (error.toString() !== expected) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was "' + error + '"');
+    }
+};
+
+var foo = 'foo';
+var success = false;
+// FIXME: According to spec foo should have value 'undefined', 
+// but possible it would be changed https://github.com/tc39/ecma262/issues/753 
+eval("success = foo === 'foo'; { function foo(){} }");
+
+assert(success, true);
+
+success = false;
+
+let boo = 'boo';
+eval("success = boo === 'boo'; { function boo(){} } success = success && boo === 'boo';");
+
+success = success && boo === 'boo';
+
+assert(success, true);
diff --git a/JSTests/stress/eval-func-decl-in-if.js b/JSTests/stress/eval-func-decl-in-if.js
new file mode 100644 (file)
index 0000000..42b515a
--- /dev/null
@@ -0,0 +1,20 @@
+var assert = function (result, expected, message) {
+    if (result !== expected) {
+        throw new Error('Error in assert. Expected-' + expected + ' but was' + result + ':' + message );
+    }
+};
+
+var updated;
+
+(function() {
+  eval(
+    '{\
+      function f() {\
+        return "first declaration";\
+      }\
+    }if (true) function f() { return "second declaration"; } else function _f() {}updated = f;'
+  );
+}());
+
+assert(typeof updated, 'function', "#1");
+assert(updated(), 'second declaration', "#2");
diff --git a/JSTests/stress/eval-func-decl-within-eval-with-reassign-to-var.js b/JSTests/stress/eval-func-decl-within-eval-with-reassign-to-var.js
new file mode 100644 (file)
index 0000000..dfd892f
--- /dev/null
@@ -0,0 +1,137 @@
+var assert = function (result, expected, message) {
+    if (result !== expected) {
+        throw new Error('Error in assert. Expected "' + expected + '" but was "' + result + '":' + message );
+    }
+};
+
+var assertThrow = function (cb, expected) {
+    let error = null;
+    try {
+        cb();
+    } catch(e) {
+        error = e;  
+    }
+    if (error === null) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was not thrown."');
+    }
+    if (error.toString() !== expected) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was "' + error + '"');
+    }
+};
+
+function foo() {
+    {
+        var f = 20;
+        eval('var f = 15; eval(" { function f() { }; } ")');
+        assert(typeof f, "function");
+    }
+    assert(typeof f, "function", "#1");
+}
+
+for (var i = 0; i < 10000; i++) {
+    foo();
+    assertThrow(() => f, "ReferenceError: Can't find variable: f");
+}
+
+function boo() {
+    {
+        var l = 20;
+        eval('{ let l = 15; eval(" { function l() { }; } ")}');
+        assert(l, 20, "#3");
+    }
+    assert(typeof l, 'number', "#4");
+}
+
+for (var i = 0; i < 10000; i++){
+    boo();
+    assertThrow(() => l, "ReferenceError: Can't find variable: l");
+}
+
+function foobar() { 
+    eval("if (false) { function _bar() { } }"); 
+    assert(_bar, undefined); 
+}
+
+for (var i = 0; i < 10000; i++){
+    foobar();
+    assertThrow(() => _bar, "ReferenceError: Can't find variable: _bar");
+}
+
+// Fixme:  https://bugs.webkit.org/show_bug.cgi?id=167837
+// Current test does not work because it should raise exception
+// that f could not be redeclared
+/*
+function goo() {
+    {   
+        var error = false;
+        try {
+            let f = 20;
+            eval('var f = 15; eval(" { function f() { }; } ")');
+        } catch (e) {
+            error = e instanceof SyntaxError;
+        }
+        assert(error, true, "syntax error should be raisen");
+    }
+    assert(typeof f, "undefined", "#6");
+}
+
+for (var i = 0; i < 10000; i++) {
+    goo();
+    assert(typeof f, "undefined", "#7");
+}
+*/
+
+function hoo() {
+    {
+        let h = 20;
+        eval('var h = 15; eval(" if (false){ function h() { }; } ");');
+        assert(h, 15);
+    }
+    assert(typeof h, "undefined");
+}
+
+for (var i = 0; i < 10000; i++) {
+    hoo();
+    assertThrow(() => h, "ReferenceError: Can't find variable: h");
+}
+
+function joo() {
+    {
+        var h = 20;
+        eval('var h = 15; eval(" if (false){ function h() { }; } ")');
+        assert(typeof h, "number");
+    }
+    assert(typeof h, "number", "#10");
+}
+
+for (var i = 0; i < 10000; i++){
+    joo();
+    assertThrow(() => h, "ReferenceError: Can't find variable: h");
+}
+
+function koo() {
+    {
+        var k = 20;
+        eval('var k = 15; eval(" if (true){ function k() { }; } ")');
+        assert(typeof k, "function" );
+    }
+    assert(typeof k, "function", "#12");
+}
+
+for (var i = 0; i < 10000; i++){
+    koo();
+    assertThrow(() => h, "ReferenceError: Can't find variable: h");
+}
+
+function loo() { 
+    let h = 20; 
+    eval("var h; if (false) { function h() { } }"); 
+    return h; 
+}
+
+assert(loo(), 20);
+
+for (var i = 0; i < 10000; i++) {
+    loo();
+    assertThrow(() => h, "ReferenceError: Can't find variable: h");
+}
diff --git a/JSTests/stress/eval-func-decl-within-eval-without-reassign-to-let.js b/JSTests/stress/eval-func-decl-within-eval-without-reassign-to-let.js
new file mode 100644 (file)
index 0000000..74dfd8f
--- /dev/null
@@ -0,0 +1,60 @@
+var assert = function (result, expected, message) {
+    if (result !== expected) {
+        throw new Error('Error in assert. Expected "' + expected + '" but was "' + result + '":' + message );
+    }
+};
+
+var assertThrow = function (cb, expected) {
+    let error = null;
+    try {
+        cb();
+    } catch(e) {
+        error = e;  
+    }
+    if (error === null) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was not thrown."');
+    }
+    if (error.toString() !== expected) {
+        throw new Error('Error is expected. Expected "' + expected + '" but error was "' + error + '"');
+    }
+};
+
+function foo() {
+    {
+        let f = 20;
+        eval('eval(" { function f() { }; } ")');
+        assert(f, 20);
+    }
+    assert(typeof f, "undefined", "#1");
+}
+
+for (var i = 0; i < 10000; i++){
+    foo();
+    assertThrow(() => f, "ReferenceError: Can't find variable: f");
+}
+
+function boo() {
+    {
+        var l = 20;
+        eval('eval(" { function l() { }; } ")');
+        assert(typeof l, 'function', "#3");
+    }
+    assert(typeof l, 'function', "#4");
+}
+
+for (var i = 0; i < 10000; i++){
+    boo();
+    assertThrow(() => l, "ReferenceError: Can't find variable: l");
+}
+
+function goo() {
+    {
+        let g = 20;
+        eval('eval(" for(var j=0; j < 10000; j++){ function g() { }; } ")');
+        assert(typeof g, 'number', "#6");
+    }
+    assertThrow(() => g, "ReferenceError: Can't find variable: g");
+}
+
+goo();
+assertThrow(() => g, "ReferenceError: Can't find variable: g");
index ce0719c..23b94c3 100644 (file)
@@ -43,7 +43,7 @@ function assert(b) {
     try {
         let b = {a: eval("function b(){ return b; }"), b: (1, eval)("(b())")};
     } catch(e) {
-        threw = e instanceof ReferenceError;
+        threw = e instanceof SyntaxError;
     }
     assert(threw);
 }
@@ -53,7 +53,7 @@ function assert(b) {
     try {
         let {b} = {a: eval("function b(){ return b; }"), b: (1, eval)("print(b())")};
     } catch(e) {
-        threw = e instanceof ReferenceError;
+        threw = e instanceof SyntaxError;
     }
     assert(threw);
 }
index 3c2387d..11562e3 100644 (file)
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-block-scoping.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-exsting-var-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-param.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-block-decl-eval-func-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-block-scoping.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-exsting-var-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-param.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-a-eval-func-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-block-scoping.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-exsting-var-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-param.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-decl-b-eval-func-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-block-scoping.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-exsting-var-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-param.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-else-stmt-eval-func-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-block-scoping.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-exsting-var-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-param.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-decl-no-else-eval-func-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-block-scoping.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-exsting-var-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-param.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-if-stmt-else-decl-eval-func-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-block-scoping.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-exsting-var-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-param.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-case-eval-func-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-block-scoping.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-exsting-var-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-param.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/func-switch-dflt-eval-func-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-block-decl-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-a-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-decl-b-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-else-stmt-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-decl-no-else-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-if-stmt-else-decl-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-case-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/global-switch-dflt-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-block-decl-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-decl-no-else-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-if-stmt-else-decl-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-case-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-block-scoping.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-exsting-block-fn-no-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-exsting-block-fn-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-exsting-fn-no-init.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-exsting-fn-update.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-exsting-global-init.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-exsting-global-update.js
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-exsting-var-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-init.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/fnGlobalObject.js", "../../../../../harness/propertyHelper.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-no-skip-try.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-block.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-for-in.js
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err-try.js
   cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-skip-early-err.js
-  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
+  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/eval-code/indirect/global-switch-dflt-eval-global-update.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
 - path: test262/test/annexB/language/expressions/object/__proto__-duplicate.js
index 741d0a1..322b777 100644 (file)
@@ -1,3 +1,15 @@
+2017-04-18  Oleksandr Skachkov  <gskachkov@gmail.com>
+
+        [ES6]. Implement Annex B.3.3 function hoisting rules for eval
+        https://bugs.webkit.org/show_bug.cgi?id=163208
+
+        Reviewed by Saam Barati.
+
+        * inspector/runtime/evaluate-CommandLineAPI-expected.txt:
+        * inspector/runtime/evaluate-CommandLineAPI.html:
+        * js/parser-syntax-check-expected.txt:
+        * js/script-tests/parser-syntax-check.js:
+
 2017-04-18  Antti Koivisto  <antti@apple.com>
 
         Enable optimized layer flushes on iOS
index 571cd90..de43b08 100644 (file)
@@ -34,3 +34,8 @@ PASS: Global `keys` variable should not be shadowed by CommandLineAPI function.
 -- Running test case: CommandLineAPIDoesNotShadowGlobalObjectProperties
 PASS: `values` should be `window.values` and not shadowed by CommandLineAPI `values` function.
 
+-- Running test case: NonStrictEvalHoistEvaluations
+PASS: Should be able to access var in global scope.
+PASS: Should be able to hoist function to var in global scope.
+PASS: Should be able to hoist function to var in global scope and keep it.
+
index 9f05285..e6ed679 100644 (file)
@@ -6,6 +6,7 @@
 var varGlobalVariable = 1;
 let letGlobalVariable = 2;
 const constGlobalVariable = 3;
+var varGlobalFunctionVariable = 4;
 
 function test()
 {
@@ -168,6 +169,27 @@ function test()
         }
     });
 
+    suite.addTestCase({
+        name: "NonStrictEvalHoistEvaluations",
+        description: "Test CommandLineAPI does not shadow global object variable that hoisted from eval.",
+        test(resolve, reject) {
+            testEvaluate("varGlobalFunctionVariable", (resultValue) => {
+                InspectorTest.expectThat(resultValue === 4, "Should be able to access var in global scope.");
+            });            
+            testEvaluate(`
+                let noError = varGlobalFunctionVariable === 4;
+                eval('eval(" { function varGlobalFunctionVariable() { }; } ")');
+                typeof varGlobalFunctionVariable === 'function' && noError;
+            `, (resultValue) => {
+                InspectorTest.expectThat(resultValue, "Should be able to hoist function to var in global scope.");
+            });
+            testEvaluate("varGlobalFunctionVariable", (resultValue) => {
+                InspectorTest.expectThat(typeof resultValue, "Should be able to hoist function to var in global scope and keep it.");
+                resolve();
+            });    
+        }
+    });
+
     suite.runTestCasesAndFinish();
 }
 </script>
index 1a60d80..691cc75 100644 (file)
@@ -688,11 +688,11 @@ PASS Invalid: "function foo() { let f1; function f1(a) {}; }". Produced the foll
 PASS Invalid: "function f() { function foo() { let f1; function f1(a) {}; } }". Produced the following syntax error: "SyntaxError: Cannot declare a function that shadows a let/const/class/function variable 'f1' in strict mode."
 PASS Invalid: "let f1; function f1(a) {};". Produced the following syntax error: "SyntaxError: Cannot declare a function that shadows a let/const/class/function variable 'f1' in strict mode."
 PASS Invalid: "function f() { let f1; function f1(a) {}; }". Produced the following syntax error: "SyntaxError: Cannot declare a function that shadows a let/const/class/function variable 'f1' in strict mode."
-PASS Valid:   "{ function f1(a) {}; let f1; }"
+PASS Invalid: "{ function f1(a) {}; let f1; }". Produced the following syntax error: "SyntaxError: Cannot declare a let variable twice: 'f1'."
 PASS Invalid: "function f() { { function f1(a) {}; let f1; } }". Produced the following syntax error: "SyntaxError: Cannot declare a let variable twice: 'f1'."
-PASS Valid:   "{ function f1(a) {}; const f1 = 25; }"
+PASS Invalid: "{ function f1(a) {}; const f1 = 25; }". Produced the following syntax error: "SyntaxError: Cannot declare a const variable twice: 'f1'."
 PASS Invalid: "function f() { { function f1(a) {}; const f1 = 25; } }". Produced the following syntax error: "SyntaxError: Cannot declare a const variable twice: 'f1'."
-PASS Valid:   "{ function f1(a) {}; class f1{}; }"
+PASS Invalid: "{ function f1(a) {}; class f1{}; }". Produced the following syntax error: "SyntaxError: Cannot declare a class twice: 'f1'."
 PASS Invalid: "function f() { { function f1(a) {}; class f1{}; } }". Produced the following syntax error: "SyntaxError: Cannot declare a class twice: 'f1'."
 PASS Invalid: "function foo() { { let bar; function bar() { } } }". Produced the following syntax error: "SyntaxError: Cannot declare a function that shadows a let/const/class/function variable 'bar' in strict mode."
 PASS Invalid: "function f() { function foo() { { let bar; function bar() { } } } }". Produced the following syntax error: "SyntaxError: Cannot declare a function that shadows a let/const/class/function variable 'bar' in strict mode."
@@ -708,15 +708,15 @@ PASS Invalid: "function foo() { { function bar() { }; class bar{}; } }". Produce
 PASS Invalid: "function f() { function foo() { { function bar() { }; class bar{}; } } }". Produced the following syntax error: "SyntaxError: Cannot declare a class twice: 'bar'."
 PASS Valid:   "switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; }"
 PASS Valid:   "function f() { switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; } }"
-PASS Valid:   "switch('foo') { case 1: let foo; function foo() {}; break; case 2: function foo() {}; break; }"
+PASS Invalid: "switch('foo') { case 1: let foo; function foo() {}; break; case 2: function foo() {}; break; }". Produced the following syntax error: "SyntaxError: Cannot declare a function that shadows a let/const/class/function variable 'foo' in strict mode."
 PASS Invalid: "function f() { switch('foo') { case 1: let foo; function foo() {}; break; case 2: function foo() {}; break; } }". Produced the following syntax error: "SyntaxError: Cannot declare a function that shadows a let/const/class/function variable 'foo' in strict mode."
-PASS Valid:   "switch('foo') { case 1: function foo() {}; let foo; break; case 2: function foo() {}; break; }"
+PASS Invalid: "switch('foo') { case 1: function foo() {}; let foo; break; case 2: function foo() {}; break; }". Produced the following syntax error: "SyntaxError: Cannot declare a let variable twice: 'foo'."
 PASS Invalid: "function f() { switch('foo') { case 1: function foo() {}; let foo; break; case 2: function foo() {}; break; } }". Produced the following syntax error: "SyntaxError: Cannot declare a let variable twice: 'foo'."
-PASS Valid:   "switch('foo') { case 1: function foo() {}; const foo = 25; break; case 2: function foo() {}; break; }"
+PASS Invalid: "switch('foo') { case 1: function foo() {}; const foo = 25; break; case 2: function foo() {}; break; }". Produced the following syntax error: "SyntaxError: Cannot declare a const variable twice: 'foo'."
 PASS Invalid: "function f() { switch('foo') { case 1: function foo() {}; const foo = 25; break; case 2: function foo() {}; break; } }". Produced the following syntax error: "SyntaxError: Cannot declare a const variable twice: 'foo'."
-PASS Valid:   "switch('foo') { case 1: function foo() {}; class foo {} ; break; case 2: function foo() {}; break; }"
+PASS Invalid: "switch('foo') { case 1: function foo() {}; class foo {} ; break; case 2: function foo() {}; break; }". Produced the following syntax error: "SyntaxError: Cannot declare a class twice: 'foo'."
 PASS Invalid: "function f() { switch('foo') { case 1: function foo() {}; class foo {} ; break; case 2: function foo() {}; break; } }". Produced the following syntax error: "SyntaxError: Cannot declare a class twice: 'foo'."
-PASS Valid:   "switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; case 3: let foo; }"
+PASS Invalid: "switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; case 3: let foo; }". Produced the following syntax error: "SyntaxError: Cannot declare a let variable twice: 'foo'."
 PASS Invalid: "function f() { switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; case 3: let foo; } }". Produced the following syntax error: "SyntaxError: Cannot declare a let variable twice: 'foo'."
 PASS Valid:   "function foo() { switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; case 3: { let foo; } } }"
 PASS Valid:   "function f() { function foo() { switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; case 3: { let foo; } } } }"
@@ -734,13 +734,13 @@ PASS Invalid: "'use strict'; if (true) function foo() { }; ". Produced the follo
 PASS Invalid: "function f() { 'use strict'; if (true) function foo() { };  }". Produced the following syntax error: "SyntaxError: Function declarations are only allowed inside blocks or switch statements in strict mode."
 PASS Valid:   "if (true) function foo() { }; "
 PASS Valid:   "function f() { if (true) function foo() { };  }"
-PASS Invalid: " let foo; if (true) function foo() { };". Produced the following syntax error: "SyntaxError: Cannot declare a function that shadows a let/const/class/function variable 'foo' in strict mode."
+PASS Valid:   " let foo; if (true) function foo() { };"
 PASS Valid:   "function f() {  let foo; if (true) function foo() { }; }"
 PASS Valid:   "function baz() { let foo; if (true) function foo() { }; }"
 PASS Valid:   "function f() { function baz() { let foo; if (true) function foo() { }; } }"
-PASS Invalid: "if (true) function foo() { }; let foo;". Produced the following syntax error: "SyntaxError: Cannot declare a let variable twice: 'foo'."
+PASS Valid:   "if (true) function foo() { }; let foo;"
 PASS Valid:   "function f() { if (true) function foo() { }; let foo; }"
-PASS Invalid: "{ if (true) function foo() { }; } let foo;". Produced the following syntax error: "SyntaxError: Cannot declare a let variable twice: 'foo'."
+PASS Valid:   "{ if (true) function foo() { }; } let foo;"
 PASS Valid:   "function f() { { if (true) function foo() { }; } let foo; }"
 PASS Invalid: "let foo; while (false) function foo() { }; ". Produced the following syntax error: "SyntaxError: Unexpected keyword 'function'. Function declarations are only allowed inside block statements or at the top level of a program."
 PASS Invalid: "function f() { let foo; while (false) function foo() { };  }". Produced the following syntax error: "SyntaxError: Unexpected keyword 'function'. Function declarations are only allowed inside block statements or at the top level of a program."
index bb98bb8..2061390 100644 (file)
@@ -446,9 +446,9 @@ valid("function foo() { { function foo() { }; function foo() { } } }")
 invalid("function foo() { 'use strict'; { function foo() { }; function foo() { } } }")
 invalid("function foo() { let f1; function f1(a) {}; }")
 invalid("let f1; function f1(a) {};")
-onlyValidGlobally("{ function f1(a) {}; let f1; }")
-onlyValidGlobally("{ function f1(a) {}; const f1 = 25; }")
-onlyValidGlobally("{ function f1(a) {}; class f1{}; }")
+invalid("{ function f1(a) {}; let f1; }")
+invalid("{ function f1(a) {}; const f1 = 25; }")
+invalid("{ function f1(a) {}; class f1{}; }")
 invalid("function foo() { { let bar; function bar() { } } }")
 invalid("function foo() { { function bar() { }; let bar; } }")
 invalid("function foo() { { const bar; function bar() { } } }")
@@ -456,11 +456,11 @@ invalid("function foo() { { function bar() { }; const bar; } }")
 invalid("function foo() { { class bar{}; function bar() { } } }")
 invalid("function foo() { { function bar() { }; class bar{}; } }")
 valid("switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; }")
-onlyValidGlobally("switch('foo') { case 1: let foo; function foo() {}; break; case 2: function foo() {}; break; }")
-onlyValidGlobally("switch('foo') { case 1: function foo() {}; let foo; break; case 2: function foo() {}; break; }")
-onlyValidGlobally("switch('foo') { case 1: function foo() {}; const foo = 25; break; case 2: function foo() {}; break; }")
-onlyValidGlobally("switch('foo') { case 1: function foo() {}; class foo {} ; break; case 2: function foo() {}; break; }")
-onlyValidGlobally("switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; case 3: let foo; }")
+invalid("switch('foo') { case 1: let foo; function foo() {}; break; case 2: function foo() {}; break; }")
+invalid("switch('foo') { case 1: function foo() {}; let foo; break; case 2: function foo() {}; break; }")
+invalid("switch('foo') { case 1: function foo() {}; const foo = 25; break; case 2: function foo() {}; break; }")
+invalid("switch('foo') { case 1: function foo() {}; class foo {} ; break; case 2: function foo() {}; break; }")
+invalid("switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; case 3: let foo; }")
 valid("function foo() { switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; case 3: { let foo; } } }")
 invalid("'use strict'; switch('foo') { case 1: function foo() {}; break; case 2: function foo() {}; break; }");
 invalid("'use strict'; switch('foo') { case 1: function foo() {}; break; case 2: let foo; break; }");
@@ -469,10 +469,10 @@ valid("'use strict'; switch('foo') { case 1: { let foo; break; } case 2: functio
 valid("'use strict'; switch('foo') { case 1: { function foo() { }; break; } case 2: function foo() {}; break; }");
 invalid("'use strict'; if (true) function foo() { }; ");
 valid("if (true) function foo() { }; ");
-onlyInvalidGlobally(" let foo; if (true) function foo() { };");
+valid(" let foo; if (true) function foo() { };");
 valid("function baz() { let foo; if (true) function foo() { }; }");
-onlyInvalidGlobally("if (true) function foo() { }; let foo;");
-onlyInvalidGlobally("{ if (true) function foo() { }; } let foo;");
+valid("if (true) function foo() { }; let foo;");
+valid("{ if (true) function foo() { }; } let foo;");
 invalid("let foo; while (false) function foo() { }; ");
 invalid("let foo;  { while (false) function foo() { }; } ");
 invalid("while (false) function foo() { }; let foo;");
index 6d29877..813ef5f 100644 (file)
@@ -1,3 +1,153 @@
+2017-04-18  Oleksandr Skachkov  <gskachkov@gmail.com>
+
+        [ES6]. Implement Annex B.3.3 function hoisting rules for eval
+        https://bugs.webkit.org/show_bug.cgi?id=163208
+
+        Reviewed by Saam Barati.
+
+        Current patch implements Annex B.3.3 that is related to 
+        hoisting of function declaration in eval. 
+        https://tc39.github.io/ecma262/#sec-web-compat-evaldeclarationinstantiation
+        Function declaration in eval should create variable with 
+        function name in function scope where eval is invoked 
+        or bind to variable if it declared outside of the eval. 
+        If variable is created it can be removed by 'delete a;' command. 
+        If eval is invoke in block scope that contains let/const 
+        variable with the same name as function declaration 
+        we do not bind. This patch leads to the following behavior: 
+        '''
+        function foo() {
+           {
+             print(boo); // undefined
+             eval('{ function boo() {}}');
+             print(boo); // function boo() {}
+           }
+           print(boo); // function boo() {}
+        }
+
+        function foobar() {
+          { 
+            let boo = 10;
+            print(boo); // 10;
+            eval('{ function boo() {}}');
+            print(boo); // 10;
+          }
+          print(boo) // 10
+        }
+
+        function bar() {
+           {
+              var boo = 10;
+              print(boo); // 10
+              eval('{ function boo() {} }'); 
+              print(boo); // function boo() {}
+           }
+           print(boo); // function boo() {}
+        }       
+        
+        function bas() {
+            {
+                 let boo = 10;
+                 eval(' { function boo() {} } ');
+                 print(boo); // 10
+            }
+            print(boo); //Reference Error
+        }
+        '''
+
+        Current implementation relies on already implemented 
+        'hoist function in sloppy mode' feature, with small changes.
+        In short it works in following way: during hoisting of function 
+        with name S in eval, we are looking for first scope that 
+        contains space for variable with name S and if this scope 
+        has var type we bind function there
+
+        To implement this feature was added bytecode ops:
+        op_resolve_scope_for_hoisting_func_decl_in_eval - get variable scope 
+        or return undefined if variable can't be binded there.
+
+        There is a corner case, hoist function in eval within catch block,
+        that is not covered by this patch, and will be fixed in 
+        https://bugs.webkit.org/show_bug.cgi?id=168184
+
+        * bytecode/BytecodeDumper.cpp:
+        (JSC::BytecodeDumper<Block>::dumpBytecode):
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::finalizeLLIntInlineCaches):
+        * bytecode/EvalCodeBlock.h:
+        (JSC::EvalCodeBlock::functionHoistingCandidate):
+        (JSC::EvalCodeBlock::numFunctionHoistingCandidates):
+        * bytecode/UnlinkedEvalCodeBlock.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::hoistSloppyModeFunctionIfNecessary):
+        (JSC::BytecodeGenerator::emitResolveScopeForHoistingFuncDeclInEval):
+        * bytecompiler/BytecodeGenerator.h:
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::hasIdentifier):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileResolveScopeForHoistingFuncDeclInEval):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileResolveScopeForHoistingFuncDeclInEval):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_resolve_scope_for_hoisting_func_decl_in_eval):
+        * jit/JITPropertyAccess32_64.cpp:
+        (JSC::JIT::emit_op_resolve_scope_for_hoisting_func_decl_in_eval):
+        * llint/LowLevelInterpreter.asm:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseFunctionDeclarationStatement):
+        * parser/Parser.h:
+        (JSC::Scope::getSloppyModeHoistedFunctions):
+        (JSC::Parser::declareFunction):
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/EvalExecutable.h:
+        (JSC::EvalExecutable::numFunctionHoistingCandidates):
+        (JSC::EvalExecutable::numTopLevelFunctionDecls):
+        (JSC::EvalExecutable::numberOfFunctionDecls): Deleted.
+        * runtime/JSScope.cpp:
+        (JSC::JSScope::resolve):
+        (JSC::JSScope::resolveScopeForHoistingFuncDeclInEval):
+        * runtime/JSScope.h:
+
 2017-04-18  Saam Barati  <sbarati@apple.com>
 
         Follow up to address Mark's comments after r215453
index 3ab162e..a73ffdd 100644 (file)
@@ -1569,6 +1569,14 @@ void BytecodeDumper<Block>::dumpBytecode(PrintStream& out, const typename Block:
         printLocationOpAndRegisterOperand(out, location, it, "end", r0);
         break;
     }
+    case op_resolve_scope_for_hoisting_func_decl_in_eval: {
+        int r0 = (++it)->u.operand;
+        int scope = (++it)->u.operand;
+        int id0 = (++it)->u.operand;
+        printLocationAndOp(out, location, it, "resolve_scope_for_hoisting_func_decl_in_eval");
+        out.printf("%s, %s, %s", registerName(r0).data(), registerName(scope).data(), idName(id0, identifier(id0)).data());
+        break;
+    }
     case op_resolve_scope: {
         int r0 = (++it)->u.operand;
         int scope = (++it)->u.operand;
index 0827af9..2b1cae2 100644 (file)
             { "name" : "op_yield", "length" : 4 },
             { "name" : "op_check_traps", "length" : 1 },
             { "name" : "op_log_shadow_chicken_prologue", "length" : 2},
-            { "name" : "op_log_shadow_chicken_tail", "length" : 3}
+            { "name" : "op_log_shadow_chicken_tail", "length" : 3},
+            { "name" : "op_resolve_scope_for_hoisting_func_decl_in_eval", "length" : 4 }
         ]
     },
     {
index e097e10..30f0545 100644 (file)
@@ -170,6 +170,7 @@ void computeUsesForBytecodeOffset(Block* codeBlock, OpcodeID opcodeID, Instructi
     case op_to_index_string:
     case op_create_lexical_environment:
     case op_resolve_scope:
+    case op_resolve_scope_for_hoisting_func_decl_in_eval:
     case op_get_from_scope:
     case op_to_primitive:
     case op_try_get_by_id:
@@ -382,6 +383,7 @@ void computeDefsForBytecodeOffset(Block* codeBlock, OpcodeID opcodeID, Instructi
     case op_push_with_scope:
     case op_create_lexical_environment:
     case op_resolve_scope:
+    case op_resolve_scope_for_hoisting_func_decl_in_eval:
     case op_strcat:
     case op_to_primitive:
     case op_create_this:
index f0a29df..671a466 100644 (file)
@@ -1315,6 +1315,10 @@ void CodeBlock::finalizeLLIntInlineCaches()
             curInstruction[7].u.structureChain.clear();
             break;
         }
+        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=166418
+        // We need to add optimizations for op_resolve_scope_for_hoisting_func_decl_in_eval to do link time scope resolution.
+        case op_resolve_scope_for_hoisting_func_decl_in_eval:
+            break;
         case op_get_array_length:
             break;
         case op_to_this:
index 3a63817..4adb487 100644 (file)
@@ -63,6 +63,8 @@ public:
 
     const Identifier& variable(unsigned index) { return unlinkedEvalCodeBlock()->variable(index); }
     unsigned numVariables() { return unlinkedEvalCodeBlock()->numVariables(); }
+    const Identifier& functionHoistingCandidate(unsigned index) { return unlinkedEvalCodeBlock()->functionHoistingCandidate(index); }
+    unsigned numFunctionHoistingCandidates() { return unlinkedEvalCodeBlock()->numFunctionHoistingCandidates(); }
     
 private:
     EvalCodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, EvalCodeBlock& other)
index 3130ea4..9987b43 100644 (file)
@@ -51,6 +51,13 @@ public:
         m_variables.swap(variables);
     }
 
+    const Identifier& functionHoistingCandidate(unsigned index) { return m_functionHoistingCandidates[index]; }
+    unsigned numFunctionHoistingCandidates() { return m_functionHoistingCandidates.size(); }
+    void adoptFunctionHoistingCandidates(Vector<Identifier, 0, UnsafeVectorOverflow>&& functionHoistingCandidates)
+    {
+        ASSERT(m_functionHoistingCandidates.isEmpty());
+        m_functionHoistingCandidates = WTFMove(functionHoistingCandidates);
+    }
 private:
     UnlinkedEvalCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info, DebuggerMode debuggerMode)
         : Base(vm, structure, EvalCode, info, debuggerMode)
@@ -58,6 +65,7 @@ private:
     }
 
     Vector<Identifier, 0, UnsafeVectorOverflow> m_variables;
+    Vector<Identifier, 0, UnsafeVectorOverflow> m_functionHoistingCandidates;
 
 public:
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
index fec3822..ad0f417 100644 (file)
@@ -756,20 +756,22 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCod
 
     emitCheckTraps();
     
-    const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
-    for (size_t i = 0; i < functionStack.size(); ++i)
-        m_codeBlock->addFunctionDecl(makeFunction(functionStack[i]));
+    for (FunctionMetadataNode* function : evalNode->functionStack())
+        m_codeBlock->addFunctionDecl(makeFunction(function));
 
     const VariableEnvironment& varDeclarations = evalNode->varDeclarations();
-    unsigned numVariables = varDeclarations.size();
     Vector<Identifier, 0, UnsafeVectorOverflow> variables;
-    variables.reserveCapacity(numVariables);
+    Vector<Identifier, 0, UnsafeVectorOverflow> hoistedFunctions;
     for (auto& entry : varDeclarations) {
         ASSERT(entry.value.isVar());
         ASSERT(entry.key->isAtomic() || entry.key->isSymbol());
-        variables.append(Identifier::fromUid(m_vm, entry.key.get()));
+        if (entry.value.isSloppyModeHoistingCandidate())
+            hoistedFunctions.append(Identifier::fromUid(m_vm, entry.key.get()));
+        else
+            variables.append(Identifier::fromUid(m_vm, entry.key.get()));
     }
     codeBlock->adoptVariables(variables);
+    codeBlock->adoptFunctionHoistingCandidates(WTFMove(hoistedFunctions));
     
     if (evalNode->usesSuperCall() || evalNode->usesNewTarget())
         m_newTargetRegister = addVar();
@@ -2175,38 +2177,72 @@ void BytecodeGenerator::initializeBlockScopedFunctions(VariableEnvironment& envi
 void BytecodeGenerator::hoistSloppyModeFunctionIfNecessary(const Identifier& functionName)
 {
     if (m_scopeNode->hasSloppyModeHoistedFunction(functionName.impl())) {
-        Variable currentFunctionVariable = variable(functionName);
-        RefPtr<RegisterID> currentValue;
-        if (RegisterID* local = currentFunctionVariable.local())
-            currentValue = local;
-        else {
-            RefPtr<RegisterID> scope = emitResolveScope(nullptr, currentFunctionVariable);
-            currentValue = emitGetFromScope(newTemporary(), scope.get(), currentFunctionVariable, DoNotThrowIfNotFound);
-        }
-        
-        ASSERT(m_varScopeLexicalScopeStackIndex);
-        ASSERT(*m_varScopeLexicalScopeStackIndex < m_lexicalScopeStack.size());
-        LexicalScopeStackEntry varScope = m_lexicalScopeStack[*m_varScopeLexicalScopeStackIndex];
-        SymbolTable* varSymbolTable = varScope.m_symbolTable;
-        ASSERT(varSymbolTable->scopeType() == SymbolTable::ScopeType::VarScope);
-        SymbolTableEntry entry = varSymbolTable->get(NoLockingNecessary, functionName.impl());
-        if (functionName == propertyNames().arguments && entry.isNull()) {
-            // "arguments" might be put in the parameter scope when we have a non-simple
-            // parameter list since "arguments" is visible to expressions inside the
-            // parameter evaluation list.
-            // e.g:
-            // function foo(x = arguments) { { function arguments() { } } }
-            RELEASE_ASSERT(*m_varScopeLexicalScopeStackIndex > 0);
-            varScope = m_lexicalScopeStack[*m_varScopeLexicalScopeStackIndex - 1];
-            SymbolTable* parameterSymbolTable = varScope.m_symbolTable;
-            entry = parameterSymbolTable->get(NoLockingNecessary, functionName.impl());
+        if (codeType() != EvalCode) {
+            Variable currentFunctionVariable = variable(functionName);
+            RefPtr<RegisterID> currentValue;
+            if (RegisterID* local = currentFunctionVariable.local())
+                currentValue = local;
+            else {
+                RefPtr<RegisterID> scope = emitResolveScope(nullptr, currentFunctionVariable);
+                currentValue = emitGetFromScope(newTemporary(), scope.get(), currentFunctionVariable, DoNotThrowIfNotFound);
+            }
+
+            ASSERT(m_varScopeLexicalScopeStackIndex);
+            ASSERT(*m_varScopeLexicalScopeStackIndex < m_lexicalScopeStack.size());
+            LexicalScopeStackEntry varScope = m_lexicalScopeStack[*m_varScopeLexicalScopeStackIndex];
+            SymbolTable* varSymbolTable = varScope.m_symbolTable;
+            ASSERT(varSymbolTable->scopeType() == SymbolTable::ScopeType::VarScope);
+            SymbolTableEntry entry = varSymbolTable->get(NoLockingNecessary, functionName.impl());
+            if (functionName == propertyNames().arguments && entry.isNull()) {
+                // "arguments" might be put in the parameter scope when we have a non-simple
+                // parameter list since "arguments" is visible to expressions inside the
+                // parameter evaluation list.
+                // e.g:
+                // function foo(x = arguments) { { function arguments() { } } }
+                RELEASE_ASSERT(*m_varScopeLexicalScopeStackIndex > 0);
+                varScope = m_lexicalScopeStack[*m_varScopeLexicalScopeStackIndex - 1];
+                SymbolTable* parameterSymbolTable = varScope.m_symbolTable;
+                entry = parameterSymbolTable->get(NoLockingNecessary, functionName.impl());
+            }
+            RELEASE_ASSERT(!entry.isNull());
+            bool isLexicallyScoped = false;
+            emitPutToScope(varScope.m_scope, variableForLocalEntry(functionName, entry, varScope.m_symbolTableConstantIndex, isLexicallyScoped), currentValue.get(), DoNotThrowIfNotFound, InitializationMode::NotInitialization);
+        } else {
+            Variable currentFunctionVariable = variable(functionName);
+            RefPtr<RegisterID> currentValue;
+            if (RegisterID* local = currentFunctionVariable.local())
+                currentValue = local;
+            else {
+                RefPtr<RegisterID> scope = emitResolveScope(nullptr, currentFunctionVariable);
+                currentValue = emitGetFromScope(newTemporary(), scope.get(), currentFunctionVariable, DoNotThrowIfNotFound);
+            }
+
+            RefPtr<RegisterID> scopeId = emitResolveScopeForHoistingFuncDeclInEval(nullptr, functionName);
+            RefPtr<RegisterID> checkResult = emitIsUndefined(newTemporary(), scopeId.get());
+            
+            Ref<Label> isNotVarScopeLabel = newLabel();
+            emitJumpIfTrue(checkResult.get(), isNotVarScopeLabel.get());
+
+            // Put to outer scope
+            emitPutToScope(scopeId.get(), functionName, currentValue.get(), DoNotThrowIfNotFound, InitializationMode::NotInitialization);
+            emitLabel(isNotVarScopeLabel.get());
+
         }
-        RELEASE_ASSERT(!entry.isNull());
-        bool isLexicallyScoped = false;
-        emitPutToScope(varScope.m_scope, variableForLocalEntry(functionName, entry, varScope.m_symbolTableConstantIndex, isLexicallyScoped), currentValue.get(), DoNotThrowIfNotFound, InitializationMode::NotInitialization);
     }
 }
 
+RegisterID* BytecodeGenerator::emitResolveScopeForHoistingFuncDeclInEval(RegisterID* dst, const Identifier& property)
+{
+    ASSERT(m_codeType == EvalCode);
+
+    dst = finalDestination(dst);
+    emitOpcode(op_resolve_scope_for_hoisting_func_decl_in_eval);
+    instructions().append(kill(dst));
+    instructions().append(m_topMostScope->index());
+    instructions().append(addConstant(property));
+    return dst;
+}
+
 void BytecodeGenerator::popLexicalScope(VariableEnvironmentNode* node)
 {
     VariableEnvironment& environment = node->lexicalVariables();
index 16a30a0..eec0a4f 100644 (file)
@@ -693,6 +693,9 @@ namespace JSC {
         RegisterID* emitResolveScope(RegisterID* dst, const Variable&);
         RegisterID* emitGetFromScope(RegisterID* dst, RegisterID* scope, const Variable&, ResolveMode);
         RegisterID* emitPutToScope(RegisterID* scope, const Variable&, RegisterID* value, ResolveMode, InitializationMode);
+
+        RegisterID* emitResolveScopeForHoistingFuncDeclInEval(RegisterID* dst, const Identifier&);
+
         RegisterID* initializeVariable(const Variable&, RegisterID* value);
 
         void emitLabel(Label&);
index cba0d6c..cf710b6 100644 (file)
@@ -2855,11 +2855,16 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
         clobberWorld(node->origin.semantic, clobberLimit);
         forNode(node).setType(m_graph, SpecObject);
         break;
-        
+
+    case ResolveScopeForHoistingFuncDeclInEval:
+        clobberWorld(node->origin.semantic, clobberLimit);
+        forNode(node).makeBytecodeTop();
+        break;
+
     case PutGlobalVariable:
     case NotifyWrite:
         break;
-            
+
     case OverridesHasInstance:
         forNode(node).setType(SpecBoolean);
         break;
index 0f99e61..e72fa64 100644 (file)
@@ -5118,6 +5118,15 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             }
             NEXT_OPCODE(op_resolve_scope);
         }
+        case op_resolve_scope_for_hoisting_func_decl_in_eval: {
+            int dst = currentInstruction[1].u.operand;
+            int scope = currentInstruction[2].u.operand;
+            unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[currentInstruction[3].u.operand];
+
+            set(VirtualRegister(dst), addToGraph(ResolveScopeForHoistingFuncDeclInEval, OpInfo(identifierNumber), get(VirtualRegister(scope))));
+
+            NEXT_OPCODE(op_resolve_scope_for_hoisting_func_decl_in_eval);
+        }
 
         case op_get_from_scope: {
             int dst = currentInstruction[1].u.operand;
index fde32e2..842889e 100644 (file)
@@ -247,6 +247,7 @@ CapabilityLevel capabilityLevel(OpcodeID opcodeID, CodeBlock* codeBlock, Instruc
     case op_log_shadow_chicken_tail:
     case op_put_to_scope:
     case op_resolve_scope:
+    case op_resolve_scope_for_hoisting_func_decl_in_eval:
     case op_new_regexp:
         return CanCompileAndInline;
 
index 8b30fc0..d2ceefe 100644 (file)
@@ -564,6 +564,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
     case SetFunctionName:
     case GetDynamicVar:
     case PutDynamicVar:
+    case ResolveScopeForHoistingFuncDeclInEval:
     case ResolveScope:
         read(World);
         write(Heap);
index b96a362..87eb27c 100644 (file)
@@ -267,6 +267,7 @@ bool doesGC(Graph& graph, Node* node)
     case LogShadowChickenTail:
     case GetDynamicVar:
     case PutDynamicVar:
+    case ResolveScopeForHoistingFuncDeclInEval:
     case ResolveScope:
     case NukeStructureAndSetButterfly:
         return false;
index fb5e8b1..e45d9c4 100644 (file)
@@ -1661,6 +1661,10 @@ private:
             break;
         }
 
+        case ResolveScopeForHoistingFuncDeclInEval: {
+            fixEdge<KnownCellUse>(node->child1());
+            break;
+        }
         case ResolveScope:
         case GetDynamicVar:
         case PutDynamicVar: {
index df5c28a..7804502 100644 (file)
@@ -948,6 +948,7 @@ public:
         case DeleteById:
         case GetDynamicVar:
         case PutDynamicVar:
+        case ResolveScopeForHoistingFuncDeclInEval:
         case ResolveScope:
             return true;
         default:
index 6c62ce6..57348b9 100644 (file)
@@ -226,6 +226,7 @@ namespace JSC { namespace DFG {
     macro(GetScope, NodeResultJS) \
     macro(SkipScope, NodeResultJS) \
     macro(ResolveScope, NodeResultJS | NodeMustGenerate) \
+    macro(ResolveScopeForHoistingFuncDeclInEval, NodeResultJS | NodeMustGenerate) \
     macro(GetGlobalObject, NodeResultJS) \
     macro(GetClosureVar, NodeResultJS) \
     macro(PutClosureVar, NodeMustGenerate) \
index f04aca5..5afeb66 100644 (file)
@@ -2206,6 +2206,15 @@ void JIT_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void*
     dataLog("\n");
 }
 
+EncodedJSValue JIT_OPERATION operationResolveScopeForHoistingFuncDeclInEval(ExecState* exec, JSScope* scope, UniquedStringImpl* impl)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+        
+    JSValue resolvedScope = JSScope::resolveScopeForHoistingFuncDeclInEval(exec, scope, Identifier::fromUid(exec, impl));
+    return JSValue::encode(resolvedScope);
+}
+    
 JSCell* JIT_OPERATION operationResolveScope(ExecState* exec, JSScope* scope, UniquedStringImpl* impl)
 {
     VM& vm = exec->vm();
index 4386a66..ae1b062 100644 (file)
@@ -207,6 +207,7 @@ JSCell* JIT_OPERATION operationSpreadGeneric(ExecState*, JSCell*);
 JSCell* JIT_OPERATION operationNewArrayWithSpreadSlow(ExecState*, void*, uint32_t);
 
 JSCell* JIT_OPERATION operationResolveScope(ExecState*, JSScope*, UniquedStringImpl*);
+EncodedJSValue JIT_OPERATION operationResolveScopeForHoistingFuncDeclInEval(ExecState*, JSScope*, UniquedStringImpl*);
 EncodedJSValue JIT_OPERATION operationGetDynamicVar(ExecState*, JSObject* scope, UniquedStringImpl*, unsigned);
 void JIT_OPERATION operationPutDynamicVar(ExecState*, JSObject* scope, EncodedJSValue, UniquedStringImpl*, unsigned);
 
index 8753fe1..68ed03e 100644 (file)
@@ -717,6 +717,7 @@ private:
             break;
         }
 
+        case ResolveScopeForHoistingFuncDeclInEval:
         case GetDynamicVar: {
             setPrediction(SpecBytecodeTop);
             break;
index 33a3947..f6c89bd 100644 (file)
@@ -376,6 +376,7 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
     case RecordRegExpCachedResult:
     case GetDynamicVar:
     case PutDynamicVar:
+    case ResolveScopeForHoistingFuncDeclInEval:
     case ResolveScope:
     case MapHash:
     case ToLowerCase:
index 5c4e92f..bc33280 100644 (file)
@@ -9418,6 +9418,27 @@ void SpeculativeJIT::compileResolveScope(Node* node)
     cellResult(resultGPR, node);
 }
 
+void SpeculativeJIT::compileResolveScopeForHoistingFuncDeclInEval(Node* node)
+{
+    SpeculateCellOperand scope(this, node->child1());
+    GPRReg scopeGPR = scope.gpr();
+#if USE(JSVALUE64)
+    GPRFlushedCallResult result(this);
+    GPRReg resultGPR = result.gpr();
+    flushRegisters();
+    callOperation(operationResolveScopeForHoistingFuncDeclInEval, resultGPR, scopeGPR, identifierUID(node->identifierNumber()));
+    m_jit.exceptionCheck();
+    jsValueResult(result.gpr(), node);
+#else
+    flushRegisters();
+    GPRFlushedCallResult2 resultTag(this);
+    GPRFlushedCallResult resultPayload(this);
+    callOperation(operationResolveScopeForHoistingFuncDeclInEval, JSValueRegs(resultTag.gpr(), resultPayload.gpr()), scopeGPR, identifierUID(node->identifierNumber()));
+    m_jit.exceptionCheck();
+    jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
+#endif
+}
+    
 void SpeculativeJIT::compileGetDynamicVar(Node* node)
 {
     SpeculateCellOperand scope(this, node->child1());
index 59221cd..75070a6 100644 (file)
@@ -1375,6 +1375,12 @@ public:
         return appendCallSetResult(operation, result);
     }
 
+    JITCompiler::Call callOperation(S_JITOperation_EO operation, GPRReg result, GPRReg arg1)
+    {
+        m_jit.setupArgumentsWithExecState(arg1);
+        return appendCallSetResult(operation, result);
+    }
+
     JITCompiler::Call callOperation(C_JITOperation_EJscI operation, GPRReg result, GPRReg arg1, UniquedStringImpl* impl)
     {
         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(impl));
@@ -1431,6 +1437,11 @@ public:
         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(uid));
         return appendCallSetResult(operation, result);
     }
+    JITCompiler::Call callOperation(J_JITOperation_EJscI operation, GPRReg result, GPRReg arg1, UniquedStringImpl* impl)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(impl));
+        return appendCallSetResult(operation, result);
+    }
     JITCompiler::Call callOperation(V_JITOperation_EJJJI operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, UniquedStringImpl* uid)
     {
         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, TrustedImmPtr(uid));
@@ -1970,6 +1981,11 @@ public:
         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2.payloadGPR(), arg2.tagGPR(), arg3.payloadGPR(), arg3.tagGPR(), arg4.payloadGPR(), arg4.tagGPR());
         return appendCall(operation);
     }
+    JITCompiler::Call callOperation(J_JITOperation_EJscI operation, JSValueRegs result, GPRReg arg1, UniquedStringImpl* impl)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(impl));
+        return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
+    }
     JITCompiler::Call callOperation(V_JITOperation_EOJJZ operation, GPRReg arg1, JSValueRegs arg2, JSValueRegs arg3, GPRReg arg4)
     {
         m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), arg3.payloadGPR(), arg3.tagGPR(), arg4);
@@ -2854,6 +2870,7 @@ public:
     void compileRecordRegExpCachedResult(Node*);
     void compileCallObjectConstructor(Node*);
     void compileResolveScope(Node*);
+    void compileResolveScopeForHoistingFuncDeclInEval(Node*);
     void compileGetDynamicVar(Node*);
     void compilePutDynamicVar(Node*);
     void compileCompareEqPtr(Node*);
index 42d0571..07169f7 100644 (file)
@@ -5610,6 +5610,11 @@ void SpeculativeJIT::compile(Node* node)
         break;
     }
 
+    case ResolveScopeForHoistingFuncDeclInEval: {
+        compileResolveScopeForHoistingFuncDeclInEval(node);
+        break;
+    }
+
     case ResolveScope: {
         compileResolveScope(node);
         break;
index ab0e569..a9c2e4b 100644 (file)
@@ -4634,6 +4634,11 @@ void SpeculativeJIT::compile(Node* node)
         compileGetDynamicVar(node);
         break;
     }
+    
+    case ResolveScopeForHoistingFuncDeclInEval: {
+        compileResolveScopeForHoistingFuncDeclInEval(node);
+        break;
+    }
 
     case ResolveScope: {
         compileResolveScope(node);
index ad54c94..a69ece8 100644 (file)
@@ -267,6 +267,7 @@ inline CapabilityLevel canCompile(Node* node)
     case LogShadowChickenPrologue:
     case LogShadowChickenTail:
     case ResolveScope:
+    case ResolveScopeForHoistingFuncDeclInEval:
     case GetDynamicVar:
     case PutDynamicVar:
     case CompareEq:
index 6fadf15..1600b8f 100644 (file)
@@ -1065,6 +1065,9 @@ private:
         case RecordRegExpCachedResult:
             compileRecordRegExpCachedResult();
             break;
+        case ResolveScopeForHoistingFuncDeclInEval:
+            compileResolveScopeForHoistingFuncDeclInEval();
+            break;
         case ResolveScope:
             compileResolveScope();
             break;
@@ -10043,6 +10046,12 @@ private:
         }
     }
 
+    void compileResolveScopeForHoistingFuncDeclInEval()
+    {
+        UniquedStringImpl* uid = m_graph.identifiers()[m_node->identifierNumber()];
+        setJSValue(vmCall(pointerType(), m_out.operation(operationResolveScopeForHoistingFuncDeclInEval), m_callFrame, lowCell(m_node->child1()), m_out.constIntPtr(uid)));
+    }
+
     void compileResolveScope()
     {
         UniquedStringImpl* uid = m_graph.identifiers()[m_node->identifierNumber()];
index de2f88b..fef8324 100644 (file)
@@ -1091,10 +1091,11 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
         return checkedReturn(throwStackOverflowError(callFrame, throwScope));
 
     unsigned numVariables = eval->numVariables();
-    int numFunctions = eval->numberOfFunctionDecls();
+    unsigned numTopLevelFunctionDecls = eval->numTopLevelFunctionDecls();
+    unsigned numFunctionHoistingCandidates = eval->numFunctionHoistingCandidates();
 
     JSScope* variableObject;
-    if ((numVariables || numFunctions) && eval->isStrictMode()) {
+    if ((numVariables || numTopLevelFunctionDecls) && eval->isStrictMode()) {
         scope = StrictEvalActivation::create(callFrame, scope);
         variableObject = scope;
     } else {
@@ -1125,7 +1126,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
     }
 
     // We can't declare a "var"/"function" that overwrites a global "let"/"const"/"class" in a sloppy-mode eval.
-    if (variableObject->isGlobalObject() && !eval->isStrictMode() && (numVariables || numFunctions)) {
+    if (variableObject->isGlobalObject() && !eval->isStrictMode() && (numVariables || numTopLevelFunctionDecls)) {
         JSGlobalLexicalEnvironment* globalLexicalEnvironment = jsCast<JSGlobalObject*>(variableObject)->globalLexicalEnvironment();
         for (unsigned i = 0; i < numVariables; ++i) {
             const Identifier& ident = codeBlock->variable(i);
@@ -1135,7 +1136,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
             }
         }
 
-        for (int i = 0; i < numFunctions; ++i) {
+        for (unsigned i = 0; i < numTopLevelFunctionDecls; ++i) {
             FunctionExecutable* function = codeBlock->functionDecl(i);
             PropertySlot slot(globalLexicalEnvironment, PropertySlot::InternalMethodType::VMInquiry);
             if (JSGlobalLexicalEnvironment::getOwnPropertySlot(globalLexicalEnvironment, callFrame, function->name(), slot)) {
@@ -1147,7 +1148,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
     if (variableObject->structure()->isUncacheableDictionary())
         variableObject->flattenDictionaryObject(vm);
 
-    if (numVariables || numFunctions) {
+    if (numVariables || numTopLevelFunctionDecls || numFunctionHoistingCandidates) {
         BatchedTransitionOptimizer optimizer(vm, variableObject);
         if (variableObject->next() && !eval->isStrictMode())
             variableObject->globalObject()->varInjectionWatchpoint()->fireAll(vm, "Executed eval, fired VarInjection watchpoint");
@@ -1164,12 +1165,35 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
                 RETURN_IF_EXCEPTION(throwScope, checkedReturn(throwScope.exception()));
             }
         }
+        
+        if (eval->isStrictMode()) {
+            for (unsigned i = 0; i < numTopLevelFunctionDecls; ++i) {
+                FunctionExecutable* function = codeBlock->functionDecl(i);
+                PutPropertySlot slot(variableObject);
+                variableObject->methodTable()->put(variableObject, callFrame, function->name(), JSFunction::create(vm, function, scope), slot);
+            }
+        } else {
+            for (unsigned i = 0; i < numTopLevelFunctionDecls; ++i) {
+                FunctionExecutable* function = codeBlock->functionDecl(i);
+                JSValue resolvedScope = JSScope::resolveScopeForHoistingFuncDeclInEval(callFrame, scope, function->name());
+                if (resolvedScope.isUndefined())
+                    return checkedReturn(throwSyntaxError(callFrame, throwScope, makeString("Can't create duplicate variable in eval: '", String(function->name().impl()), "'")));
+                PutPropertySlot slot(variableObject);
+                variableObject->methodTable()->put(variableObject, callFrame, function->name(), JSFunction::create(vm, function, scope), slot);
+                RETURN_IF_EXCEPTION(throwScope, checkedReturn(throwScope.exception()));
+            }
 
-        for (int i = 0; i < numFunctions; ++i) {
-            FunctionExecutable* function = codeBlock->functionDecl(i);
-            PutPropertySlot slot(variableObject);
-            variableObject->methodTable()->put(variableObject, callFrame, function->name(), JSFunction::create(vm, function, scope), slot);
-            RETURN_IF_EXCEPTION(throwScope, checkedReturn(throwScope.exception()));
+            for (unsigned i = 0; i < numFunctionHoistingCandidates; ++i) {
+                const Identifier& ident = codeBlock->functionHoistingCandidate(i);
+                JSValue resolvedScope = JSScope::resolveScopeForHoistingFuncDeclInEval(callFrame, scope, ident);
+                if (!resolvedScope.isUndefined()) {
+                    if (!variableObject->hasProperty(callFrame, ident)) {
+                        PutPropertySlot slot(variableObject);
+                        variableObject->methodTable()->put(variableObject, callFrame, ident, jsUndefined(), slot);
+                        RETURN_IF_EXCEPTION(throwScope, checkedReturn(throwScope.exception()));
+                    }
+                }
+            }
         }
     }
 
index c3f93fd..9b672fd 100644 (file)
@@ -392,6 +392,7 @@ void JIT::privateCompileMainPass()
         DEFINE_OP(op_to_primitive)
 
         DEFINE_OP(op_resolve_scope)
+        DEFINE_OP(op_resolve_scope_for_hoisting_func_decl_in_eval)
         DEFINE_OP(op_get_from_scope)
         DEFINE_OP(op_put_to_scope)
         DEFINE_OP(op_get_from_arguments)
index 7edd0b1..43685b3 100644 (file)
@@ -665,6 +665,7 @@ namespace JSC {
         void emitSlow_op_get_direct_pname(Instruction*, Vector<SlowCaseEntry>::iterator&);
 
         void emit_op_resolve_scope(Instruction*);
+        void emit_op_resolve_scope_for_hoisting_func_decl_in_eval(Instruction*);
         void emit_op_get_from_scope(Instruction*);
         void emit_op_put_to_scope(Instruction*);
         void emit_op_get_from_arguments(Instruction*);
index c7a3c8e..0f99e03 100644 (file)
@@ -153,6 +153,7 @@ typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJJ)(ExecState*, EncodedJ
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJArp)(ExecState*, EncodedJSValue, EncodedJSValue, ArithProfile*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJJMic)(ExecState*, EncodedJSValue, EncodedJSValue, void*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJMic)(ExecState*, EncodedJSValue, void*);
+typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJscI)(ExecState*, JSScope*, UniquedStringImpl*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJssZ)(ExecState*, JSString*, int32_t);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJss)(ExecState*, JSString*);
 typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJssReo)(ExecState*, JSString*, RegExpObject*);
@@ -232,6 +233,7 @@ typedef int32_t (JIT_OPERATION *Z_JITOperation_EJZ)(ExecState*, EncodedJSValue,
 typedef int32_t (JIT_OPERATION *Z_JITOperation_EJZZ)(ExecState*, EncodedJSValue, int32_t, int32_t);
 typedef int32_t (JIT_OPERATION *Z_JITOperation_EOI)(ExecState*, JSObject*, UniquedStringImpl*);
 typedef int32_t (JIT_OPERATION *Z_JITOperation_EOJ)(ExecState*, JSObject*, EncodedJSValue);
+typedef size_t (JIT_OPERATION *S_JITOperation_EO)(ExecState*, JSObject*);
 typedef size_t (JIT_OPERATION *S_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
 typedef size_t (JIT_OPERATION *S_JITOperation_EGC)(ExecState*, JSGlobalObject*, JSCell*);
 typedef size_t (JIT_OPERATION *S_JITOperation_EGJJ)(ExecState*, JSGlobalObject*, EncodedJSValue, EncodedJSValue);
index 332ccb2..612b568 100644 (file)
@@ -764,6 +764,12 @@ void JIT::emitResolveClosure(int dst, int scope, bool needsVarInjectionChecks, u
     emitPutVirtualRegister(dst);
 }
 
+void JIT::emit_op_resolve_scope_for_hoisting_func_decl_in_eval(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_resolve_scope_for_hoisting_func_decl_in_eval);
+    slowPathCall.call();
+}
+
 void JIT::emit_op_resolve_scope(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
index cedf9fd..8e9fbf2 100644 (file)
@@ -771,6 +771,12 @@ void JIT::emitResolveClosure(int dst, int scope, bool needsVarInjectionChecks, u
     emitStore(dst, regT1, regT0);
 }
 
+void JIT::emit_op_resolve_scope_for_hoisting_func_decl_in_eval(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_resolve_scope_for_hoisting_func_decl_in_eval);
+    slowPathCall.call();
+}
+    
 void JIT::emit_op_resolve_scope(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
index ab3c0c8..3da98be 100644 (file)
@@ -1831,6 +1831,11 @@ _llint_op_put_by_val_with_this:
     callOpcodeSlowPath(_slow_path_put_by_val_with_this)
     dispatch(5)
 
+_llint_op_resolve_scope_for_hoisting_func_decl_in_eval:
+    traceExecution()
+    callOpcodeSlowPath(_slow_path_resolve_scope_for_hoisting_func_decl_in_eval)
+    dispatch(4)
+
 # Lastly, make sure that we can link even though we don't support all opcodes.
 # These opcodes should never arise when using LLInt or either JIT. We assert
 # as much.
index c03f176..6fdaf6a 100644 (file)
@@ -1784,8 +1784,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla
 {
     semanticFailIfTrue(strictMode(), "Function declarations are only allowed inside blocks or switch statements in strict mode");
     failIfFalse(parentAllowsFunctionDeclarationAsStatement, "Function declarations are only allowed inside block statements or at the top level of a program");
-    if (!currentScope()->isFunction()) {
-        // We only implement annex B.3.3 if we're in function mode. Otherwise, we fall back
+    if (!currentScope()->isFunction() && !closestParentOrdinaryFunctionNonLexicalScope()->isEvalContext()) {
+        // We only implement annex B.3.3 if we're in function mode or eval mode. Otherwise, we fall back
         // to hoisting behavior.
         // FIXME: https://bugs.webkit.org/show_bug.cgi?id=155813
         DepthManager statementDepth(&m_statementDepth);
index 0ddc144..fee1d7b 100644 (file)
@@ -647,6 +647,7 @@ public:
                 if (!isParameter) {
                     auto addResult = m_declaredVariables.add(function);
                     addResult.iterator->value.setIsVar();
+                    addResult.iterator->value.setIsSloppyModeHoistingCandidate();
                     sloppyModeHoistedFunctions.add(function);
                 }
             }
@@ -1234,7 +1235,7 @@ private:
 
     std::pair<DeclarationResultMask, ScopeRef> declareFunction(const Identifier* ident)
     {
-        if (m_statementDepth == 1 || (!strictMode() && !currentScope()->isFunction())) {
+        if ((m_statementDepth == 1) || (!strictMode() && !currentScope()->isFunction() && !closestParentOrdinaryFunctionNonLexicalScope()->isEvalContext())) {
             // Functions declared at the top-most scope (both in sloppy and strict mode) are declared as vars
             // for backwards compatibility. This allows us to declare functions with the same name more than once.
             // In sloppy mode, we always declare functions as vars.
@@ -1245,7 +1246,7 @@ private:
         }
 
         if (!strictMode()) {
-            ASSERT(currentScope()->isFunction());
+            ASSERT(currentScope()->isFunction() || closestParentOrdinaryFunctionNonLexicalScope()->isEvalContext());
 
             // Functions declared inside a function inside a nested block scope in sloppy mode are subject to this
             // crazy rule defined inside Annex B.3.3 in the ES6 spec. It basically states that we will create
index f0d3bef..41b9be8 100644 (file)
@@ -812,6 +812,18 @@ SLOW_PATH_DECL(slow_path_push_with_scope)
     RETURN(JSWithScope::create(vm, exec->lexicalGlobalObject(), newScope, currentScope));
 }
 
+SLOW_PATH_DECL(slow_path_resolve_scope_for_hoisting_func_decl_in_eval)
+{
+    BEGIN();
+    const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
+    JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
+    JSValue resolvedScope = JSScope::resolveScopeForHoistingFuncDeclInEval(exec, scope, ident);
+
+    CHECK_EXCEPTION();
+
+    RETURN(resolvedScope);
+}
+
 SLOW_PATH_DECL(slow_path_resolve_scope)
 {
     BEGIN();
index 7a62728..f9d818d 100644 (file)
@@ -257,6 +257,8 @@ SLOW_PATH_HIDDEN_DECL(slow_path_assert);
 SLOW_PATH_HIDDEN_DECL(slow_path_create_lexical_environment);
 SLOW_PATH_HIDDEN_DECL(slow_path_push_with_scope);
 SLOW_PATH_HIDDEN_DECL(slow_path_resolve_scope);
+SLOW_PATH_HIDDEN_DECL(slow_path_is_var_scope);
+SLOW_PATH_HIDDEN_DECL(slow_path_resolve_scope_for_hoisting_func_decl_in_eval);
 SLOW_PATH_HIDDEN_DECL(slow_path_create_rest);
 SLOW_PATH_HIDDEN_DECL(slow_path_get_by_id_with_this);
 SLOW_PATH_HIDDEN_DECL(slow_path_get_by_val_with_this);
index c871e5f..976541b 100644 (file)
@@ -58,7 +58,8 @@ public:
     ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, JSParserScriptMode::Classic, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), isArrowFunctionContext(), false, evalContextType()); }
 
     unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); }
-    unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }
+    unsigned numFunctionHoistingCandidates() { return m_unlinkedEvalCodeBlock->numFunctionHoistingCandidates(); }
+    unsigned numTopLevelFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }
 
 protected:
     friend class ExecutableBase;
index e55bfb7..6bd82cf 100644 (file)
@@ -211,7 +211,8 @@ static inline bool isUnscopable(ExecState* exec, JSScope* scope, JSObject* objec
     return blocked.toBoolean(exec);
 }
 
-JSObject* JSScope::resolve(ExecState* exec, JSScope* scope, const Identifier& ident)
+template<typename ReturnPredicateFunctor, typename SkipPredicateFunctor>
+ALWAYS_INLINE JSObject* JSScope::resolve(ExecState* exec, JSScope* scope, const Identifier& ident, ReturnPredicateFunctor returnPredicate, SkipPredicateFunctor skipPredicate)
 {
     VM& vm = exec->vm();
     auto throwScope = DECLARE_THROW_SCOPE(vm);
@@ -238,6 +239,9 @@ JSObject* JSScope::resolve(ExecState* exec, JSScope* scope, const Identifier& id
             return object;
         }
 
+        if (skipPredicate(scope))
+            continue;
+
         bool hasProperty = object->hasProperty(exec, ident);
         RETURN_IF_EXCEPTION(throwScope, nullptr);
         if (hasProperty) {
@@ -246,9 +250,45 @@ JSObject* JSScope::resolve(ExecState* exec, JSScope* scope, const Identifier& id
             if (!unscopable)
                 return object;
         }
+
+        if (returnPredicate(scope))
+            return object;
     }
 }
 
+JSValue JSScope::resolveScopeForHoistingFuncDeclInEval(ExecState* exec, JSScope* scope, const Identifier& ident)
+{
+    auto returnPredicate = [&] (JSScope* scope) -> bool {
+        return scope->isVarScope();
+    };
+    auto skipPredicate = [&] (JSScope* scope) -> bool {
+        return scope->isWithScope();
+    };
+    JSObject* object = resolve(exec, scope, ident, returnPredicate, skipPredicate);
+    
+    bool result = false;
+    if (JSScope* scope = jsDynamicCast<JSScope*>(exec->vm(), object)) {
+        if (SymbolTable* scopeSymbolTable = scope->symbolTable(exec->vm())) {
+            result = scope->isGlobalObject()
+                ? JSObject::isExtensible(object, exec)
+                : scopeSymbolTable->scopeType() == SymbolTable::ScopeType::VarScope;
+        }
+    }
+
+    return result ? JSValue(object) : jsUndefined();
+}
+
+JSObject* JSScope::resolve(ExecState* exec, JSScope* scope, const Identifier& ident)
+{
+    auto predicate1 = [&] (JSScope*) -> bool {
+        return false;
+    };
+    auto predicate2 = [&] (JSScope*) -> bool {
+        return false;
+    };
+    return resolve(exec, scope, ident, predicate1, predicate2);
+}
+
 ResolveOp JSScope::abstractResolve(ExecState* exec, size_t depthOffset, JSScope* scope, const Identifier& ident, GetOrPut getOrPut, ResolveType unlinkedType, InitializationMode initializationMode)
 {
     ResolveOp op(Dynamic, 0, 0, 0, 0, 0);
index 7154574..e079ee4 100644 (file)
@@ -46,6 +46,7 @@ public:
     static JSObject* objectAtScope(JSScope*);
 
     static JSObject* resolve(ExecState*, JSScope*, const Identifier&);
+    static JSValue resolveScopeForHoistingFuncDeclInEval(ExecState*, JSScope*, const Identifier&);
     static ResolveOp abstractResolve(ExecState*, size_t depthOffset, JSScope*, const Identifier&, GetOrPut, ResolveType, InitializationMode);
 
     static bool hasConstantScope(ResolveType);
@@ -76,6 +77,9 @@ public:
 protected:
     JSScope(VM&, Structure*, JSScope* next);
 
+    template<typename ReturnPredicateFunctor, typename SkipPredicateFunctor>
+    static JSObject* resolve(ExecState*, JSScope*, const Identifier&, ReturnPredicateFunctor, SkipPredicateFunctor);
+
 private:
     WriteBarrier<JSScope> m_next;
 };