private void expressionWillThrow(CompilerMessageCallback message) { if (message != null && !(this is RegExpExpression)) { message(MessageLevel.Warning, new CodeCoordinates(0, Position, Length), "Expression will throw an exception"); } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, CompilerMessageCallback 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); } } } }
/// <summary> /// Initializes a new Module with specified code, callback for output compiler messages and compiler options. /// </summary> /// <param name="path">Path to file with script. Used for resolving paths to other modules for importing via import directive. Can be null or empty</param> /// <param name="code">JavaScript code.</param> /// <param name="messageCallback">Callback used to output compiler messages or null</param> /// <param name="options">Compiler options</param> public Module(string path, string code, CompilerMessageCallback messageCallback, Options options) { if (code == null) { throw new ArgumentNullException(); } Code = code; Context = new Context(Context.CurrentGlobalContext, true, null); Context._module = this; if (!string.IsNullOrWhiteSpace(path)) { lock (__modulesCache) { if (!__modulesCache.ContainsKey(path)) { __modulesCache[path] = this; } } FilePath = path; } if (code == "") { return; } var internalCallback = messageCallback != null ? (level, cord, message) => messageCallback(level, CodeCoordinates.FromTextPosition(code, cord.Column, cord.Length), message) : null as CompilerMessageCallback; int i = 0; _root = (CodeBlock)CodeBlock.Parse(new ParseInfo(Tools.removeComments(code, 0), Code, internalCallback), ref i); var stat = new FunctionInfo(); Parser.Build(ref _root, 0, new Dictionary <string, VariableDescriptor>(), CodeContext.None, internalCallback, stat, options); var body = _root as CodeBlock; body._suppressScopeIsolation = SuppressScopeIsolationMode.Suppress; Context._thisBind = new GlobalObject(Context); Context._strict = body._strict; var tv = stat.WithLexicalEnvironment ? null : new Dictionary <string, VariableDescriptor>(); body.RebuildScope(stat, tv, body._variables.Length == 0 || !stat.WithLexicalEnvironment ? 1 : 0); var bd = body as CodeNode; body.Optimize(ref bd, null, internalCallback, options, stat); if (tv != null) { body._variables = new List <VariableDescriptor>(tv.Values).ToArray(); } if (stat.NeedDecompose) { body.Decompose(ref bd); } }
internal void baseOptimize(ref CodeNode _this, FunctionDefinition owner, CompilerMessageCallback 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, CompilerMessageCallback 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; } } } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, CompilerMessageCallback 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, new CodeCoordinates(0, parameters[i].references[0].Position, 0), "Type of return value is ambiguous"); } break; } } } else { _functionInfo.ResultType = PredictedType.Undefined; } }
internal void Optimize(ref CodeBlock self, FunctionDefinition owner, CompilerMessageCallback message, Options opts, FunctionInfo stats) { CodeNode cn = self; Optimize(ref cn, owner, message, opts, stats); self = (CodeBlock)cn; }
/// <summary> /// Инициализирует объект типа Script и преобрзует код сценария во внутреннее представление. /// </summary> /// <param name="code">Код скрипта на языке JavaScript.</param> /// <param name="parentContext">Родительский контекст для контекста выполнения сценария.</param> /// <param name="messageCallback">Делегат обратного вызова, используемый для вывода сообщений компилятора</param> public Script(string code, Context parentContext, CompilerMessageCallback messageCallback, Options options) { if (code == null) throw new ArgumentNullException(); Code = code; int i = 0; root = CodeBlock.Parse(new ParsingState(Tools.RemoveComments(code, 0), Code, messageCallback), ref i).Statement; if (i < code.Length) throw new System.ArgumentException("Invalid char"); CompilerMessageCallback icallback = messageCallback != null ? (level, cord, message) => { messageCallback(level, CodeCoordinates.FromTextPosition(code, cord.Column, cord.Length), message); } : null as CompilerMessageCallback; var stat = new FunctionStatistics(); Parser.Build(ref root, 0, new System.Collections.Generic.Dictionary<string, VariableDescriptor>(), _BuildState.None, icallback, stat, options); var body = root as CodeBlock; Context = new Context(parentContext ?? NiL.JS.Core.Context.globalContext, true, pseudoCaller); Context.thisBind = new GlobalObject(Context); Context.variables = (root as CodeBlock).variables; Context.strict = (root as CodeBlock).strict; for (i = body.localVariables.Length; i-- > 0; ) { var f = Context.DefineVariable(body.localVariables[i].name); body.localVariables[i].cacheRes = f; body.localVariables[i].cacheContext = Context; if (body.localVariables[i].Inititalizator != null) f.Assign(body.localVariables[i].Inititalizator.Evaluate(Context)); if (body.localVariables[i].isReadOnly) body.localVariables[i].cacheRes.attributes |= JSObjectAttributesInternal.ReadOnly; body.localVariables[i].captured |= stat.ContainsEval; } var bd = body as CodeNode; body.Optimize(ref bd, null, icallback, options, stat); }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, CompilerMessageCallback 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, CompilerMessageCallback message, Options opts, FunctionInfo stats) { for (int i = 0; i < _initializers.Length; i++) { _initializers[i].Optimize(ref _initializers[i], owner, message, opts, stats); } }
/// <summary> /// Initializes a new Module with specified code, callback for output compiler messages and compiler options. /// </summary> /// <param name="virtualPath">Path to file with script. Used for resolving paths to other modules for importing via import directive. Can be null or empty</param> /// <param name="code">JavaScript code.</param> /// <param name="messageCallback">Callback used to output compiler messages or null</param> /// <param name="options">Compiler options</param> public Module(string virtualPath, string code, CompilerMessageCallback messageCallback, Options options) { if (code == null) { throw new ArgumentNullException(); } if (!string.IsNullOrWhiteSpace(virtualPath)) { lock (_modulesCache) { if (!_modulesCache.ContainsKey(virtualPath)) { _modulesCache[virtualPath] = this; } } FilePath = virtualPath; } Context = new Context(Context.CurrentGlobalContext, true, null); Context._module = this; Context._thisBind = new GlobalObject(Context); Script = Script.Parse(code, messageCallback, options); Context._strict = Script.Root._strict; }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, CompilerMessageCallback 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, CompilerMessageCallback message, Options opts, FunctionInfo stats) { _variable.Optimize(ref _variable, owner, message, opts, stats); _source.Optimize(ref _source, owner, message, opts, stats); if (_body != null) { _body.Optimize(ref _body, owner, message, opts, stats); } }
public static Script Parse(string code, CompilerMessageCallback messageCallback = null, Options options = Options.None) { if (code == null) { throw new ArgumentNullException(); } if (code == "") { return(new Script { Root = new CodeBlock(new CodeNode[0]), Code = "" }); } var internalCallback = messageCallback != null ? (level, position, length, message) => messageCallback(level, CodeCoordinates.FromTextPosition(code, position, length), message) : null as InternalCompilerMessageCallback; int i = 0; var root = (CodeBlock)CodeBlock.Parse(new ParseInfo(Parser.RemoveComments(code, 0), code, internalCallback), ref i); var stat = new FunctionInfo(); Parser.Build(ref root, 0, new Dictionary <string, VariableDescriptor>(), CodeContext.None, internalCallback, stat, options); var body = root as CodeBlock; body._suppressScopeIsolation = SuppressScopeIsolationMode.Suppress; for (var vi = 0; vi < body._variables.Length; vi++) { body._variables[vi].captured = true; } var tv = stat.WithLexicalEnvironment ? null : new Dictionary <string, VariableDescriptor>(); body.RebuildScope(stat, tv, body._variables.Length == 0 || !stat.WithLexicalEnvironment ? 1 : 0); var bd = body as CodeNode; body.Optimize(ref bd, null, internalCallback, options, stat); if (tv != null) { body._variables = new List <VariableDescriptor>(tv.Values).ToArray(); } if (stat.NeedDecompose) { body.Decompose(ref bd); } return(new Script() { Code = code, Root = root }); }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, CompilerMessageCallback 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, CompilerMessageCallback 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); return; } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, CompilerMessageCallback message, Options opts, FunctionInfo stats) { baseOptimize(ref _this, owner, message, opts, stats); if (_this == this) { if (_left.ResultType == PredictedType.Number && _right.ResultType == PredictedType.Number) { _this = new NumberLessOrEqual(_left, _right); return; } } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, CompilerMessageCallback 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, CompilerMessageCallback 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); } for (var i = 0; i < computedProperties.Length; i++) { computedProperties[i]._name.Optimize(ref computedProperties[i]._name, owner, message, opts, stats); computedProperties[i]._value.Optimize(ref computedProperties[i]._value, owner, message, opts, stats); } }
/// <summary> /// Initializes a new Module with specified code, callback for output compiler messages and compiler options. /// </summary> /// <param name="virtualPath">Path to file with script. Used for resolving paths to other modules for importing via import directive. Can be null or empty</param> /// <param name="code">JavaScript code.</param> /// <param name="messageCallback">Callback used to output compiler messages or null</param> /// <param name="options">Compiler options</param> public Module(string virtualPath, string code, CompilerMessageCallback messageCallback, Options options) { if (code == null) { throw new ArgumentNullException(); } Context = new Context(Context.CurrentGlobalContext, true, null); Context._module = this; Context._thisBind = new GlobalObject(Context); Script = Script.Parse(code, messageCallback, options); Context._strict = Script.Root._strict; }
public ParseInfo(string code, string sourceCode, CompilerMessageCallback 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, CompilerMessageCallback message, Options opts, FunctionInfo stats) { if (_scope != null) { _scope.Optimize(ref _scope, owner, message, opts, stats); } if (_body != null) { _body.Optimize(ref _body, owner, message, opts, stats); } if (_body == null) { _this = _scope; } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, CompilerMessageCallback 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, new CodeCoordinates(0, Position, Length), "Type of an expression is ambiguous"); } }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, CompilerMessageCallback 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 override void Optimize(ref CodeNode _this, FunctionDefinition owner, CompilerMessageCallback 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, CompilerMessageCallback 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, 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 ParsingState(string code, string sourceCode, CompilerMessageCallback message) { Code = code; SourceCode = sourceCode; Labels = new List<string>(); strict = new Stack<bool>(); strict.Push(false); AllowDirectives = true; containsWith = new Stack<bool>(); containsWith.Push(false); AllowBreak = new Stack<bool>(); AllowBreak.Push(false); AllowContinue = new Stack<bool>(); AllowContinue.Push(false); AllowYield = new Stack<bool>(); AllowYield.Push(false); this.message = message; stringConstants = new Dictionary<string, JSObject>(); intConstants = new Dictionary<int, JSObject>(); doubleConstants = new Dictionary<double, JSObject>(); }
public override void Optimize(ref CodeNode _this, FunctionDefinition owner, CompilerMessageCallback 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, new CodeCoordinates(0, Position, Length), "To compare with undefined use '===' or '!==' instead of '==' or '!='."); break; case JSValueType.Object: if (fc.value._oValue == null) { message(MessageLevel.Warning, new CodeCoordinates(0, Position, Length), "To compare with null use '===' or '!==' instead of '==' or '!='."); } break; } } } }
/// <summary> /// Инициализирует объект типа Script и преобрзует код сценария во внутреннее представление. /// </summary> /// <param name="code">Код скрипта на языке JavaScript.</param> /// <param name="messageCallback">Делегат обратного вызова, используемый для вывода сообщений компилятора</param> public Script(string code, CompilerMessageCallback messageCallback) : this(code, null, messageCallback, Options.Default) { }
/// <summary> /// Initializes a new Module with specified code, callback for output compiler messages and compiler options. /// </summary> /// <param name="code">JavaScript code.</param> /// <param name="messageCallback">Callback used to output compiler messages or null</param> /// <param name="options">Compiler options</param> public Module(string code, CompilerMessageCallback messageCallback, Options options) : this(null, code, messageCallback, options) { }
/// <summary> /// Initializes a new Module with specified code and callback for output compiler messages. /// </summary> /// <param name="path">Path to file with script. Used for resolving paths to other modules for importing via import directive. Can be null or empty</param> /// <param name="code">JavaScript code.</param> /// <param name="messageCallback">Callback used to output compiler messages</param> public Module(string path, string code, CompilerMessageCallback messageCallback) : this(path, code, messageCallback, Options.None) { }
public override void Optimize(ref CodeNode _this, Expressions.FunctionDefinition owner, CompilerMessageCallback message, Options opts, FunctionInfo stats) { original.Optimize(ref _this, owner, message, opts, stats); }
public override bool Build(ref CodeNode _this, int expressionDepth, Dictionary <string, VariableDescriptor> variables, CodeContext codeContext, CompilerMessageCallback message, FunctionInfo stats, Options opts) { return(original.Build(ref _this, expressionDepth, variables, codeContext, message, stats, opts)); }
internal override bool Build(ref CodeNode _this, int depth, Dictionary<string, VariableDescriptor> variables, _BuildState state, CompilerMessageCallback message, FunctionStatistics statistic, Options opts) { depth = System.Math.Max(1, depth); Parser.Build(ref body, depth, variables, state | _BuildState.InLoop, message, statistic, opts); Parser.Build(ref condition, 2, variables, state | _BuildState.InLoop, message, statistic, opts); try { if (allowRemove && (opts & Options.SuppressUselessExpressionsElimination) == 0 && (condition is Constant || (condition as Expressions.Expression).IsContextIndependent)) { if ((bool)condition.Evaluate(null)) _this = new InfinityLoop(body, labels); else if (labels.Length == 0) _this = body; condition.Eliminated = true; } } #if PORTABLE catch {
internal override void Optimize(ref CodeNode _this, FunctionExpression owner, CompilerMessageCallback message, Options opts, FunctionStatistics statistic) { // do nothing }
internal override bool Build(ref CodeNode _this, int depth, System.Collections.Generic.Dictionary<string, VariableDescriptor> variables, _BuildState state, CompilerMessageCallback message, FunctionStatistics statistic, Options opts) { return false; }
internal override bool Build(ref CodeNode _this, int depth, Dictionary<string, VariableDescriptor> variables, _BuildState state, CompilerMessageCallback message, FunctionStatistics statistic, Options opts) { depth = System.Math.Max(1, depth); Parser.Build(ref body, depth, variables, state | _BuildState.Conditional | _BuildState.InLoop, message, statistic, opts); Parser.Build(ref condition, 2, variables, state | _BuildState.InLoop, message, statistic, opts); if ((opts & Options.SuppressUselessExpressionsElimination) == 0 && condition is ToBool) { if (message == null) message(MessageLevel.Warning, new CodeCoordinates(0, condition.Position, 2), "Useless conversion. Remove double negation in condition"); condition = (condition as Expression).first; } try { if (allowRemove && (condition is Constant || (condition is Expression && (condition as Expression).IsContextIndependent))) { if ((bool)condition.Evaluate(null)) { if ((opts & Options.SuppressUselessExpressionsElimination) == 0) _this = new InfinityLoop(body, labels); } else if ((opts & Options.SuppressUselessStatementsElimination) == 0) { _this = null; Eliminated = true; body.Eliminated = true; } condition.Eliminated = true; } else if ((opts & Options.SuppressUselessExpressionsElimination) == 0 && ((condition is Json && (condition as Json).Fields.Length == 0) || (condition is ArrayExpression && (condition as ArrayExpression).Elements.Count == 0))) { _this = new InfinityLoop(body, labels); condition.Eliminated = true; } } #if PORTABLE catch {