Skip to content

Commit 978d319

Browse files
authored
Remove LexicalEnvironment (#901)
1 parent b29573b commit 978d319

34 files changed

+242
-227
lines changed

Jint/Engine.cs

+44-40
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ public Engine(Action<Engine, Options> options)
186186
Object._prototype = Function.PrototypeObject;
187187

188188
// create the global environment http://www.ecma-international.org/ecma-262/5.1/#sec-10.2.3
189-
GlobalEnvironment = LexicalEnvironment.NewGlobalEnvironment(this, Global);
189+
GlobalEnvironment = JintEnvironment.NewGlobalEnvironment(this, Global, Global);
190190

191191
// create the global execution context http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.1.1
192192
EnterExecutionContext(GlobalEnvironment, GlobalEnvironment);
@@ -213,7 +213,7 @@ public Engine(Action<Engine, Options> options)
213213
Options.Apply(this);
214214
}
215215

216-
internal LexicalEnvironment GlobalEnvironment { get; }
216+
internal GlobalEnvironmentRecord GlobalEnvironment { get; }
217217
public GlobalObject Global { get; }
218218
public ObjectConstructor Object { get; }
219219
public FunctionConstructor Function { get; }
@@ -274,8 +274,8 @@ internal Options Options
274274
public DebugHandler DebugHandler => _debugHandler ??= new DebugHandler(this);
275275

276276
public ExecutionContext EnterExecutionContext(
277-
LexicalEnvironment lexicalEnvironment,
278-
LexicalEnvironment variableEnvironment)
277+
EnvironmentRecord lexicalEnvironment,
278+
EnvironmentRecord variableEnvironment)
279279
{
280280
var context = new ExecutionContext(
281281
lexicalEnvironment,
@@ -285,6 +285,12 @@ public ExecutionContext EnterExecutionContext(
285285
return context;
286286
}
287287

288+
internal ExecutionContext EnterExecutionContext(ExecutionContext context)
289+
{
290+
_executionContexts.Push(context);
291+
return context;
292+
}
293+
288294
public Engine SetValue(JsValue name, Delegate value)
289295
{
290296
Global.FastAddProperty(name, new DelegateWrapper(this, value), true, false, true);
@@ -791,26 +797,26 @@ public JsValue GetValue(JsValue scope, JsValue property)
791797
/// <summary>
792798
/// https://tc39.es/ecma262/#sec-resolvebinding
793799
/// </summary>
794-
internal Reference ResolveBinding(string name, LexicalEnvironment env = null)
800+
internal Reference ResolveBinding(string name, EnvironmentRecord env = null)
795801
{
796802
env ??= ExecutionContext.LexicalEnvironment;
797803
return GetIdentifierReference(env, name, StrictModeScope.IsStrictModeCode);
798804
}
799805

800-
private Reference GetIdentifierReference(LexicalEnvironment env, string name, bool strict)
806+
private Reference GetIdentifierReference(EnvironmentRecord env, string name, bool strict)
801807
{
802808
if (env is null)
803809
{
804810
return new Reference(JsValue.Undefined, name, strict);
805811
}
806812

807-
var envRec = env._record;
813+
var envRec = env;
808814
if (envRec.HasBinding(name))
809815
{
810816
return new Reference(envRec, name, strict);
811817
}
812818

813-
return GetIdentifierReference(env._outer, name, strict);
819+
return GetIdentifierReference(env._outerEnv, name, strict);
814820
}
815821

816822
/// <summary>
@@ -837,10 +843,8 @@ internal JsValue ResolveThisBinding()
837843
/// </summary>
838844
private void GlobalDeclarationInstantiation(
839845
Script script,
840-
LexicalEnvironment env)
846+
GlobalEnvironmentRecord env)
841847
{
842-
var envRec = (GlobalEnvironmentRecord) env._record;
843-
844848
var hoistingScope = HoistingScope.GetProgramLevelDeclarations(script);
845849
var functionDeclarations = hoistingScope._functionDeclarations;
846850
var varDeclarations = hoistingScope._variablesDeclarations;
@@ -858,7 +862,7 @@ private void GlobalDeclarationInstantiation(
858862
var fn = d.Id.Name;
859863
if (!declaredFunctionNames.Contains(fn))
860864
{
861-
var fnDefinable = envRec.CanDeclareGlobalFunction(fn);
865+
var fnDefinable = env.CanDeclareGlobalFunction(fn);
862866
if (!fnDefinable)
863867
{
864868
ExceptionHelper.ThrowTypeError(this);
@@ -882,14 +886,14 @@ private void GlobalDeclarationInstantiation(
882886
{
883887
var vn = boundNames[j];
884888

885-
if (envRec.HasLexicalDeclaration(vn))
889+
if (env.HasLexicalDeclaration(vn))
886890
{
887891
ExceptionHelper.ThrowSyntaxError(this, $"Identifier '{vn}' has already been declared");
888892
}
889893

890894
if (!declaredFunctionNames.Contains(vn))
891895
{
892-
var vnDefinable = envRec.CanDeclareGlobalVar(vn);
896+
var vnDefinable = env.CanDeclareGlobalVar(vn);
893897
if (!vnDefinable)
894898
{
895899
ExceptionHelper.ThrowTypeError(this);
@@ -911,20 +915,20 @@ private void GlobalDeclarationInstantiation(
911915
for (var j = 0; j < boundNames.Count; j++)
912916
{
913917
var dn = boundNames[j];
914-
if (envRec.HasVarDeclaration(dn)
915-
|| envRec.HasLexicalDeclaration(dn)
916-
|| envRec.HasRestrictedGlobalProperty(dn))
918+
if (env.HasVarDeclaration(dn)
919+
|| env.HasLexicalDeclaration(dn)
920+
|| env.HasRestrictedGlobalProperty(dn))
917921
{
918922
ExceptionHelper.ThrowSyntaxError(this, $"Identifier '{dn}' has already been declared");
919923
}
920924

921925
if (d.Kind == VariableDeclarationKind.Const)
922926
{
923-
envRec.CreateImmutableBinding(dn, strict: true);
927+
env.CreateImmutableBinding(dn, strict: true);
924928
}
925929
else
926930
{
927-
envRec.CreateMutableBinding(dn, canBeDeleted: false);
931+
env.CreateMutableBinding(dn, canBeDeleted: false);
928932
}
929933
}
930934
}
@@ -934,19 +938,19 @@ private void GlobalDeclarationInstantiation(
934938
{
935939
var fn = f.Id!.Name;
936940

937-
if (envRec.HasLexicalDeclaration(fn))
941+
if (env.HasLexicalDeclaration(fn))
938942
{
939943
ExceptionHelper.ThrowSyntaxError(this, $"Identifier '{fn}' has already been declared");
940944
}
941945

942946
var fo = Function.InstantiateFunctionObject(f, env);
943-
envRec.CreateGlobalFunctionBinding(fn, fo, canBeDeleted: false);
947+
env.CreateGlobalFunctionBinding(fn, fo, canBeDeleted: false);
944948
}
945949

946950
for (var i = 0; i < declaredVarNames.Count; i++)
947951
{
948952
var vn = declaredVarNames[i];
949-
envRec.CreateGlobalVarBinding(vn, canBeDeleted: false);
953+
env.CreateGlobalVarBinding(vn, canBeDeleted: false);
950954
}
951955
}
952956

@@ -956,11 +960,11 @@ private void GlobalDeclarationInstantiation(
956960
internal ArgumentsInstance FunctionDeclarationInstantiation(
957961
FunctionInstance functionInstance,
958962
JsValue[] argumentsList,
959-
LexicalEnvironment env)
963+
EnvironmentRecord env)
960964
{
961965
var func = functionInstance._functionDefinition;
962966

963-
var envRec = (FunctionEnvironmentRecord) env._record;
967+
var envRec = (FunctionEnvironmentRecord) env;
964968
var strict = StrictModeScope.IsStrictModeCode;
965969

966970
var configuration = func.Initialize(this, functionInstance);
@@ -1010,7 +1014,7 @@ internal ArgumentsInstance FunctionDeclarationInstantiation(
10101014
// Else,
10111015
// Perform ? IteratorBindingInitialization for formals with iteratorRecord and env as arguments.
10121016

1013-
LexicalEnvironment varEnv;
1017+
EnvironmentRecord varEnv;
10141018
DeclarativeEnvironmentRecord varEnvRec;
10151019
if (!hasParameterExpressions)
10161020
{
@@ -1028,8 +1032,8 @@ internal ArgumentsInstance FunctionDeclarationInstantiation(
10281032
{
10291033
// NOTE: A separate Environment Record is needed to ensure that closures created by expressions
10301034
// in the formal parameter list do not have visibility of declarations in the function body.
1031-
varEnv = LexicalEnvironment.NewDeclarativeEnvironment(this, env);
1032-
varEnvRec = (DeclarativeEnvironmentRecord) varEnv._record;
1035+
varEnv = JintEnvironment.NewDeclarativeEnvironment(this, env);
1036+
varEnvRec = (DeclarativeEnvironmentRecord) varEnv;
10331037

10341038
UpdateVariableEnvironment(varEnv);
10351039

@@ -1044,10 +1048,10 @@ internal ArgumentsInstance FunctionDeclarationInstantiation(
10441048
// NOTE: Annex B.3.3.1 adds additional steps at this point.
10451049
// A https://tc39.es/ecma262/#sec-web-compat-functiondeclarationinstantiation
10461050

1047-
LexicalEnvironment lexEnv;
1051+
EnvironmentRecord lexEnv;
10481052
if (!strict)
10491053
{
1050-
lexEnv = LexicalEnvironment.NewDeclarativeEnvironment(this, varEnv);
1054+
lexEnv = JintEnvironment.NewDeclarativeEnvironment(this, varEnv);
10511055
// NOTE: Non-strict functions use a separate lexical Environment Record for top-level lexical declarations
10521056
// so that a direct eval can determine whether any var scoped declarations introduced by the eval code conflict
10531057
// with pre-existing top-level lexically scoped declarations. This is not needed for strict functions
@@ -1058,7 +1062,7 @@ internal ArgumentsInstance FunctionDeclarationInstantiation(
10581062
lexEnv = varEnv;
10591063
}
10601064

1061-
var lexEnvRec = lexEnv._record;
1065+
var lexEnvRec = lexEnv;
10621066

10631067
UpdateLexicalEnvironment(lexEnv);
10641068

@@ -1077,7 +1081,7 @@ internal ArgumentsInstance FunctionDeclarationInstantiation(
10771081

10781082
private void InitializeFunctions(
10791083
LinkedList<FunctionDeclaration> functionsToInitialize,
1080-
LexicalEnvironment lexEnv,
1084+
EnvironmentRecord lexEnv,
10811085
DeclarativeEnvironmentRecord varEnvRec)
10821086
{
10831087
foreach (var f in functionsToInitialize)
@@ -1129,14 +1133,14 @@ private ArgumentsInstance CreateUnmappedArgumentsObject(JsValue[] argumentsList)
11291133
/// </summary>
11301134
internal void EvalDeclarationInstantiation(
11311135
Script script,
1132-
LexicalEnvironment varEnv,
1133-
LexicalEnvironment lexEnv,
1136+
EnvironmentRecord varEnv,
1137+
EnvironmentRecord lexEnv,
11341138
bool strict)
11351139
{
11361140
var hoistingScope = HoistingScope.GetProgramLevelDeclarations(script);
11371141

1138-
var lexEnvRec = (DeclarativeEnvironmentRecord) lexEnv._record;
1139-
var varEnvRec = varEnv._record;
1142+
var lexEnvRec = (DeclarativeEnvironmentRecord) lexEnv;
1143+
var varEnvRec = varEnv;
11401144

11411145
if (!strict && hoistingScope._variablesDeclarations != null)
11421146
{
@@ -1156,9 +1160,9 @@ internal void EvalDeclarationInstantiation(
11561160
}
11571161

11581162
var thisLex = lexEnv;
1159-
while (thisLex != varEnv)
1163+
while (!ReferenceEquals(thisLex, varEnv))
11601164
{
1161-
var thisEnvRec = thisLex._record;
1165+
var thisEnvRec = thisLex;
11621166
if (!(thisEnvRec is ObjectEnvironmentRecord))
11631167
{
11641168
ref readonly var nodes = ref hoistingScope._variablesDeclarations;
@@ -1173,7 +1177,7 @@ internal void EvalDeclarationInstantiation(
11731177
}
11741178
}
11751179

1176-
thisLex = thisLex._outer;
1180+
thisLex = thisLex._outerEnv;
11771181
}
11781182
}
11791183

@@ -1295,13 +1299,13 @@ internal void EvalDeclarationInstantiation(
12951299
}
12961300

12971301
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1298-
internal void UpdateLexicalEnvironment(LexicalEnvironment newEnv)
1302+
internal void UpdateLexicalEnvironment(EnvironmentRecord newEnv)
12991303
{
13001304
_executionContexts.ReplaceTopLexicalEnvironment(newEnv);
13011305
}
13021306

13031307
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1304-
internal void UpdateVariableEnvironment(LexicalEnvironment newEnv)
1308+
internal void UpdateVariableEnvironment(EnvironmentRecord newEnv)
13051309
{
13061310
_executionContexts.ReplaceTopVariableEnvironment(newEnv);
13071311
}

Jint/EsprimaExtensions.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,11 @@ internal static void BindingInitialization(
179179
this Expression? expression,
180180
Engine engine,
181181
JsValue value,
182-
LexicalEnvironment env)
182+
EnvironmentRecord env)
183183
{
184184
if (expression is Identifier identifier)
185185
{
186-
var catchEnvRecord = (DeclarativeEnvironmentRecord) env._record;
186+
var catchEnvRecord = (DeclarativeEnvironmentRecord) env;
187187
catchEnvRecord.CreateMutableBindingAndInitialize(identifier.Name, canBeDeleted: false, value);
188188
}
189189
else if (expression is BindingPattern bindingPattern)

Jint/Native/Array/ArrayInstance.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ internal void CopyValues(ArrayInstance source, uint sourceStartIndex, uint targe
880880
? sourceDense[i]
881881
: source.GetProperty(i);
882882

883-
dense[targetStartIndex + j] = sourcePropertyDescriptor?._value != null
883+
dense[targetStartIndex + j] = sourcePropertyDescriptor?._value is not null
884884
? new PropertyDescriptor(sourcePropertyDescriptor._value, PropertyFlag.ConfigurableEnumerableWritable)
885885
: null;
886886
}

Jint/Native/Function/ClassDefinition.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,16 @@ public ClassDefinition(
4848
/// </summary>
4949
public ScriptFunctionInstance BuildConstructor(
5050
Engine engine,
51-
LexicalEnvironment env)
51+
EnvironmentRecord env)
5252
{
5353
// A class definition is always strict mode code.
5454
using var _ = (new StrictModeScope(true, true));
5555

56-
var classScope = LexicalEnvironment.NewDeclarativeEnvironment(engine, env);
56+
var classScope = JintEnvironment.NewDeclarativeEnvironment(engine, env);
5757

5858
if (_className is not null)
5959
{
60-
classScope._record.CreateImmutableBinding(_className, true);
60+
classScope.CreateImmutableBinding(_className, true);
6161
}
6262

6363
ObjectInstance? protoParent = null;
@@ -158,7 +158,7 @@ public ScriptFunctionInstance BuildConstructor(
158158

159159
if (_className is not null)
160160
{
161-
classScope._record.InitializeBinding(_className, F);
161+
classScope.InitializeBinding(_className, F);
162162
}
163163

164164
return F;

Jint/Native/Function/EvalFunctionInstance.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,16 @@ public JsValue PerformEval(JsValue x, object callerRealm, bool strictCaller, boo
9292

9393
using (new StrictModeScope(strictEval))
9494
{
95-
LexicalEnvironment lexEnv;
96-
LexicalEnvironment varEnv;
95+
EnvironmentRecord lexEnv;
96+
EnvironmentRecord varEnv;
9797
if (direct)
9898
{
99-
lexEnv = LexicalEnvironment.NewDeclarativeEnvironment(_engine, ctx.LexicalEnvironment);
99+
lexEnv = JintEnvironment.NewDeclarativeEnvironment(_engine, ctx.LexicalEnvironment);
100100
varEnv = ctx.VariableEnvironment;
101101
}
102102
else
103103
{
104-
lexEnv = LexicalEnvironment.NewDeclarativeEnvironment(_engine, Engine.GlobalEnvironment);
104+
lexEnv = JintEnvironment.NewDeclarativeEnvironment(_engine, Engine.GlobalEnvironment);
105105
varEnv = Engine.GlobalEnvironment;
106106
}
107107

Jint/Native/Function/FunctionConstructor.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public ObjectInstance Construct(JsValue[] arguments, JsValue newTarget)
125125
/// <summary>
126126
/// https://tc39.es/ecma262/#sec-runtime-semantics-instantiatefunctionobject
127127
/// </summary>
128-
internal FunctionInstance InstantiateFunctionObject(FunctionDeclaration functionDeclaration, LexicalEnvironment env)
128+
internal FunctionInstance InstantiateFunctionObject(FunctionDeclaration functionDeclaration, EnvironmentRecord env)
129129
{
130130
var functionObject = new ScriptFunctionInstance(
131131
Engine,

0 commit comments

Comments
 (0)