summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibJS/AST.cpp5
-rw-r--r--Userland/Libraries/LibJS/Tests/with-basic.js21
2 files changed, 24 insertions, 2 deletions
diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp
index 80dd4f6448..658d5b6081 100644
--- a/Userland/Libraries/LibJS/AST.cpp
+++ b/Userland/Libraries/LibJS/AST.cpp
@@ -379,12 +379,13 @@ Value WithStatement::execute(Interpreter& interpreter, GlobalObject& global_obje
// 6. Let C be the result of evaluating Statement.
auto result = interpreter.execute_statement(global_object, m_body).value_or(js_undefined());
- if (interpreter.exception())
- return {};
// 7. Set the running execution context's LexicalEnvironment to oldEnv.
interpreter.vm().running_execution_context().lexical_environment = old_environment;
+ if (interpreter.exception())
+ return {};
+
// 8. Return Completion(UpdateEmpty(C, undefined)).
return result;
}
diff --git a/Userland/Libraries/LibJS/Tests/with-basic.js b/Userland/Libraries/LibJS/Tests/with-basic.js
index c2ef01698b..110c454734 100644
--- a/Userland/Libraries/LibJS/Tests/with-basic.js
+++ b/Userland/Libraries/LibJS/Tests/with-basic.js
@@ -15,6 +15,7 @@ test("basic with statement functionality", () => {
}
expect(object.bar).toBe(2);
+ expect(() => foo).toThrowWithMessage(ReferenceError, "'foo' is not defined");
expect(bar).toBe(99);
});
@@ -22,3 +23,23 @@ test("basic with statement functionality", () => {
test("syntax error in strict mode", () => {
expect("'use strict'; with (foo) {}").not.toEval();
});
+
+test("restores lexical environment even when exception is thrown", () => {
+ var object = {
+ foo: 1,
+ get bar() {
+ throw Error();
+ },
+ };
+
+ try {
+ with (object) {
+ expect(foo).toBe(1);
+ bar;
+ }
+ expect().fail();
+ } catch (e) {
+ expect(() => foo).toThrowWithMessage(ReferenceError, "'foo' is not defined");
+ }
+ expect(() => foo).toThrowWithMessage(ReferenceError, "'foo' is not defined");
+});