//
-// CodeGenerator.cs: The actual IL code generator for JScript .Net programs.
+// CodeGenerator.cs
//
// Author:
// Cesar Lopez Nataren (cesar@ciencias.unam.mx)
//
-// (C) 2003, Cesar Lopez Nataren
+// (C) 2003, 2004 Cesar Lopez Nataren
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
+using System.IO;
using System.Reflection;
using System.Reflection.Emit;
-using System.Runtime.CompilerServices;
+using System.Threading;
using Microsoft.JScript.Vsa;
+using System.Runtime.CompilerServices;
-namespace Microsoft.JScript.Tmp {
-
- internal sealed class CodeGenerator {
-
- internal AssemblyName assemblyName;
- internal AssemblyBuilder assemblyBuilder;
- internal ModuleBuilder moduleBuilder;
- internal TypeBuilder typeBuilder;
- internal ILGenerator ilGen;
+namespace Microsoft.JScript {
- internal string MODULE_NAME = "JScript Module";
- internal string GLOBAL_SCOPE = "Microsoft.JScript.GlobalScope";
-
- internal CodeGenerator (string assemName, AssemblyBuilderAccess access)
- {
- assemblyName = new AssemblyName ();
- assemblyName.Name = assemName;
+ internal class EmitContext {
- AppDomain appDomain = AppDomain.CurrentDomain;
-
- this.assemblyBuilder = appDomain.DefineDynamicAssembly (assemblyName,
- access);
-
- this.moduleBuilder = assemblyBuilder.DefineDynamicModule (MODULE_NAME,
- assemblyName.Name + ".exe", false);
- }
+ internal TypeBuilder type_builder;
+ internal ILGenerator ig;
+ internal ModuleBuilder mod_builder;
+ internal Label LoopBegin, LoopEnd;
- internal void EmitJScript0Type ()
+ internal EmitContext (TypeBuilder type)
{
- this.typeBuilder = moduleBuilder.DefineType ("JScript 0",
- TypeAttributes.Class |
- TypeAttributes.Public);
-
- this.typeBuilder.SetParent (typeof (Microsoft.JScript.GlobalScope));
-
- CustomAttributeBuilder attr;
- Type t = typeof (CompilerGlobalScopeAttribute);
- attr = new CustomAttributeBuilder (t.GetConstructor (new Type [] {}),
- new object [] {});
- this.typeBuilder.SetCustomAttribute (attr);
+ type_builder = type;
+
+ if (type_builder != null) {
+ MethodBuilder global_code = type_builder.DefineMethod (
+ "Global Code",
+ MethodAttributes.Public,
+ typeof (System.Object),
+ new Type [] {});
+ ig = global_code.GetILGenerator ();
+ }
}
-
- internal void EmitJScript0Cons ()
+ internal EmitContext (TypeBuilder type_builder, ModuleBuilder mod_builder, ILGenerator ig)
{
- ConstructorBuilder consBuilder;
-
- consBuilder = typeBuilder.DefineConstructor (MethodAttributes.Public,
- CallingConventions.Standard,
- new Type [] {typeof (Microsoft.JScript.GlobalScope)});
-
- this.ilGen = consBuilder.GetILGenerator ();
-
- this.ilGen.Emit (OpCodes.Ldarg_0);
- this.ilGen.Emit (OpCodes.Ldarg_1);
- this.ilGen.Emit (OpCodes.Dup);
- this.ilGen.Emit (OpCodes.Ldfld,
- typeof (Microsoft.JScript.ScriptObject).GetField ("engine"));
- this.ilGen.Emit (OpCodes.Call,
- typeof (Microsoft.JScript.GlobalScope).GetConstructor (new Type [] {typeof (Microsoft.JScript.GlobalScope), typeof (Microsoft.JScript.Vsa.VsaEngine)}));
- this.ilGen.Emit (OpCodes.Ret);
+ this.type_builder = type_builder;
+ this.mod_builder = mod_builder;
+ this.ig = ig;
}
+ }
+ public class CodeGenerator {
- private void EmitJScript0GlobalCode (ASTList program)
- {
- MethodBuilder methodBuilder;
- methodBuilder = this.typeBuilder.DefineMethod ("Global Code",
- MethodAttributes.Public,
- typeof (object),
- null);
-
- this.ilGen = methodBuilder.GetILGenerator ();
-
- this.ilGen.Emit (OpCodes.Ldarg_0);
-
- this.ilGen.Emit (OpCodes.Ldfld,
- typeof (Microsoft.JScript.ScriptObject).GetField ("engine"));
-
- this.ilGen.Emit (OpCodes.Ldarg_0);
-
- this.ilGen.Emit (OpCodes.Call,
- typeof (Microsoft.JScript.Vsa.VsaEngine).GetMethod ("PushScriptObject", new Type [] {typeof (Microsoft.JScript.ScriptObject)}));
-
-
- // program.Visit (this, null);
-
-
- this.ilGen.Emit (OpCodes.Ldsfld,
- typeof (Microsoft.JScript.Empty).GetField ("Value"));
-
- this.ilGen.Emit (OpCodes.Ldarg_0);
-
- this.ilGen.Emit (OpCodes.Ldfld,
- typeof (Microsoft.JScript.ScriptObject).GetField ("engine"));
-
- this.ilGen.Emit (OpCodes.Call,
- typeof (Microsoft.JScript.Vsa.VsaEngine).GetMethod ("PopScriptObject"));
-
- this.ilGen.Emit (OpCodes.Pop);
- this.ilGen.Emit (OpCodes.Ret);
- }
-
+ private static string MODULE = "JScript Module";
+ internal static string mod_name;
+ internal static AppDomain app_domain;
+ internal static AssemblyName assembly_name;
+ internal static AssemblyBuilder assembly_builder;
+ internal static ModuleBuilder module_builder;
-
- public void EmitJScript0 (ASTList program)
+ internal static string Basename (string name)
{
- this.EmitJScript0Type ();
- this.EmitJScript0Cons ();
- this.EmitJScript0GlobalCode (program);
-
- this.typeBuilder.CreateType ();
- }
-
-
- //
- // JScript Main class construction
- //
-
- private void EmitJScriptMainType ()
- {
- this.typeBuilder = moduleBuilder.DefineType ("JScript Main",
- TypeAttributes.Public);
-
- this.typeBuilder.SetParent (typeof (System.Object));
- }
-
-
- private void EmitJScriptMainCons ()
- {
- ConstructorBuilder consBuilder;
- consBuilder = typeBuilder.DefineConstructor (MethodAttributes.Public,
- CallingConventions.Standard,
- new Type [] {});
-
- this.ilGen = consBuilder.GetILGenerator ();
- this.ilGen.Emit (OpCodes.Ldarg_0);
- this.ilGen.Emit (OpCodes.Call,
- typeof (Object).GetConstructor (new Type [] {}));
- this.ilGen.Emit (OpCodes.Ret);
- }
-
+ int pos = name.LastIndexOf ('/');
- private void EmitJScriptMainFunction ()
- {
- MethodBuilder methodBuilder;
- methodBuilder = typeBuilder.DefineMethod ("Main",
- MethodAttributes.Public |
- MethodAttributes.Static,
- typeof (void),
- new Type [] {typeof (String [])});
-
- methodBuilder.SetCustomAttribute (new CustomAttributeBuilder
- (typeof (STAThreadAttribute).GetConstructor (new Type [] {}),
- new object [] {}));
+ if (pos != -1)
+ return name.Substring (pos + 1);
+ pos = name.LastIndexOf ('\\');
+ if (pos != -1)
+ return name.Substring (pos + 1);
- this.ilGen = methodBuilder.GetILGenerator ();
-
- // declare local vars
- this.ilGen.DeclareLocal (typeof (Microsoft.JScript.GlobalScope));
-
- this.ilGen.Emit (OpCodes.Ldc_I4_1);
- this.ilGen.Emit (OpCodes.Ldc_I4_1);
- this.ilGen.Emit (OpCodes.Newarr, typeof (string));
- this.ilGen.Emit (OpCodes.Dup);
- this.ilGen.Emit (OpCodes.Ldc_I4_0);
- this.ilGen.Emit (OpCodes.Ldstr,
- "mscorlib, Version=1.0.3300.0, Culture=neutral, Pub" + "licKeyToken=b77a5c561934e089");
- this.ilGen.Emit (OpCodes.Stelem_Ref);
- this.ilGen.Emit (OpCodes.Call,
- typeof (Microsoft.JScript.Vsa.VsaEngine).GetMethod ("CreateEngineAndGetGlobalScope", new Type [] {typeof (bool), typeof (string [])}));
-
- this.ilGen.Emit (OpCodes.Stloc_0);
- this.ilGen.Emit (OpCodes.Ldloc_0);
-
-
- this.ilGen.Emit (OpCodes.Newobj,
- assemblyBuilder.GetType ("JScript 0").GetConstructor (new Type [] {typeof (Microsoft.JScript.GlobalScope)}));
-
- this.ilGen.Emit (OpCodes.Call, assemblyBuilder.GetType ("JScript 0").GetMethod ("Global Code", new Type [] {}));
-
- this.ilGen.Emit (OpCodes.Pop);
- this.ilGen.Emit (OpCodes.Ret);
-
- this.assemblyBuilder.SetEntryPoint (methodBuilder);
-
- }
-
- public void EmitJScriptMain ()
- {
- this.EmitJScriptMainType ();
- this.EmitJScriptMainCons ();
- this.EmitJScriptMainFunction ();
-
- Type t2 = this.typeBuilder.CreateType ();
- }
+ return name;
+ }
+ internal static string Dirname (string name)
+ {
+ int pos = name.LastIndexOf ('/');
+ if (pos != -1)
+ return name.Substring (0, pos);
+ pos = name.LastIndexOf ('\\');
+ if (pos != -1)
+ return name.Substring (0, pos);
- //
- // Visitor methods, that Emit IL OpCodes for each type of
- // language constructs.
- //
+ return ".";
+ }
- public object VisitASTList (ASTList prog, object obj)
+ internal static void Init (string file_name)
{
- int size = prog.elems.Count;
+ app_domain = Thread.GetDomain ();
+
+ assembly_name = new AssemblyName ();
+ assembly_name.Name = Path.GetFileNameWithoutExtension (file_name);
+ mod_name = MODULE;
+
+ assembly_builder = app_domain.DefineDynamicAssembly (
+ assembly_name,
+ AssemblyBuilderAccess.RunAndSave,
+ Dirname (file_name));
+
+ ConstructorInfo ctr_info = typeof (Microsoft.JScript.ReferenceAttribute).GetConstructor (new Type [] { typeof (string) });
+ // FIXME: find out which is the blob.
+ byte [] blob = new byte [] {};
+ assembly_builder.SetCustomAttribute (ctr_info, blob);
+
+ module_builder = assembly_builder.DefineDynamicModule (
+ mod_name,
+ Basename (assembly_name.Name + ".exe"),
+ false);
+ }
- // for (int i = 0; i < size; i++)
- // ((AST) prog.elems [i]).Visit (this, obj);
+ internal static string trim_extension (string file_name)
+ {
+ int index = file_name.LastIndexOf ('.');
- return null;
+ if (index < 0)
+ return file_name;
+ else
+ return file_name.Substring (0, index);
}
-
- public object VisitVariableDeclaration (VariableDeclaration decl,
- object args)
+ internal static void Save (string target_name)
{
- throw new NotImplementedException ();
+ assembly_builder.Save (CodeGenerator.Basename (target_name));
}
-
- public object VisitFunctionDeclaration (FunctionDeclaration decl,
- object args)
+ internal static void Emit (AST prog)
{
- throw new NotImplementedException ();
+ if (prog == null)
+ return;
+
+ TypeBuilder type_builder;
+ type_builder = module_builder.DefineType ("JScript 0", TypeAttributes.Public);
+
+ type_builder.SetParent (typeof (GlobalScope));
+ type_builder.SetCustomAttribute (new CustomAttributeBuilder
+ (typeof (CompilerGlobalScopeAttribute).GetConstructor (new Type [] {}), new object [] {}));
+
+ EmitContext ec = new EmitContext (type_builder);
+ ec.mod_builder = module_builder;
+ ILGenerator global_code = ec.ig;
+
+ emit_default_script_constructor (ec);
+ emit_default_init_global_code (global_code);
+ prog.Emit (ec);
+ emit_default_end_global_code (global_code);
+ ec.type_builder.CreateType ();
+
+ //
+ // Build the default 'JScript Main' class
+ //
+ ec.type_builder = module_builder.DefineType ("JScript Main");
+ emit_jscript_main (ec.type_builder);
+ ec.type_builder.CreateType ();
}
-
- public object VisitBlock (Block b, object args)
+ internal static void emit_default_init_global_code (ILGenerator ig)
{
- throw new NotImplementedException ();
+ ig.Emit (OpCodes.Ldarg_0);
+ ig.Emit (OpCodes.Ldfld, typeof (ScriptObject).GetField ("engine"));
+ ig.Emit (OpCodes.Ldarg_0);
+ ig.Emit (OpCodes.Call,
+ typeof (VsaEngine).GetMethod ("PushScriptObject",
+ new Type [] { typeof (ScriptObject)}));
}
-
- public object VisitEval (Eval e, object args)
- {
- throw new NotImplementedException ();
+ internal static void emit_default_end_global_code (ILGenerator ig)
+ {
+ ig.Emit (OpCodes.Ldnull);
+ ig.Emit (OpCodes.Ldarg_0);
+ ig.Emit (OpCodes.Ldfld, typeof (ScriptObject).GetField ("engine"));
+ ig.Emit (OpCodes.Call, typeof (VsaEngine).GetMethod ("PopScriptObject"));
+ ig.Emit (OpCodes.Pop);
+ ig.Emit (OpCodes.Ret);
}
-
- public object VisitForIn (ForIn forIn, object args)
+ internal static void emit_default_script_constructor (EmitContext ec)
{
- throw new NotImplementedException ();
+ ConstructorBuilder cons_builder;
+ TypeBuilder tb = ec.type_builder;
+ cons_builder = tb.DefineConstructor (MethodAttributes.Public,
+ CallingConventions.Standard,
+ new Type [] { typeof (GlobalScope) });
+
+ ILGenerator ig = cons_builder.GetILGenerator ();
+ ig.Emit (OpCodes.Ldarg_0);
+ ig.Emit (OpCodes.Ldarg_1);
+ ig.Emit (OpCodes.Dup);
+ ig.Emit (OpCodes.Ldfld,
+ typeof (ScriptObject).GetField ("engine"));
+
+ ig.Emit (OpCodes.Call,
+ typeof (GlobalScope).GetConstructor (new Type [] {typeof (GlobalScope),
+ typeof (VsaEngine)}));
+ ig.Emit (OpCodes.Ret);
}
-
- public object VisitFunctionExpression (FunctionExpression fexp,
- object args)
+ internal static void emit_jscript_main (TypeBuilder tb)
{
- throw new NotImplementedException ();
+ emit_jscript_main_constructor (tb);
+ emit_jscript_main_entry_point (tb);
}
-
- public object VisitImport (Import imp, object args)
+ internal static void emit_jscript_main_constructor (TypeBuilder tb)
{
- throw new NotImplementedException ();
+ ConstructorBuilder cons = tb.DefineConstructor (MethodAttributes.Public,
+ CallingConventions.Standard,
+ new Type [] {});
+ ILGenerator ig = cons.GetILGenerator ();
+ ig.Emit (OpCodes.Ldarg_0);
+ ig.Emit (OpCodes.Call, typeof (Object).GetConstructor (new Type [] {}));
+ ig.Emit (OpCodes.Ret);
}
-
- public object VisitPackage (Package pkg, object args)
+ internal static void emit_jscript_main_entry_point (TypeBuilder tb)
{
- throw new NotImplementedException ();
+ MethodBuilder method;
+ method = tb.DefineMethod ("Main",
+ MethodAttributes.Public | MethodAttributes.Static,
+ typeof (void), new Type [] {typeof (String [])});
+
+ method.SetCustomAttribute (new CustomAttributeBuilder
+ (typeof (STAThreadAttribute).GetConstructor (
+ new Type [] {}),
+ new object [] {}));
+
+ ILGenerator ig = method.GetILGenerator ();
+
+ ig.DeclareLocal (typeof (GlobalScope));
+
+ ig.Emit (OpCodes.Ldc_I4_1);
+ ig.Emit (OpCodes.Ldc_I4_1);
+ ig.Emit (OpCodes.Newarr, typeof (string));
+ ig.Emit (OpCodes.Dup);
+ ig.Emit (OpCodes.Ldc_I4_0);
+
+ ig.Emit (OpCodes.Ldstr,
+ "mscorlib, Version=1.0.3300.0, Culture=neutral, Pub" +
+ "licKeyToken=b77a5c561934e089");
+
+ ig.Emit (OpCodes.Stelem_Ref);
+
+ ig.Emit (OpCodes.Call,
+ typeof (VsaEngine).GetMethod ("CreateEngineAndGetGlobalScope",
+ new Type [] {typeof (bool),
+ typeof (string [])}));
+ ig.Emit (OpCodes.Stloc_0);
+ ig.Emit (OpCodes.Ldloc_0);
+
+ ig.Emit (OpCodes.Newobj,
+ assembly_builder.GetType ("JScript 0").GetConstructor (
+ new Type [] {typeof (GlobalScope)}));
+ ig.Emit (OpCodes.Call,
+ assembly_builder.GetType ("JScript 0").GetMethod (
+ "Global Code", new Type [] {}));
+ ig.Emit (OpCodes.Pop);
+ ig.Emit (OpCodes.Ret);
+
+ assembly_builder.SetEntryPoint (method);
}
-
- public object VisitScriptBlock (ScriptBlock sblock, object args)
+ public static void Run (string file_name, AST prog)
{
- throw new NotImplementedException ();
+ CodeGenerator.Init (file_name);
+ CodeGenerator.Emit (prog);
+ CodeGenerator.Save (trim_extension (file_name) + ".exe");
}
-
- public object VisitThrow (Throw t, object args)
+ static void emit_default_case (EmitContext ec, AST ast, OpCode op, Label lbl)
{
- throw new NotImplementedException ();
+ ast.Emit (ec);
+ if (need_convert_to_boolean (ast))
+ emit_to_boolean (ast, ec.ig, 0);
+ ec.ig.Emit (op, lbl);
}
-
- public object VisitTry (Try t, object args)
+ static void ft_binary_recursion (EmitContext ec, AST ast, Label lbl)
{
- throw new NotImplementedException ();
+ ILGenerator ig = ec.ig;
+ if (ast is Binary) {
+ Binary b = ast as Binary;
+ switch (b.op) {
+ case JSToken.LogicalOr:
+ Label ftLb = ig.DefineLabel ();
+ fall_false (ec, b.left, ftLb);
+ fall_true (ec, b.right, lbl);
+ ig.MarkLabel (ftLb);
+ break;
+ case JSToken.LogicalAnd:
+ fall_true (ec, b.left, lbl);
+ fall_true (ec, b.right, lbl);
+ break;
+
+ case JSToken.LessThan:
+ ig.Emit (OpCodes.Ldc_I4_0);
+ ig.Emit (OpCodes.Conv_R8);
+ ig.Emit (OpCodes.Blt, lbl);
+ break;
+ }
+ }
}
-
- public object VisitWith (With w, object args)
+ static void ft_emit_equality (EmitContext ec, AST ast, Label lbl)
{
- throw new NotImplementedException ();
+ ILGenerator ig = ec.ig;
+ Equality eq = ast as Equality;
+
+ switch (eq.op) {
+ case JSToken.NotEqual:
+ ig.Emit (OpCodes.Brtrue, lbl);
+ break;
+ case JSToken.Equal:
+ ig.Emit (OpCodes.Brfalse, lbl);
+ break;
+ }
}
-
- public object VisitPrint (Print p, object args)
+ internal static void fall_true (EmitContext ec, AST ast, Label lbl)
{
- StringLiteral sl = p.Exp as StringLiteral;
-
- // sl.Visit (this, args);
-
- this.ilGen.Emit (OpCodes.Call,
- typeof (Microsoft.JScript.ScriptStream).GetMethod ("WriteLine", new Type [] {typeof (string)}));
-
- return null;
+ Type type = ast.GetType ();
+
+ if (type == typeof (Expression)) {
+ Expression exp = ast as Expression;
+ exp.Emit (ec);
+ AST last_exp = (AST) exp.exprs [exp.exprs.Count - 1];
+
+ if (last_exp is Binary)
+ ft_binary_recursion (ec, last_exp, lbl);
+ else if (last_exp is Equality)
+ ft_emit_equality (ec, last_exp, lbl);
+ } else if (type == typeof (Binary))
+ ft_binary_recursion (ec, ast, lbl);
+ else
+ emit_default_case (ec, ast, OpCodes.Brfalse, lbl);
}
+ static void ff_emit_relational (EmitContext ec, AST ast, Label lbl)
+ {
+ ILGenerator ig = ec.ig;
+ Relational r = ast as Relational;
+ r.Emit (ec);
+
+ switch (r.op) {
+ case JSToken.LessThan:
+ ig.Emit (OpCodes.Ldc_I4_0);
+ ig.Emit (OpCodes.Conv_R8);
+ ig.Emit (OpCodes.Blt, lbl);
+ break;
+ }
+ }
- //
- // Literals
- //
-
- public object VisitArrayLiteral (ArrayLiteral al, object args)
+ static void ff_binary_recursion (EmitContext ec, AST ast, Label lbl)
{
- throw new NotImplementedException ();
+ ILGenerator ig = ec.ig;
+ Binary b = ast as Binary;
+
+ switch (b.op) {
+ case JSToken.LogicalOr:
+ fall_false (ec, b.left, lbl);
+ fall_false (ec, b.right, lbl);
+ break;
+
+ case JSToken.LogicalAnd:
+ Label ftLb = ig.DefineLabel ();
+ fall_true (ec, b.left, ftLb);
+ fall_false (ec, b.right, lbl);
+ ig.MarkLabel (ftLb);
+ break;
+ }
}
+ static void ff_emit_equality_cond (EmitContext ec, AST ast, Label lbl)
+ {
+ ILGenerator ig = ec.ig;
+ Equality eq = ast as Equality;
+ eq.Emit (ec);
+
+ switch (eq.op) {
+ case JSToken.NotEqual:
+ case JSToken.Equal:
+ ig.Emit (OpCodes.Brfalse, lbl);
+ break;
+ }
+ }
+
+ internal static void fall_false (EmitContext ec, AST ast, Label lbl)
+ {
+ Type type = ast.GetType ();
+
+ if (type == typeof (Expression)) {
+ Expression exp = ast as Expression;
+
+ if (exp.Size > 1)
+ exp.Emit (ec);
+
+ AST last_exp = (AST) exp.exprs [exp.exprs.Count - 1];
+
+ if (last_exp is Relational)
+ ff_emit_relational (ec, last_exp, lbl);
+ else if (last_exp is Binary)
+ ff_binary_recursion (ec, last_exp, lbl);
+ else if (last_exp is Identifier || last_exp is BooleanLiteral)
+ emit_default_case (ec, last_exp, OpCodes.Brtrue, lbl);
+ else if (last_exp is Equality)
+ ff_emit_equality_cond (ec, last_exp, lbl);
+ else {
+ Console.WriteLine ("fall_false, last_exp.GetType () == {0}", last_exp);
+ throw new Exception ("uknown type: " + last_exp.GetType ().ToString ());
+ }
+ } else if (type == typeof (Binary))
+ ff_binary_recursion (ec, ast, lbl);
+ else
+ emit_default_case (ec, ast, OpCodes.Brtrue, lbl);
+ }
- public object VisitStringLiteral (StringLiteral sl, object args)
+ internal static void emit_to_boolean (AST ast, ILGenerator ig, int i)
{
- this.ilGen.Emit (OpCodes.Ldstr, sl.Str);
+ ig.Emit (OpCodes.Ldc_I4, i);
+ ig.Emit (OpCodes.Call, typeof (Convert).GetMethod ("ToBoolean",
+ new Type [] { typeof (object), typeof (Boolean)}));
+ }
- return null;
+ internal static bool need_convert_to_boolean (AST ast)
+ {
+ if (ast == null)
+ return false;
+
+ if (ast is Identifier)
+ return true;
+ else if (ast is Expression) {
+ Expression exp = ast as Expression;
+ int n = exp.exprs.Count - 1;
+ AST tmp = (AST) exp.exprs [n];
+ if (tmp is Equality || tmp is Relational || tmp is BooleanLiteral)
+ return false;
+ else
+ return true;
+ } else
+ return false;
+ }
+
+ //
+ // Loads a current VsaEngine
+ //
+ internal static void load_engine (AST parent, ILGenerator ig)
+ {
+ //
+ // If we are in a function declaration at global level,
+ // we must load the engine associated to the current 'JScript N' instance,
+ // otherwise pick up the engine at second place in method's signature.
+ //
+ if (parent == null || parent.GetType () == typeof (ScriptBlock)) {
+ ig.Emit (OpCodes.Ldarg_0);
+ ig.Emit (OpCodes.Ldfld, typeof (ScriptObject).GetField ("engine"));
+ } else if (parent != null && parent.GetType () == typeof (FunctionDeclaration ))
+ ig.Emit (OpCodes.Ldarg_1);
}
}
}