public ValueEmitter GetEmitter(IBoundReadable readable) { IBoundType type = null; var variable = readable as BoundVariable; if (variable != null) { type = variable.Type; } else { var magic = readable as BoundMagicVariable; if (magic != null) _magicTypes.TryGetValue(magic.VariableType, out type); } if (type == null) return null; var scope = this; while (scope != null) { ValueEmitter emitter; if (scope._locals.TryGetValue(type, out emitter)) return emitter; scope = scope.Parent; } return null; }
private void MarkRead(IBoundReadable variable) { if (!_branch.IsKilled) { var hasBoundType = variable as BoundVariable; if (hasBoundType != null) _branch.MarkRead(hasBoundType); } }
private IBoundType ResolveType(IBoundReadable readable) { var variable = readable as BoundVariable; if (variable != null) return variable.Type; var argument = readable as BoundArgument; if (argument != null) { variable = GetMappedArgument(argument); if (variable != null) return variable.Type; return null; } var magic = readable as BoundMagicVariable; if (magic != null) { IBoundType result; if (_magicTypes.TryGetValue(magic.VariableType, out result)) return result; } return null; }
public void SpeculateType(IBoundReadable target, IBoundReadable source) { var sourceType = ResolveType(source); var targetType = ResolveType(target); if (sourceType != null && targetType != null) { #if TRACE_SPECULATION Trace.WriteLine("Speculating " + target + " from " + source); #endif _marker.SpeculateType(targetType, sourceType); } }
public void SpeculateType(IBoundReadable target, SpeculatedType type, bool definite) { var targetType = ResolveType(target); if (targetType != null) { #if TRACE_SPECULATION Trace.WriteLine("Speculating " + target + " to " + type + " definite " + definite); #endif _marker.SpeculateType(targetType, type, definite); } }
private BoundValueType EmitGetVariable(IBoundReadable variable) { switch (variable.Kind) { case BoundVariableKind.Global: return _scope.GlobalScopeEmitter.EmitGetMember(new BoundGetMember( new BoundGetVariable(BoundMagicVariable.Global), BoundConstant.Create(((BoundGlobal)variable).Name) )); case BoundVariableKind.Local: case BoundVariableKind.Temporary: case BoundVariableKind.ClosureField: _scope.GetEmitter(variable).EmitGetValue(); return variable.ValueType; case BoundVariableKind.Magic: switch (((BoundMagicVariable)variable).VariableType) { case BoundMagicVariableType.Global: return _scope.EmitLoad(SpecialLocal.GlobalScope); case BoundMagicVariableType.This: return _scope.EmitLoad(SpecialLocal.This); case BoundMagicVariableType.Null: return _scope.EmitLoad(SpecialLocal.Null); case BoundMagicVariableType.Undefined: return _scope.EmitLoad(SpecialLocal.Undefined); case BoundMagicVariableType.Arguments: return _scope.EmitLoad(SpecialLocal.Arguments); default: throw new InvalidOperationException(); } case BoundVariableKind.Argument: var argument = (BoundArgument)variable; // Check whether the argument is mapped to a local or closure // field. var scope = argument.Closure == null ? _scope : _scope.FindScope(argument.Closure); var mappedArgument = scope.GetMappedArgument(argument); if (mappedArgument != null) return EmitGetVariable(mappedArgument); BoundGetVariable getVariable; if (scope.ArgumentsClosureField != null) getVariable = new BoundGetVariable(scope.ArgumentsClosureField); else getVariable = new BoundGetVariable(BoundMagicVariable.Arguments); EmitGetMember(new BoundGetMember( getVariable, BoundConstant.Create((double)argument.Index) )); return BoundValueType.Unknown; default: throw new InvalidOperationException(); } }