Skip to content

Commit 9afa790

Browse files
committed
wip
1 parent e752354 commit 9afa790

35 files changed

+818
-171
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Xunit;
2+
3+
namespace Jint.Tests.Test262.Language.Expressions
4+
{
5+
public class YieldTests : Test262Test
6+
{
7+
[Theory(DisplayName = "language\\expressions\\yield")]
8+
[MemberData(nameof(SourceFiles), "language\\expressions\\yield", false)]
9+
[MemberData(nameof(SourceFiles), "language\\expressions\\yield", true, Skip = "Skipped")]
10+
protected void New(SourceFile sourceFile)
11+
{
12+
RunTestInternal(sourceFile);
13+
}
14+
}
15+
}

Jint.Tests.Test262/Test262Test.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,6 @@ public static IEnumerable<object[]> SourceFiles(string pathPrefix, bool skipped)
244244
skip = true;
245245
reason = "BigInt not implemented";
246246
break;
247-
case "generators":
248-
skip = true;
249-
reason = "generators not implemented";
250-
break;
251247
case "async-functions":
252248
skip = true;
253249
reason = "async-functions not implemented";

Jint/Engine.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Jint.Native;
77
using Jint.Native.Argument;
88
using Jint.Native.Function;
9+
using Jint.Native.Generator;
910
using Jint.Native.Object;
1011
using Jint.Native.Promise;
1112
using Jint.Native.Symbol;
@@ -1222,6 +1223,13 @@ internal void UpdateVariableEnvironment(EnvironmentRecord newEnv)
12221223
_executionContexts.ReplaceTopVariableEnvironment(newEnv);
12231224
}
12241225

1226+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1227+
internal ExecutionContext UpdateGenerator(Generator generator)
1228+
{
1229+
// TODO
1230+
return ExecutionContext;
1231+
}
1232+
12251233
internal JsValue Call(ICallable callable, JsValue thisObject, JsValue[] arguments, JintExpression expression)
12261234
{
12271235
if (callable is FunctionInstance functionInstance)

Jint/Native/Array/ArrayConstructor.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ public ObjectInstance Construct(JsValue[] arguments, JsValue newTarget)
282282
}
283283

284284
var proto = GetPrototypeFromConstructor(
285+
_engine,
285286
newTarget,
286287
static intrinsics => intrinsics.Array.PrototypeObject);
287288

@@ -418,7 +419,7 @@ public ObjectInstance ArraySpeciesCreate(ObjectInstance originalArray, ulong len
418419
if (c.IsConstructor)
419420
{
420421
var thisRealm = _engine.ExecutionContext.Realm;
421-
var realmC = GetFunctionRealm(c);
422+
var realmC = GetFunctionRealm(_engine, c);
422423
if (!ReferenceEquals(thisRealm, realmC))
423424
{
424425
if (ReferenceEquals(c, realmC.Intrinsics.Array))

Jint/Native/Function/FunctionConstructor.cs

Lines changed: 136 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
using Esprima;
1+
using System;
2+
using Esprima;
23
using Esprima.Ast;
4+
using Jint.Native.Generator;
35
using Jint.Native.Object;
46
using Jint.Runtime;
57
using Jint.Runtime.Descriptors;
68
using Jint.Runtime.Environments;
9+
using Jint.Runtime.Interpreter;
710

811
namespace Jint.Native.Function
912
{
@@ -32,43 +35,116 @@ public override JsValue Call(JsValue thisObject, JsValue[] arguments)
3235
return Construct(arguments, thisObject);
3336
}
3437

38+
public ObjectInstance Construct(JsValue[] arguments, JsValue newTarget)
39+
{
40+
var function = CreateDynamicFunction(
41+
_engine,
42+
this,
43+
newTarget,
44+
FunctionKind.Normal,
45+
arguments);
46+
47+
return function;
48+
}
49+
3550
/// <summary>
3651
/// https://tc39.es/ecma262/#sec-createdynamicfunction
3752
/// </summary>
38-
public ObjectInstance Construct(JsValue[] arguments, JsValue newTarget)
53+
internal static FunctionInstance CreateDynamicFunction(
54+
Engine engine,
55+
ObjectInstance constructor,
56+
JsValue newTarget,
57+
FunctionKind kind,
58+
JsValue[] args)
3959
{
40-
var argCount = arguments.Length;
41-
string p = "";
42-
string body = "";
60+
if (newTarget.IsUndefined())
61+
{
62+
newTarget = constructor;
63+
}
64+
65+
Func<Intrinsics, ObjectInstance> fallbackProto = null;
66+
switch (kind)
67+
{
68+
case FunctionKind.Normal:
69+
fallbackProto = intrinsics => intrinsics.Function.PrototypeObject;
70+
break;
71+
case FunctionKind.Generator:
72+
fallbackProto = intrinsics => intrinsics.GeneratorFunction.PrototypeObject;
73+
break;
74+
case FunctionKind.AsyncGenerator:
75+
case FunctionKind.Async:
76+
default:
77+
ExceptionHelper.ThrowArgumentOutOfRangeException(nameof(kind), kind.ToString());
78+
break;
79+
}
80+
81+
var argCount = args.Length;
82+
var p = "";
83+
var body = "";
4384

4485
if (argCount == 1)
4586
{
46-
body = TypeConverter.ToString(arguments[0]);
87+
body = TypeConverter.ToString(args[0]);
4788
}
4889
else if (argCount > 1)
4990
{
50-
var firstArg = arguments[0];
91+
var firstArg = args[0];
5192
p = TypeConverter.ToString(firstArg);
5293
for (var k = 1; k < argCount - 1; k++)
5394
{
54-
var nextArg = arguments[k];
95+
var nextArg = args[k];
5596
p += "," + TypeConverter.ToString(nextArg);
5697
}
5798

58-
body = TypeConverter.ToString(arguments[argCount-1]);
99+
body = TypeConverter.ToString(args[argCount - 1]);
59100
}
60101

61102
IFunction function = null;
62103
try
63104
{
64-
string functionExpression;
105+
string functionExpression = null;
65106
if (argCount == 0)
66107
{
67-
functionExpression = "function f(){}";
108+
switch (kind)
109+
{
110+
case FunctionKind.Normal:
111+
functionExpression = "function f(){}";
112+
break;
113+
case FunctionKind.Generator:
114+
functionExpression = "function* f(){}";
115+
break;
116+
case FunctionKind.Async:
117+
ExceptionHelper.ThrowNotImplementedException("Async functions not implemented");
118+
break;
119+
case FunctionKind.AsyncGenerator:
120+
ExceptionHelper.ThrowNotImplementedException("Async generators not implemented");
121+
break;
122+
default:
123+
ExceptionHelper.ThrowArgumentOutOfRangeException(nameof(kind), kind.ToString());
124+
break;
125+
}
68126
}
69127
else
70128
{
71-
functionExpression = "function f(";
129+
switch (kind)
130+
{
131+
case FunctionKind.Normal:
132+
functionExpression = "function f(";
133+
break;
134+
case FunctionKind.Generator:
135+
functionExpression = "function* f(";
136+
break;
137+
case FunctionKind.Async:
138+
ExceptionHelper.ThrowNotImplementedException("Async functions not implemented");
139+
break;
140+
case FunctionKind.AsyncGenerator:
141+
ExceptionHelper.ThrowNotImplementedException("Async generators not implemented");
142+
break;
143+
default:
144+
ExceptionHelper.ThrowArgumentOutOfRangeException(nameof(kind), kind.ToString());
145+
break;
146+
}
147+
72148
if (p.IndexOf('/') != -1)
73149
{
74150
// ensure comments don't screw up things
@@ -95,49 +171,70 @@ public ObjectInstance Construct(JsValue[] arguments, JsValue newTarget)
95171
var parser = new JavaScriptParser(functionExpression, ParserOptions);
96172
function = (IFunction) parser.ParseScript().Body[0];
97173
}
98-
catch (ParserException)
174+
catch (ParserException ex)
99175
{
100-
ExceptionHelper.ThrowSyntaxError(_realm);
176+
ExceptionHelper.ThrowSyntaxError(engine.Realm, ex.Message);
101177
}
102178

103-
// TODO generators etc, rewrite logic
104-
var proto = GetPrototypeFromConstructor(newTarget, static intrinsics => intrinsics.Function.PrototypeObject);
105-
106-
var functionObject = new ScriptFunctionInstance(
107-
Engine,
108-
function,
109-
_realm.GlobalEnv,
110-
function.Strict,
111-
proto)
112-
{
113-
_realm = _realm
114-
};
179+
var proto = GetPrototypeFromConstructor(engine, newTarget, fallbackProto);
180+
var thisMode = function.Strict
181+
? FunctionThisMode.Strict
182+
: FunctionThisMode.Global;
115183

116-
functionObject.MakeConstructor();
184+
FunctionInstance F = new ScriptFunctionInstance(
185+
engine,
186+
new JintFunctionDefinition(engine, function),
187+
engine.Realm.GlobalEnv,
188+
thisMode,
189+
proto);
117190

118-
// the function is not actually a named function
119-
functionObject.SetFunctionName(_functionNameAnonymous, force: true);
191+
if (kind == FunctionKind.Generator)
192+
{
193+
F = new GeneratorFunctionInstance(engine, engine.Realm, F);
194+
}
195+
else if (kind == FunctionKind.AsyncGenerator)
196+
{
197+
// TODO
198+
// Let prototype be ! OrdinaryObjectCreate(%AsyncGeneratorFunction.prototype.prototype%).
199+
// Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
200+
ExceptionHelper.ThrowNotImplementedException();
201+
}
202+
else if (kind == FunctionKind.Normal)
203+
{
204+
F.MakeConstructor();
205+
}
120206

121-
return functionObject;
207+
F.SetFunctionName(_functionNameAnonymous, force: true);
208+
return F;
122209
}
123210

124211
/// <summary>
125212
/// https://tc39.es/ecma262/#sec-runtime-semantics-instantiatefunctionobject
126213
/// </summary>
127-
internal FunctionInstance InstantiateFunctionObject(FunctionDeclaration functionDeclaration, EnvironmentRecord env)
214+
internal FunctionInstance InstantiateFunctionObject(FunctionDeclaration functionDeclaration, EnvironmentRecord scope)
128215
{
129-
var functionObject = new ScriptFunctionInstance(
216+
var strict = functionDeclaration.Strict || _engine._isStrict;
217+
FunctionInstance F = new ScriptFunctionInstance(
130218
Engine,
131219
functionDeclaration,
132-
env,
133-
functionDeclaration.Strict || _engine._isStrict)
134-
{
135-
_realm = _realm
136-
};
220+
scope,
221+
strict,
222+
_realm.Intrinsics.Function.PrototypeObject);;
137223

138-
functionObject.MakeConstructor();
224+
var name = functionDeclaration.Id?.Name ?? "default";
225+
if (functionDeclaration.Generator)
226+
{
227+
// https://tc39.es/ecma262/#sec-generator-function-definitions-runtime-semantics-instantiatefunctionobject
228+
F = new GeneratorFunctionInstance(_engine, _realm, F);
229+
}
230+
else
231+
{
232+
// https://tc39.es/ecma262/#sec-function-definitions-runtime-semantics-instantiatefunctionobject
233+
F.MakeConstructor();
234+
}
139235

140-
return functionObject;
236+
F.SetFunctionName(name);
237+
return F;
141238
}
142239
}
143240
}

0 commit comments

Comments
 (0)