mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 12:20:00 +01:00
LibJS: Stop tracking whether execution context is strict mode or not
This was only used for basic testing, and forced us to plumb this flag flag in a bunch of places.
This commit is contained in:
parent
fb05063dde
commit
fdb85a330e
|
|
@ -249,9 +249,6 @@ ThrowCompletionOr<Value> Interpreter::run(Script& script_record, GC::Ptr<Environ
|
|||
|
||||
// 8. Set the PrivateEnvironment of scriptContext to null.
|
||||
|
||||
// NOTE: This isn't in the spec, but we require it.
|
||||
script_context->is_strict_mode = script_record.is_strict_mode();
|
||||
|
||||
// 9. Suspend the currently running execution context.
|
||||
// 10. Push scriptContext onto the execution context stack; scriptContext is now the running execution context.
|
||||
TRY(vm.push_execution_context(*script_context, {}));
|
||||
|
|
|
|||
|
|
@ -723,9 +723,6 @@ ThrowCompletionOr<Value> perform_eval(VM& vm, Value x, CallerMode strict_caller,
|
|||
// 28. Set evalContext's PrivateEnvironment to privateEnv.
|
||||
eval_context->private_environment = private_environment;
|
||||
|
||||
// NOTE: This isn't in the spec, but we require it.
|
||||
eval_context->is_strict_mode = strict_eval;
|
||||
|
||||
// 29. Push evalContext onto the execution context stack; evalContext is now the running execution context.
|
||||
TRY(vm.push_execution_context(*eval_context, {}));
|
||||
|
||||
|
|
|
|||
|
|
@ -689,9 +689,6 @@ void ECMAScriptFunctionObject::make_method(Object& home_object)
|
|||
// 10.2.1.1 PrepareForOrdinaryCall ( F, newTarget ), https://tc39.es/ecma262/#sec-prepareforordinarycall
|
||||
void ECMAScriptFunctionObject::prepare_for_ordinary_call(VM& vm, ExecutionContext& callee_context, Object* new_target)
|
||||
{
|
||||
// Non-standard
|
||||
callee_context.is_strict_mode = is_strict_mode();
|
||||
|
||||
// 1. Let callerContext be the running execution context.
|
||||
// 2. Let calleeContext be a new ECMAScript code execution context.
|
||||
|
||||
|
|
|
|||
|
|
@ -125,7 +125,6 @@ NonnullOwnPtr<ExecutionContext> ExecutionContext::copy() const
|
|||
copy->program_counter = program_counter;
|
||||
copy->function_name = function_name;
|
||||
copy->this_value = this_value;
|
||||
copy->is_strict_mode = is_strict_mode;
|
||||
copy->executable = executable;
|
||||
copy->arguments_offset = arguments_offset;
|
||||
copy->passed_argument_count = passed_argument_count;
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ public:
|
|||
|
||||
u32 arguments_offset { 0 };
|
||||
u32 passed_argument_count { 0 };
|
||||
bool is_strict_mode { false };
|
||||
|
||||
Span<Value> arguments;
|
||||
|
||||
|
|
|
|||
|
|
@ -151,9 +151,6 @@ ThrowCompletionOr<Value> NativeFunction::internal_call(ExecutionContext& callee_
|
|||
// calling async_block_start which goes through a NativeFunction here.
|
||||
callee_context.private_environment = caller_context.private_environment;
|
||||
|
||||
// NOTE: This is a LibJS specific hack for NativeFunction to inherit the strictness of its caller.
|
||||
callee_context.is_strict_mode = caller_context.is_strict_mode;
|
||||
|
||||
// </8.> --------------------------------------------------------------------------
|
||||
|
||||
// 9. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
|
||||
|
|
@ -204,9 +201,6 @@ ThrowCompletionOr<GC::Ref<Object>> NativeFunction::internal_construct(ExecutionC
|
|||
callee_context.lexical_environment = caller_context.lexical_environment;
|
||||
callee_context.variable_environment = caller_context.variable_environment;
|
||||
|
||||
// NOTE: This is a LibJS specific hack for NativeFunction to inherit the strictness of its caller.
|
||||
callee_context.is_strict_mode = caller_context.is_strict_mode;
|
||||
|
||||
// </8.> --------------------------------------------------------------------------
|
||||
|
||||
// 9. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
|
||||
|
|
|
|||
|
|
@ -342,9 +342,6 @@ NonnullOwnPtr<ExecutionContext> get_shadow_realm_context(Realm& shadow_realm, bo
|
|||
// 10. Set context's PrivateEnvironment to null.
|
||||
context->private_environment = nullptr;
|
||||
|
||||
// Non-standard
|
||||
context->is_strict_mode = strict_eval;
|
||||
|
||||
// 11. Return context.
|
||||
return context;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,18 +25,15 @@ Result<GC::Ref<Script>, Vector<ParserError>> Script::parse(StringView source_tex
|
|||
if (parser.has_errors())
|
||||
return parser.errors();
|
||||
|
||||
bool strict_mode = script->is_strict_mode();
|
||||
|
||||
// 3. Return Script Record { [[Realm]]: realm, [[ECMAScriptCode]]: script, [[HostDefined]]: hostDefined }.
|
||||
return realm.heap().allocate<Script>(realm, filename, move(script), host_defined, strict_mode);
|
||||
return realm.heap().allocate<Script>(realm, filename, move(script), host_defined);
|
||||
}
|
||||
|
||||
Script::Script(Realm& realm, StringView filename, NonnullRefPtr<Program> parse_node, HostDefined* host_defined, bool strict_mode)
|
||||
Script::Script(Realm& realm, StringView filename, NonnullRefPtr<Program> parse_node, HostDefined* host_defined)
|
||||
: m_realm(realm)
|
||||
, m_parse_node(move(parse_node))
|
||||
, m_filename(filename)
|
||||
, m_host_defined(host_defined)
|
||||
, m_strict_mode(strict_mode)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,10 +46,8 @@ public:
|
|||
HostDefined* host_defined() const { return m_host_defined; }
|
||||
StringView filename() const LIFETIME_BOUND { return m_filename; }
|
||||
|
||||
[[nodiscard]] bool is_strict_mode() const { return m_strict_mode; }
|
||||
|
||||
private:
|
||||
Script(Realm&, StringView filename, NonnullRefPtr<Program>, HostDefined*, bool strict_mode);
|
||||
Script(Realm&, StringView filename, NonnullRefPtr<Program>, HostDefined*);
|
||||
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
|
|
@ -60,8 +58,6 @@ private:
|
|||
// Needed for potential lookups of modules.
|
||||
ByteString m_filename;
|
||||
HostDefined* m_host_defined { nullptr }; // [[HostDefined]]
|
||||
|
||||
bool m_strict_mode { false };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -709,9 +709,6 @@ ThrowCompletionOr<void> SourceTextModule::execute_module(VM& vm, GC::Ptr<Promise
|
|||
ExecutionContext* module_context = nullptr;
|
||||
ALLOCATE_EXECUTION_CONTEXT_ON_NATIVE_STACK(module_context, registers_and_constants_and_locals_count, 0);
|
||||
|
||||
// NOTE: This is not in the spec but we require it.
|
||||
module_context->is_strict_mode = true;
|
||||
|
||||
// 2. Set the Function of moduleContext to null.
|
||||
|
||||
// 3. Set the Realm of moduleContext to module.[[Realm]].
|
||||
|
|
|
|||
|
|
@ -15,12 +15,11 @@ describe("normal behavior", () => {
|
|||
// Currently uses a plain JS::GlobalObject, i.e. no TestRunnerGlobalObject functions are available on the
|
||||
// shadow realm's global object. This may change in the future, update the test accordingly.
|
||||
const shadowRealm = new ShadowRealm();
|
||||
expect(shadowRealm.evaluate("globalThis.isStrictMode")).toBeUndefined();
|
||||
expect(shadowRealm.evaluate("globalThis.markAsGarbage")).toBeUndefined();
|
||||
});
|
||||
|
||||
test("strict mode behavior", () => {
|
||||
const shadowRealm = new ShadowRealm();
|
||||
// NOTE: We don't have access to the isStrictMode() test helper inside the shadow realm, see the comment in the test above.
|
||||
|
||||
// sloppy mode
|
||||
expect(shadowRealm.evaluate("(function() { return !this; })()")).toBe(false);
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
test("constructors are always strict mode", () => {
|
||||
class A {
|
||||
constructor() {
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
}
|
||||
}
|
||||
|
||||
new A();
|
||||
});
|
||||
|
||||
test("methods are always strict mode", () => {
|
||||
class A {
|
||||
method() {
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
}
|
||||
}
|
||||
|
||||
new A().method();
|
||||
});
|
||||
|
|
@ -110,33 +110,6 @@ test("arrow functions in objects", () => {
|
|||
expect(foobar.x.z()).toBe(foobar.x);
|
||||
});
|
||||
|
||||
test("strict mode propagation", () => {
|
||||
(() => {
|
||||
"use strict";
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
|
||||
(() => {
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
})();
|
||||
})();
|
||||
|
||||
(() => {
|
||||
"use strict";
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
})();
|
||||
|
||||
(() => {
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
|
||||
(() => {
|
||||
"use strict";
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
})();
|
||||
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
})();
|
||||
});
|
||||
|
||||
test("no prototype", () => {
|
||||
let foo = () => {};
|
||||
expect(foo).not.toHaveProperty("prototype");
|
||||
|
|
|
|||
|
|
@ -1,64 +1,3 @@
|
|||
test("non strict-mode by default", () => {
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
});
|
||||
|
||||
test("use strict with double quotes", () => {
|
||||
"use strict";
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
});
|
||||
|
||||
// prettier-ignore
|
||||
test("use strict with single quotes", () => {
|
||||
'use strict';
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
});
|
||||
|
||||
// prettier-ignore
|
||||
test("use strict with backticks does not yield strict mode", () => {
|
||||
`use strict`;
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
});
|
||||
|
||||
// prettier-ignore
|
||||
test("use strict with single quotes after statement does not yield strict mode code", () => {
|
||||
;'use strict';
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
});
|
||||
|
||||
// prettier-ignore
|
||||
test("use strict with double quotes after statement does not yield strict mode code", () => {
|
||||
;"use strict";
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
});
|
||||
|
||||
test("use strict interrupted by a line continuation does not yield strict mode code", () => {
|
||||
"use \
|
||||
strict";
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
});
|
||||
|
||||
test("strict mode propagates down the scope chain", () => {
|
||||
"use strict";
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
(function () {
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
})();
|
||||
});
|
||||
|
||||
test("strict mode does not propagate up the scope chain", () => {
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
(function () {
|
||||
"use strict";
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
})();
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
});
|
||||
|
||||
test('only the string "use strict" yields strict mode code', () => {
|
||||
"use stric";
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
});
|
||||
|
||||
test("strict mode does not apply global object to |this|", () => {
|
||||
"use strict";
|
||||
let functionThis;
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
"do not use strict";
|
||||
"no really";
|
||||
// /\ Valid directives which should not trigger strict mode
|
||||
|
||||
test("basic functionality", () => {
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
|
||||
(function () {
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
})();
|
||||
|
||||
(() => {
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
})();
|
||||
|
||||
(() => {
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
})();
|
||||
|
||||
function a() {
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
}
|
||||
|
||||
a();
|
||||
|
||||
eval("expect(isStrictMode()).toBeFalse()");
|
||||
});
|
||||
|
||||
test("functions with strict mode", () => {
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
|
||||
function a() {
|
||||
"this is allowed trust me";
|
||||
"use strict";
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
}
|
||||
|
||||
a();
|
||||
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
|
||||
(() => {
|
||||
"use strict";
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
})();
|
||||
|
||||
function b() {
|
||||
eval("expect(isStrictMode()).toBeFalse()");
|
||||
|
||||
function nested() {
|
||||
"use strict";
|
||||
eval("expect(isStrictMode()).toBeTrue()");
|
||||
}
|
||||
|
||||
nested();
|
||||
|
||||
eval("expect(isStrictMode()).toBeFalse()");
|
||||
}
|
||||
|
||||
b();
|
||||
});
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
test("basic functionality", () => {
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
|
||||
(function () {
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
})();
|
||||
|
||||
(() => {
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
})();
|
||||
|
||||
(() => {
|
||||
"use strict";
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
})();
|
||||
|
||||
function a() {
|
||||
expect(isStrictMode()).toBeTrue();
|
||||
}
|
||||
|
||||
a();
|
||||
|
||||
eval("expect(isStrictMode()).toBeTrue()");
|
||||
});
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
test("Issue #3641, strict mode should be function- or program-level, not block-level", () => {
|
||||
function func() {
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
|
||||
// prettier-ignore
|
||||
{
|
||||
"use strict";
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
}
|
||||
|
||||
// prettier-ignore
|
||||
if (true) {
|
||||
"use strict";
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
}
|
||||
|
||||
// prettier-ignore
|
||||
do {
|
||||
"use strict";
|
||||
expect(isStrictMode()).toBeFalse();
|
||||
} while (false);
|
||||
}
|
||||
|
||||
func();
|
||||
});
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
test("valid 'use strict; directive", () => {
|
||||
expect(
|
||||
(() => {
|
||||
"use strict";
|
||||
return isStrictMode();
|
||||
})()
|
||||
).toBeTrue();
|
||||
expect(
|
||||
// prettier-ignore
|
||||
(() => {
|
||||
'use strict';
|
||||
return isStrictMode();
|
||||
})()
|
||||
).toBeTrue();
|
||||
});
|
||||
|
||||
test("invalid 'use strict; directive", () => {
|
||||
expect(
|
||||
(() => {
|
||||
" use strict ";
|
||||
return isStrictMode();
|
||||
})()
|
||||
).toBeFalse();
|
||||
expect(
|
||||
(() => {
|
||||
`use strict`;
|
||||
return isStrictMode();
|
||||
})()
|
||||
).toBeFalse();
|
||||
expect(
|
||||
(() => {
|
||||
"use\
|
||||
strict";
|
||||
return isStrictMode();
|
||||
})()
|
||||
).toBeFalse();
|
||||
expect(
|
||||
(() => {
|
||||
"use\ strict";
|
||||
return isStrictMode();
|
||||
})()
|
||||
).toBeFalse();
|
||||
expect(
|
||||
(() => {
|
||||
"use \163trict";
|
||||
return isStrictMode();
|
||||
})()
|
||||
).toBeFalse();
|
||||
expect(
|
||||
(() => {
|
||||
`"use strict"`;
|
||||
return isStrictMode();
|
||||
})()
|
||||
).toBeFalse();
|
||||
expect(
|
||||
(() => {
|
||||
"use strict" + 1;
|
||||
return isStrictMode();
|
||||
})()
|
||||
).toBeFalse();
|
||||
});
|
||||
|
|
@ -17,11 +17,6 @@ TEST_ROOT("Libraries/LibJS/Tests");
|
|||
|
||||
TESTJS_PROGRAM_FLAG(test262_parser_tests, "Run test262 parser tests", "test262-parser-tests", 0);
|
||||
|
||||
TESTJS_GLOBAL_FUNCTION(is_strict_mode, isStrictMode, 0)
|
||||
{
|
||||
return JS::Value(vm.running_execution_context().is_strict_mode);
|
||||
}
|
||||
|
||||
TESTJS_GLOBAL_FUNCTION(can_parse_source, canParseSource)
|
||||
{
|
||||
auto source = TRY(vm.argument(0).to_string(vm));
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user