public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { var vr = _left as VariableReference; if (vr != null && vr._descriptor.IsDefined) { var pd = vr._descriptor.lastPredictedType; switch (pd) { case PredictedType.Int: case PredictedType.Unknown: { vr._descriptor.lastPredictedType = PredictedType.Number; break; } case PredictedType.Double: { // кроме как double он ничем больше оказаться не может. Даже NaN это double break; } default: { vr._descriptor.lastPredictedType = PredictedType.Ambiguous; break; } } } }
internal void Optimize(ref CodeBlock self, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { CodeNode cn = self; Optimize(ref cn, owner, message, opts, stats); self = (CodeBlock)cn; }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { if (_reexportSourceModuleName != null) { return; } if (_internalDefinition != null) { CodeNode t = _internalDefinition; _internalDefinition.Optimize(ref t, owner, message, opts, stats); if (t != _internalDefinition) { _internalDefinition = t as VariableDefinition; } } else { for (var i = 0; i < _map.Count; i++) { var v = _map[i].Value; _map[i].Value.Optimize(ref v, owner, message, opts, stats); if (v != _map[i].Value) { _map[i] = new KeyValuePair <string, Expression>(_map[i].Key, v); } } } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { if (_body != null) { _body.Optimize(ref _body, owner, message, opts, stats); } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { var bd = _body as CodeNode; var oldScopeIsolation = _body._suppressScopeIsolation; _body._suppressScopeIsolation = SuppressScopeIsolationMode.DoNotSuppress; _body.Optimize(ref bd, this, message, opts, _functionInfo); _body._suppressScopeIsolation = oldScopeIsolation; if (_functionInfo.Returns.Count > 0) { _functionInfo.ResultType = _functionInfo.Returns[0].ResultType; for (var i = 1; i < _functionInfo.Returns.Count; i++) { if (_functionInfo.ResultType != _functionInfo.Returns[i].ResultType) { _functionInfo.ResultType = PredictedType.Ambiguous; if (message != null && _functionInfo.ResultType >= PredictedType.Undefined && _functionInfo.Returns[i].ResultType >= PredictedType.Undefined) { message(MessageLevel.Warning, parameters[i].references[0].Position, 0, "Type of return value is ambiguous"); } break; } } } else { _functionInfo.ResultType = PredictedType.Undefined; } }
private void expressionWillThrow(InternalCompilerMessageCallback message) { if (message != null && !(this is RegExpExpression)) { message(MessageLevel.Warning, Position, Length, "Expression will throw an exception"); } }
internal void baseOptimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { var f = _left as CodeNode; var s = _right as CodeNode; if (f != null) { f.Optimize(ref f, owner, message, opts, stats); _left = f as Expression; } if (s != null) { s.Optimize(ref s, owner, message, opts, stats); _right = s as Expression; } if (ContextIndependent && !(this is Constant)) { try { _this = new Constant(Evaluate(null)); } catch (JSException e) { _this = new ExpressionWrapper(new Throw(new Constant(e.Error))); expressionWillThrow(message); } catch (Exception e) { _this = new ExpressionWrapper(new Throw(e)); expressionWillThrow(message); } } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { for (var i = 0; i < expressions.Length; i++) { expressions[i].Optimize(ref expressions[i], owner, message, opts, stats); } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { for (int i = 0; i < _initializers.Length; i++) { _initializers[i].Optimize(ref _initializers[i], owner, message, opts, stats); } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { var cn = value as CodeNode; value.Optimize(ref cn, owner, message, opts, stats); value = cn as Expression; base.Optimize(ref _this, owner, message, opts, stats); }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { baseOptimize(ref _this, owner, message, opts, stats); if (_this == this && (_left.ResultType == PredictedType.Number && _right.ResultType == PredictedType.Number)) { _this = new NumberLess(_left, _right); } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { statement.Optimize(ref statement, owner, message, opts, stats); if (statement == null) { _this = null; } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { base.Optimize(ref _this, owner, message, opts, stats); for (var i = _arguments.Length; i-- > 0;) { var cn = _arguments[i] as CodeNode; cn.Optimize(ref cn, owner, message, opts, stats); _arguments[i] = cn as Expression; } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { base.Optimize(ref _this, owner, message, opts, stats); if (Tools.IsEqual(_left.ResultType, PredictedType.Number, PredictedType.Group) && Tools.IsEqual(_right.ResultType, PredictedType.Number, PredictedType.Group)) { _this = new NumberAddition(_left, _right); } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { for (var i = elements.Length; i-- > 0;) { var cn = elements[i] as CodeNode; if (cn != null) { cn.Optimize(ref cn, owner, message, opts, stats); elements[i] = cn as Expression; } } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { if ((opts & Options.SuppressConstantPropogation) == 0 && !_descriptor.captured && _descriptor.isDefined && !stats.ContainsWith && !stats.ContainsEval && (_descriptor.owner != owner || !owner._functionInfo.ContainsArguments)) { var assigns = _descriptor.assignments; if (assigns != null && assigns.Count > 0) { CodeNode lastAssign = null; for (var i = assigns.Count; i-- > 0;) { if (assigns[i]._left == this || ((assigns[i]._left is AssignmentOperatorCache) && assigns[i]._left._left == this)) { lastAssign = null; break; } if (assigns[i].Position > Position) { if ((_codeContext & CodeContext.InLoop) != 0 && ((assigns[i] as Expression)._codeContext & CodeContext.InLoop) != 0) { lastAssign = null; break; } continue; } if (_descriptor.isReadOnly) { if (assigns[i] is ForceAssignmentOperator) { lastAssign = assigns[i]; break; } } else if (lastAssign == null || assigns[i].Position > lastAssign.Position) { lastAssign = assigns[i]; } } var assign = lastAssign as Assignment; if (assign != null && (assign._codeContext & CodeContext.Conditional) == 0 && assign._right is Constant) { _this = assign._right; } } } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { if (value != null) { var t = value as CodeNode; value.Optimize(ref t, owner, message, opts, stats); value = (Expression)t; if (value is Empty || ((value is Constant) && value.Evaluate(null) == JSValue.undefined)) { value = null; } } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { body.Optimize(ref body, owner, message, opts, stats); if (catchBody != null) { catchBody.Optimize(ref catchBody, owner, message, opts, stats); } if (finallyBody != null) { finallyBody.Optimize(ref finallyBody, owner, message, opts, stats); } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { _baseClass?.Optimize(ref _baseClass, owner, message, opts, stats); for (var i = _members.Length; i-- > 0;) { _members[i]._value.Optimize(ref _members[i]._value, owner, message, opts, stats); } foreach (var prop in computedProperties) { prop._name.Optimize(ref prop._name, owner, message, opts, stats); prop._value.Optimize(ref prop._value, owner, message, opts, stats); } }
public ParseInfo(string code, string sourceCode, InternalCompilerMessageCallback message) { Code = code; SourceCode = sourceCode; Labels = new List <string>(); AllowDirectives = true; AllowBreak = new Stack <bool>(); AllowBreak.Push(false); AllowContinue = new Stack <bool>(); AllowContinue.Push(false); this.Message = message; StringConstants = new Dictionary <string, JSValue>(); IntConstants = new Dictionary <int, JSValue>(); DoubleConstants = new Dictionary <double, JSValue>(); Variables = new List <VariableDescriptor>(); }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { /* * Дублирование оптимизации для локальных переменных нужно для правильной работы ряда оптимизаций */ if (_variables != null) { for (var i = 0; i < _variables.Length; i++) { if (_variables[i].initializer != null) { var cn = _variables[i].initializer as CodeNode; cn.Optimize(ref cn, owner, message, opts, stats); } } } for (int i = 0; i < _lines.Length; i++) { var cn = _lines[i] as CodeNode; cn.Optimize( ref cn, owner, message, opts | (i == _lines.Length - 1 ? Options.SuppressUselessExpressionsElimination | Options.SuppressUselessStatementsElimination : Options.None), stats); _lines[i] = cn; } if (_variables != null) { for (var i = 0; i < _variables.Length; i++) { if (_variables[i].initializer != null) { var cn = _variables[i].initializer as CodeNode; cn.Optimize(ref cn, owner, message, opts, stats); } } } if (_lines.Length == 1 && _suppressScopeIsolation == SuppressScopeIsolationMode.Suppress && _variables.Length == 0) { _this = _lines[0]; } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { base.Optimize(ref _this, owner, message, opts, stats); for (var i = threads.Length; i-- > 0;) { var cn = threads[i] as CodeNode; cn.Optimize(ref cn, owner, message, opts, stats); threads[i] = cn as Expression; } if (message != null && (threads[0] is Variable || threads[0] is Constant) && (threads[1] is Variable || threads[1] is Constant) && ResultType == PredictedType.Ambiguous) { message(MessageLevel.Warning, Position, Length, "Type of an expression is ambiguous"); } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { image.Optimize(ref image, owner, message, opts, stats); for (var i = 1; i < Cases.Length; i++) { Cases[i].statement.Optimize(ref Cases[i].statement, owner, message, opts, stats); } for (var i = Body.Length; i-- > 0;) { if (Body[i] == null) { continue; } var cn = Body[i]; cn.Optimize(ref cn, owner, message, opts, stats); Body[i] = cn; } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { if (_initializer != null) { _initializer.Optimize(ref _initializer, owner, message, opts, stats); } if (_condition != null) { _condition.Optimize(ref _condition, owner, message, opts, stats); } if (_post != null) { _post.Optimize(ref _post, owner, message, opts, stats); } if (_body != null) { _body.Optimize(ref _body, owner, message, opts, stats); } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { for (var i = Values.Length; i-- > 0;) { var cn = Values[i] as CodeNode; cn.Optimize(ref cn, owner, message, opts, stats); Values[i] = cn as Expression; } for (var i = 0; i < ComputedProperties.Length; i++) { var key = ComputedProperties[i].Key; key.Optimize(ref key, owner, message, opts, stats); var value = ComputedProperties[i].Value; value.Optimize(ref value, owner, message, opts, stats); ComputedProperties[i] = new KeyValuePair <Expression, Expression>(key, value); } }
public ParseInfo(string sourceCode, InternalCompilerMessageCallback message) { Code = Parser.RemoveComments(sourceCode, 0); SourceCode = sourceCode; Message = message; CodeContext |= CodeContext.AllowDirectives; Labels = new List <string>(); AllowBreak = new Stack <bool>(); AllowContinue = new Stack <bool>(); StringConstants = new Dictionary <string, JSValue>(); IntConstants = new Dictionary <int, JSValue>(); DoubleConstants = new Dictionary <double, JSValue>(); Variables = new List <VariableDescriptor>(); AllowContinue.Push(false); AllowBreak.Push(false); }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, InternalCompilerMessageCallback message, Options opts, FunctionInfo stats) { base.Optimize(ref _this, owner, message, opts, stats); if (message != null) { var fc = _left as Constant ?? _right as Constant; if (fc != null) { switch (fc.value._valueType) { case JSValueType.Undefined: message(MessageLevel.Warning, Position, Length, "To compare with undefined use '===' or '!==' instead of '==' or '!='."); break; case JSValueType.Object: if (fc.value._oValue == null) { message(MessageLevel.Warning, Position, Length, "To compare with null use '===' or '!==' instead of '==' or '!='."); } break; } } } }
public override bool Build(ref CodeNode _this, int expressionDepth, Dictionary <string, VariableDescriptor> variables, CodeContext codeContext, InternalCompilerMessageCallback message, FunctionInfo stats, Options opts) { stats.NeedDecompose = true; return(base.Build(ref _this, expressionDepth, variables, codeContext, message, stats, opts)); }
public override bool Build(ref CodeNode _this, int expressionDepth, Dictionary <string, VariableDescriptor> variables, CodeContext codeContext, InternalCompilerMessageCallback message, FunctionInfo stats, Options opts) { if (_body.built) { return(false); } if (stats != null) { stats.ContainsInnerEntities = true; } _codeContext = codeContext; if ((codeContext & CodeContext.InLoop) != 0 && message != null) { message(MessageLevel.Warning, Position, EndPosition - Position, Strings.FunctionInLoop); } /* * Если переменная за время построения функции получит хоть одну ссылку плюсом, * значит её следует пометить захваченной. Для этого необходимо запомнить количество * ссылок для всех пеменных */ var numbersOfReferences = new Dictionary <string, int>(); foreach (var variable in variables) { numbersOfReferences[variable.Key] = variable.Value.references.Count; } VariableDescriptor descriptorToRestore = null; if (!string.IsNullOrEmpty(_name)) { variables.TryGetValue(_name, out descriptorToRestore); variables[_name] = reference._descriptor; } _functionInfo.ContainsRestParameters = parameters.Length > 0 && parameters[parameters.Length - 1].IsRest; var bodyCode = _body as CodeNode; bodyCode.Build( ref bodyCode, 0, variables, codeContext & ~(CodeContext.Conditional | CodeContext.InExpression | CodeContext.InEval) | CodeContext.InFunction, message, _functionInfo, opts); _body = bodyCode as CodeBlock; if (message != null) { for (var i = parameters.Length; i-- > 0;) { if (parameters[i].ReferenceCount == 1) { message(MessageLevel.Recomendation, parameters[i].references[0].Position, 0, "Unused parameter \"" + parameters[i].name + "\""); } else { break; } } } _body._suppressScopeIsolation = SuppressScopeIsolationMode.Suppress; checkUsings(); if (stats != null) { stats.ContainsDebugger |= _functionInfo.ContainsDebugger; stats.ContainsEval |= _functionInfo.ContainsEval; stats.ContainsInnerEntities = true; stats.ContainsTry |= _functionInfo.ContainsTry; stats.ContainsWith |= _functionInfo.ContainsWith; stats.NeedDecompose |= _functionInfo.NeedDecompose; stats.UseCall |= _functionInfo.UseCall; stats.UseGetMember |= _functionInfo.UseGetMember; stats.ContainsThis |= _functionInfo.ContainsThis; } if (descriptorToRestore != null) { variables[descriptorToRestore.name] = descriptorToRestore; } else if (!string.IsNullOrEmpty(_name)) { variables.Remove(_name); } foreach (var variable in variables) { int count = 0; if (!numbersOfReferences.TryGetValue(variable.Key, out count) || count != variable.Value.references.Count) { variable.Value.captured = true; if ((codeContext & CodeContext.InWith) != 0) { for (var i = count; i < variable.Value.references.Count; i++) { variable.Value.references[i].ScopeLevel = -System.Math.Abs(variable.Value.references[i].ScopeLevel); } } } } return(false); }
public override bool Build(ref CodeNode _this, int expressionDepth, Dictionary <string, VariableDescriptor> variables, CodeContext codeContext, InternalCompilerMessageCallback message, FunctionInfo stats, Options opts) { Parser.Build(ref _variable, 2, variables, codeContext | CodeContext.InExpression, message, stats, opts); Parser.Build(ref _source, 2, variables, codeContext | CodeContext.InExpression, message, stats, opts); Parser.Build(ref _body, System.Math.Max(1, expressionDepth), variables, codeContext | CodeContext.Conditional | CodeContext.InLoop, message, stats, opts); if (_variable is Comma) { if ((_variable as Comma).RightOperand != null) { throw new InvalidOperationException("Invalid left-hand side in for-of"); } _variable = (_variable as Comma).LeftOperand; } if (message != null && (_source is ObjectDefinition || _source is ArrayDefinition || _source is Constant)) { message(MessageLevel.Recomendation, Position, Length, "for-of with constant source. This solution has a performance penalty. Rewrite without using for..in."); } return(false); }