public BoundClosureField(BoundClosure closure, IBoundType type) : base(type) { if (closure == null) throw new ArgumentNullException("closure"); Closure = closure; Builder = closure.Builder.CreateClosureFieldBuilder(this); }
public BoundArgument(string name, int index, BoundClosure closure) { if (name == null) throw new ArgumentNullException("name"); Name = name; Index = index; Closure = closure; }
public BoundClosure(BoundClosure parent, IEnumerable<IBoundType> fields, IScriptBuilder scriptBuilder) { if (fields == null) throw new ArgumentNullException("fields"); if (scriptBuilder == null) throw new ArgumentNullException("scriptBuilder"); Parent = parent; Builder = scriptBuilder.CreateClosureBuilder(this); _fields = new BoundClosureFieldCollection(); foreach (var field in fields) { _fields.Add(new BoundClosureField(this, field)); } Fields = ReadOnlyKeyedCollection.Create(_fields); }
public Scope(Scope parent, BodySyntax body, IScriptBuilder scriptBuilder) { Parent = parent; TypeManager = new BoundTypeManager(); if (body.Closure != null) { _sourceClosure = body.Closure; Closure = new BoundClosure( FindParentClosure(), body.Closure.Fields.Select(p => TypeManager.CreateType(p, BoundTypeKind.ClosureField)), scriptBuilder ); } foreach (var variable in body.Identifiers) { if (variable.Index.HasValue) { BoundClosure closure = null; if (variable.Closure != null) closure = GetClosure(variable.Closure); _arguments.Add(variable, new BoundArgument(variable.Name, variable.Index.Value, closure)); } else if (variable.Closure == null) { BoundLocalBase local; if (variable.Type == IdentifierType.Global) local = new BoundGlobal(variable.IsDeclared, TypeManager.CreateType(variable.Name, BoundTypeKind.Global)); else local = new BoundLocal(variable.IsDeclared, TypeManager.CreateType(variable.Name, BoundTypeKind.Local)); _locals.Add(variable, local); } } }
public Scope FindScope(BoundClosure closure) { // Here we find the scope that the closure actually belongs to, // not the scope the closure is scoped in. This method is used // to get the scope the closure actually belongs to to be able to // get information that is cached in that scope, e.g. the // _arguments and ArgumentsClosureField. var scope = this; while (scope._body.Closure != closure) { scope = scope.Parent; } return scope; }
public void EmitLoadClosure(BoundClosure closure) { // Push our scoped closure onto the stack. if (_closureLocal != null) IL.Emit(OpCodes.Ldloc, _closureLocal); else IL.Emit(OpCodes.Ldarg_0); // If the request wasn't for our scoped closure, but a parent, // resolve the parent. if (Closure != closure) IL.Emit(OpCodes.Ldfld, Closure.Builder.ParentFields[closure.Builder].Field); }