internal static int LoadFunction(Script script, SourceCode source, ByteCode bytecode, bool usesGlobalEnv) { ScriptLoadingContext lcontext = CreateLoadingContext(script, source); try { FunctionDefinitionExpression fnx; using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.AstCreation)) fnx = new FunctionDefinitionExpression(lcontext, usesGlobalEnv); int beginIp = -1; //var srcref = new SourceRef(source.SourceID); using (script.PerformanceStats.StartStopwatch(Diagnostics.PerformanceCounter.Compilation)) using (bytecode.EnterSource(null)) { bytecode.Emit_Nop(string.Format("Begin function {0}", source.Name)); beginIp = fnx.CompileBody(bytecode, source.Name); bytecode.Emit_Nop(string.Format("End function {0}", source.Name)); } //Debug_DumpByteCode(bytecode, source.SourceID); return beginIp; } catch (SyntaxErrorException ex) { ex.DecorateMessage(script); throw; } }
public FunctionDefinitionStatement(ScriptLoadingContext lcontext, bool local, Token localToken) : base(lcontext) { // here lexer must be at the 'function' keyword Token funcKeyword = CheckTokenType(lcontext, TokenType.Function); funcKeyword = localToken ?? funcKeyword; // for debugger purposes m_Local = local; if (m_Local) { Token name = CheckTokenType(lcontext, TokenType.Name); m_FuncSymbol = lcontext.Scope.TryDefineLocal(name.Text); m_FriendlyName = string.Format("{0} (local)", name.Text); m_SourceRef = funcKeyword.GetSourceRef(name); } else { Token name = CheckTokenType(lcontext, TokenType.Name); string firstName = name.Text; m_SourceRef = funcKeyword.GetSourceRef(name); m_FuncSymbol = lcontext.Scope.Find(firstName); m_FriendlyName = firstName; if (lcontext.Lexer.Current.Type != TokenType.Brk_Open_Round) { m_TableAccessors = new List<string>(); while (lcontext.Lexer.Current.Type != TokenType.Brk_Open_Round) { Token separator = lcontext.Lexer.Current; if (separator.Type != TokenType.Colon && separator.Type != TokenType.Dot) UnexpectedTokenType(separator); lcontext.Lexer.Next(); Token field = CheckTokenType(lcontext, TokenType.Name); m_FriendlyName += separator.Text + field.Text; m_SourceRef = funcKeyword.GetSourceRef(field); if (separator.Type == TokenType.Colon) { m_MethodName = field.Text; m_IsMethodCallingConvention = true; break; } else { m_TableAccessors.Add(field.Text); } } if (m_MethodName == null && m_TableAccessors.Count > 0) { m_MethodName = m_TableAccessors[m_TableAccessors.Count - 1]; m_TableAccessors.RemoveAt(m_TableAccessors.Count - 1); } } } m_FuncDef = new FunctionDefinitionExpression(lcontext, m_IsMethodCallingConvention, false); lcontext.Source.Refs.Add(m_SourceRef); }