public VariableDeclaration(JSSymbol identifier, WriteIdentifierExpression initialization) { Symbol = identifier; Initialization = initialization; Use(Initialization); }
public override bool Replace(Node oldValue, Node newValue) { return (Replace(Initialization, oldValue, newValue, n => Initialization = n) || base.Replace(oldValue, newValue)); }
public override bool Replace(Node oldValue, Node newValue) { return Replace(Initialization, oldValue, newValue, n => Initialization = n) || base.Replace(oldValue, newValue); }
private void AssignToImplicitReturn(Expression expression) { Debug.Assert(expression == _currExpressionStatement.Expression, "Invalid situation!"); expression.RemoveUser(_currExpressionStatement); //to avoid user complications! var assign = new WriteIdentifierExpression(_implicitReturn, expression); //_currExpressionStatement.Expression = assign; _currExpressionStatement.Replace(_currExpressionStatement.Expression, assign); TerminateCurrBlock(); }
public FunctionDeclarationStatement(FunctionExpression expression, WriteIdentifierExpression implementation) { Expression = expression; Implementation = implementation; SourceOffset = expression.SourceOffset; //We don't need to Use the functionExpression, the real user of it is the implementation //Use(Expression); Debug.Assert(implementation.Value == expression && expression.User == implementation, "Invalid IR"); Use(Implementation); }
internal static mdr.ValueTypes GetType(WriteIdentifierExpression expression) { return expression.Value.ValueType; }
public override void Visit(WriteIdentifierExpression node) { base.Visit(node); node.ValueType = GetType(node); }
public override void Visit(WriteIdentifierExpression node) { var renamedSymbol = GetRenamedSymbolOf(node.Symbol); unfinishedClone = new WriteIdentifierExpression(renamedSymbol, GetCloneOf(node.Value)); Visit((Identifier)node); }
public override void Visit(WriteIdentifierExpression node) { PushLocation(node); var symbol = node.Symbol; VisitNode(node.Value); //We should not pop the results since there might be a user BeginICMethod(node); switch (symbol.SymbolType) { case JSSymbol.SymbolTypes.Local: case JSSymbol.SymbolTypes.HiddenLocal: case JSSymbol.SymbolTypes.Arguments: if (symbol.IsParameter) { if (_currFuncMetadata.Scope.HasArgumentsSymbol) { _ilGen.Call(Types.Operations.ICMethods.GetArguments); _ilGen.Ldfld(Types.DArray.Elements); _ilGen.Ldc_I4(symbol.ParameterIndex); _ilGen.Ldelema(Types.DValue.TypeOf); } else { Ldarg_Parameter(symbol.ParameterIndex); } } else { _ilGen.LoadValue(GetIndex(symbol)); } StackTop(); _ilGen.Call(Types.DValue.Set.Get(mdr.ValueTypes.DValueRef)); break; case JSSymbol.SymbolTypes.ClosedOnLocal: case JSSymbol.SymbolTypes.ParentLocal: case JSSymbol.SymbolTypes.Global: case JSSymbol.SymbolTypes.Unknown: _ilGen.Ldarg_CallFrame(); _ilGen.Ldc_I4(_stackModel.StackPointer - 1); _ilGen.Ldc_I4(GetIndex(symbol)); _ilGen.Ldc_I4(symbol.FieldId); _ilGen.Call(Types.Operations.ICMethods.WriteToContext); break; default: Trace.Fail("cannot process symbol type {0} in {1}", symbol.SymbolType, _currFuncMetadata.FullName); break; } EndICMethod(); PopLocation(); }
private void AddVarDeclarationsForParams(BlockStatement body) { foreach (var p in _targetFuncMetadata.FunctionIR.Parameters) { var s = p.Symbol; Debug.Assert(s.IsParameter, "Invalid situation, symbol {0} in function {1} must be a Parameter", s.Name, _targetFuncMetadata.Declaration); var renamedSymbol = GetRenamedSymbolOf(s); WriteIdentifierExpression initialization = null; if (s.ParameterIndex < _call.Arguments.Count) { //TODO: in the following, we have not removed the user of the argument, so it will introduce a WriteTemporary. initialization = new WriteIdentifierExpression(renamedSymbol, _call.Arguments[s.ParameterIndex]); } var declaration = new VariableDeclarationStatement(new List<VariableDeclaration>() { new VariableDeclaration(renamedSymbol, initialization) }); body.Statements.Add(declaration); } }
public override void Visit(ReturnStatement node) { var gotoEnd = new GotoStatement(_returnLabelName); if (node.Expression != null) { //We have a return value as well var cloned = new BlockStatement(new List<Statement>()); var returnValue = GetCloneOf(node.Expression); var retAssign = new WriteIdentifierExpression(_returnValueSymbol, returnValue); cloned.Statements.Add(gotoEnd); cloned.Statements.Add(new ExpressionStatement(retAssign)); result = cloned; } else { result = gotoEnd; } }
public abstract void Visit(WriteIdentifierExpression node);
public override void Visit(WriteIdentifierExpression node) { Visit((Identifier)node); }
public override void Visit(WriteIdentifierExpression node) { AssignToImplicitReturn(node); }
public override void Visit(WriteIdentifierExpression node) { Visit((Identifier)node); VisitNode(node.Value); }
public VariableDeclaration(Identifier identifier, WriteIdentifierExpression initialization) : this(identifier.Symbol, initialization) { SourceOffset = identifier.SourceOffset; }
public override void Visit(WriteIdentifierExpression node) { base.Visit(node); Debug.Assert(node.Symbol.Writers.Contains(node), "Writer {0} is not in the writer list of symbol {0}", node.Symbol); }
public override void Visit(WriteIdentifierExpression node) { PushLocation(node); VisitNode(node.Value); var valueType = _result.ValueType; _ilGen.Dup(); var symbol = node.Symbol; if (symbol.SymbolType == JSSymbol.SymbolTypes.OuterDuplicate) symbol = symbol.ResolvedSymbol; var local = _localVars.Get(symbol); if (local == null) { if (symbol.IsParameter) { if (_currFuncMetadata.Scope.HasArgumentsSymbol) { _ilGen.Ldloc(_arguments); _ilGen.Ldfld(Types.DArray.Elements); _ilGen.Ldc_I4(symbol.ParameterIndex); _ilGen.Ldelema(Types.DValue.TypeOf); } else { Ldarg_Parameter(symbol.ParameterIndex); //this function changes the _result } _ilGen.Call(Types.Operations.Assign.Get(valueType)); } else { Debug.Assert(symbol.SymbolType == JSSymbol.SymbolTypes.Unknown, "symbol {0}:{1} must have a variable", symbol.Name, symbol.SymbolType); var value = _localVars.PushTemporary(_result.ValueType); _ilGen.Stloc(value); var pd = _localVars.PushTemporary(Types.PropertyDescriptor.TypeOf); _ilGen.Ldloc(_context); _ilGen.Ldc_I4(symbol.FieldId); _ilGen.Call(Types.DObject.GetPropertyDescriptorByFieldId); _ilGen.Stloc(pd); var undefined = _ilGen.DefineLabel(); var done = _ilGen.DefineLabel(); _ilGen.Ldloc(pd); _ilGen.Call(Types.PropertyDescriptor.IsUndefined); _ilGen.Brtrue(undefined); _ilGen.Ldloc(pd); _ilGen.Ldloc(_context); _ilGen.Ldloc(value); _ilGen.Call(Types.PropertyDescriptor.Set.Get(mdr.ValueTypes.Object, _result.ValueType)); _ilGen.Br(done); _ilGen.MarkLabel(undefined); _ilGen.LoadRuntimeInstance(); _ilGen.Ldfld(Types.Runtime.GlobalContext); _ilGen.Ldc_I4(symbol.FieldId); _ilGen.Ldloc(value); _ilGen.Call(Types.DObject.SetFieldByFieldId(_result.ValueType)); _ilGen.MarkLabel(done); _localVars.PopTemporary(pd); _localVars.PopTemporary(value); } } else { if (local.LocalType == Types.PropertyDescriptor.TypeOf) { var value = _localVars.PushTemporary(_result.ValueType); _ilGen.Stloc(value); _ilGen.Ldloc(local); if (symbol.SymbolType == JSSymbol.SymbolTypes.Global) { _ilGen.LoadRuntimeInstance(); _ilGen.Ldfld(Types.Runtime.GlobalContext); } else { _ilGen.Ldloc(_context); } _ilGen.Ldloc(value); _ilGen.Call(Types.PropertyDescriptor.Set.Get(mdr.ValueTypes.Object, _result.ValueType)); _localVars.PopTemporary(value); } else if (local.LocalType == Types.DValue.TypeOf) { _ilGen.Ldloca(local); _ilGen.Call(Types.Operations.Assign.Get(_result.ValueType)); } else if (local.LocalType == Types.DValue.RefOf) { _ilGen.Ldloc(local); _ilGen.Call(Types.Operations.Assign.Get(_result.ValueType)); } else { if (local.LocalType != _result.Type) { if ((_result.ValueType == mdr.ValueTypes.Array || _result.ValueType == mdr.ValueTypes.Null || _result.ValueType == mdr.ValueTypes.Undefined) && Types.ValueTypeOf(local.LocalType) == mdr.ValueTypes.Object) _ilGen.Castclass(Types.TypeOf(mdr.ValueTypes.Object)); else _ilGen.Call(Types.ClrSys.Convert.Get(_result.ValueType, Types.ValueTypeOf(local.LocalType))); } _ilGen.Stloc(local); } } _result.ValueType = valueType; //since we .Dup(), this ensures that final value type is correct PopLocation(); }
public override void Visit(WriteIdentifierExpression node) { PushLocation(node); VisitNode(node.Value); WriteResults(node.Symbol, true); PopLocation(); }