private static BoundExpression[] Perform(BoundBody node, BoundTypeManager.DefiniteAssignmentMarker.Branch parentBranch) { var marker = new Marker(node.TypeManager, parentBranch); marker.Visit(node); return marker.ResultExpressions; }
public Rewriter(IEnumerable<BoundExpression> resultExpressions, BoundTypeManager typeManager) { _typeManager = typeManager; _resultExpressions = new HashSet<BoundExpression>(resultExpressions); _resultTemporary = new BoundTemporary( --_lastTemporaryIndex, typeManager.CreateType(null, BoundTypeKind.Temporary) ); }
public TypeMarker(BoundTypeManager typeManager) { _typeManager = typeManager; // Initialize all globals to unknown; they come from the // GlobalScope object and are implicitly converted to Get/SetMember's. foreach (BoundType type in _typeManager.Types) { if (type.Kind == BoundTypeKind.Global) type.Type = BoundValueType.Unknown; } }
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 void EmitLocals(BoundTypeManager typeManager) { _magicTypes = _body.TypeManager.MagicTypes.ToDictionary(p => p.MagicType, p => p.Type); // Create the arguments local if it's required and there isn't // a closure field for it. if ((_body.Flags & BoundBodyFlags.ArgumentsReferenced) != 0 && ArgumentsEmitter == null) { var type = _magicTypes[BoundMagicVariableType.Arguments]; var argumentsEmitter = CreateEmitter(type); argumentsEmitter.DeclareLocal(); ArgumentsEmitter = argumentsEmitter; _locals.Add(type, argumentsEmitter); } if ((_body.Flags & BoundBodyFlags.GlobalReferenced) != 0) { _globalLocal = IL.DeclareLocal(typeof(JsGlobal)); EmitLoad(SpecialLocal.Runtime); IL.EmitCall(_runtimeGetGlobal); IL.Emit(OpCodes.Stloc, _globalLocal); } if ((_body.Flags & BoundBodyFlags.GlobalScopeReferenced) != 0) { var type = _magicTypes[BoundMagicVariableType.Global]; GlobalScopeEmitter = CreateEmitter(type); GlobalScopeEmitter.DeclareLocal(); GlobalScopeEmitter.EmitSetValue(new BoundEmitExpression( BoundValueType.Object, () => { EmitLoad(SpecialLocal.Runtime); IL.EmitCall(_runtimeGetGlobalScope); } )); _locals.Add(type, GlobalScopeEmitter); } if ((_body.Flags & BoundBodyFlags.ThisReferenced) != 0) { // We can't set assign to _thisLocal because then EmitLoad // would return the local. var type = _magicTypes[BoundMagicVariableType.This]; var thisLocal = CreateEmitter(type); thisLocal.DeclareLocal(); thisLocal.EmitSetValue(new BoundEmitExpression( BoundValueType.Unknown, () => EmitLoad(SpecialLocal.This) )); _thisLocal = thisLocal; _locals.Add(type, _thisLocal); } var getUnknown = new BoundGetVariable(BoundMagicVariable.Undefined); foreach (var type in typeManager.Types) { if (type.Type == BoundValueType.Unset) continue; if (type.Kind == BoundTypeKind.Local || type.Kind == BoundTypeKind.Temporary) { var emitter = CreateEmitter(type); emitter.DeclareLocal(); if (type.Kind == BoundTypeKind.Local) emitter.Local.SetLocalSymInfo(type.Name); if (!type.DefinitelyAssigned) emitter.EmitSetValue(getUnknown); _locals.Add(type, emitter); } else if (type.Kind == BoundTypeKind.ClosureField) { _locals.Add(type, new ClosureFieldEmitter( Generator, Closure.Fields[type.Name] )); } } }
public BoundType(BoundTypeManager typeManager, string name, BoundTypeKind kind) { _typeManager = typeManager; Name = name; Kind = kind; }
public DefiniteAssignmentMarker(BoundTypeManager typeManager, Branch parentBranch) { _typeManager = typeManager; _parentBranch = parentBranch; }
public void JoinBranch(BoundTypeManager.DefiniteAssignmentMarker.Branch branch) { // When a branch is killed, _branch becomes null. We test for // that here to simplify the algorithm. We also skip the branch // when it's the branch of this block for the same reason. if (branch.IsKilled || branch == Branch) return; if (Joins == null) Joins = new List<BoundTypeManager.DefiniteAssignmentMarker.Branch>(); Joins.Add(branch); }
public Block(BoundTypeManager.DefiniteAssignmentMarker.Branch branch, string label, bool isBreakTarget, bool isContinueTarget, BoundFinally @finally) { Label = label; Finally = @finally; Branch = branch; IsBreakTarget = isBreakTarget; IsContinueTarget = isContinueTarget; }