internal override System.Linq.Expressions.Expression TryCompile(bool selfCompile, bool forAssign, Type expectedType, List <CodeNode> dynamicValues) { dynamicValues.Add(this); var res = System.Linq.Expressions.Expression.Call( System.Linq.Expressions.Expression.ArrayAccess(JITHelpers.DynamicValuesParameter, JITHelpers.cnst(dynamicValues.Count - 1)), forAssign ? JITHelpers.EvaluateForWriteMethod : JITHelpers.EvaluateMethod, JITHelpers.ContextParameter ); if (expectedType == typeof(int)) { res = System.Linq.Expressions.Expression.Call(JITHelpers.JSObjectToInt32Method, res); } return(res); }
public override bool Build(ref CodeNode _this, int expressionDepth, Dictionary <string, VariableDescriptor> variables, CodeContext codeContext, InternalCompilerMessageCallback message, FunctionInfo stats, Options opts) { if (built) { return(false); } built = true; List <VariableDescriptor> variablesToRestore = null; if (_variables != null && _variables.Length != 0) { for (var i = 0; i < _variables.Length; i++) { VariableDescriptor desc = null; if (variables.TryGetValue(_variables[i].name, out desc) && desc.definitionScopeLevel < _variables[i].definitionScopeLevel) { if (variablesToRestore == null) { variablesToRestore = new List <VariableDescriptor>(); } variablesToRestore.Add(desc); } variables[_variables[i].name] = _variables[i]; _variables[i].owner = this; } for (var i = 0; i < _variables.Length; i++) { Parser.Build( ref _variables[i].initializer, System.Math.Max(2, expressionDepth), variables, codeContext | (this._strict ? CodeContext.Strict : CodeContext.None), message, stats, opts); } } for (var i = 0; i < _lines.Length; i++) { var ed = _lines[i] as EntityDefinition; if (ed != null && ed.Hoist) { _lines[i] = null; } } bool unreachable = false; for (int i = 0; i < _lines.Length; i++) { if (_lines[i] != null) { if (_lines[i] is Empty) { _lines[i] = null; } else { if (unreachable && message != null) { message(MessageLevel.CriticalWarning, _lines[i].Position, _lines[i].Length, "Unreachable code detected."); } var cn = _lines[i]; Parser.Build(ref cn, (codeContext & CodeContext.InEval) != 0 ? 2 : System.Math.Max(1, expressionDepth), variables, codeContext | (this._strict ? CodeContext.Strict : CodeContext.None), message, stats, opts); if (cn is Empty) { _lines[i] = null; } else { _lines[i] = cn; } unreachable |= cn is Return || cn is Break || cn is Continue || cn is Throw; } } } int f = _lines.Length, t = _lines.Length - 1; for (; f-- > 0;) { if (_lines[f] != null && _lines[t] == null) { _lines[t] = _lines[f]; _lines[f] = null; } if (_lines[t] != null) { t--; } } if (expressionDepth > 0 && (_variables == null || _variables.Length == 0)) { if (_lines.Length == 0) { _this = Empty.Instance; } } else { if (message != null) { for (var i = 0; i < _variables.Length; i++) { if (_variables[i].ReferenceCount == 1) { message( MessageLevel.Recomendation, _variables[i].references[0].Position, 0, "Unused variable \"" + _variables[i].name + "\""); } else { break; } } } #if (NET40 || INLINE) && JIT compiledVersion = JITHelpers.compile(this, depth >= 0); #endif } if (t >= 0 && this == _this) { var newBody = new CodeNode[_lines.Length - t - 1]; f = 0; while (++t < _lines.Length) { newBody[f++] = _lines[t]; } _lines = newBody; } if (_variables != null && _variables.Length != 0) { for (var i = 0; i < _variables.Length; i++) { variables.Remove(_variables[i].name); } } if (variablesToRestore != null) { for (var i = 0; i < variablesToRestore.Count; i++) { variables[variablesToRestore[i].name] = variablesToRestore[i]; } } return(false); }