public MethodInfo BuildFunction(BoundFunction function, string sourceCode) { var method = DeclareFunction(function, _scriptBuilder, sourceCode); _scriptBuilder.Commit(); return method.Method; }
public static BoundFunction Perform(BoundFunction node) { return node.Update( node.Name, node.Parameters, Perform(node.Body), node.Location ); }
public static void Perform(BoundFunction node) { Perform(node.Body, null); }
private IFunctionBuilder DeclareFunction(BoundFunction function, ITypeBuilder typeBuilder, string sourceCode) { var method = typeBuilder.CreateFunction(typeof(JsFunction), function.Name, sourceCode); var argumentsReferenced = (function.Body.Flags & BoundBodyFlags.ArgumentsReferenced) != 0; BoundClosureField argumentsClosureField = null; var il = method.GetILBuilder(); if (argumentsReferenced && function.Body.Closure != null) function.Body.Closure.Fields.TryGetValue(BoundClosure.ArgumentsFieldName, out argumentsClosureField); _scope = new Scope( this, il, true, function.Body, argumentsClosureField, typeBuilder, _scope ); _scope.EmitLocals(function.Body.TypeManager); // Instantiate the closure if we own it. if (function.Body.Closure != null) EmitClosureSetup(function.Body); EmitInitializeArguments(function.Body); // Build the arguments object when we need it. if (argumentsReferenced) { // Initialize the arguments array. _scope.ArgumentsEmitter.EmitSetValue(new BoundEmitExpression( BoundValueType.Object, () => { _scope.EmitLoad(SpecialLocal.Runtime); _scope.EmitLoad(SpecialLocal.Callee); _scope.EmitLoad(SpecialLocal.ArgumentsRaw); IL.EmitCall(_runtimeCreateArguments); } )); } // Emit the body. EmitStatements(function.Body.Body); // Ensure that we return something. EmitReturn(new BoundReturn(null, SourceLocation.Missing)); // Emit the exceptional return block if we need it. EmitExceptionalReturn(); // Put a debug location at the end of the function. if (function.Location != null) { IL.MarkSequencePoint(new SourceLocation( function.Location.EndOffset, function.Location.EndLine, function.Location.EndColumn, function.Location.EndOffset + 1, function.Location.EndLine, function.Location.EndColumn + 1, null )); } _scope = _scope.Parent; return method; }