2004-01-23 Cesar Lopez Nataren <cesar@ciencias.unam.mx>
authorCésar Natarén <cesar@mono-cvs.ximian.com>
Fri, 23 Jan 2004 22:18:22 +0000 (22:18 -0000)
committerCésar Natarén <cesar@mono-cvs.ximian.com>
Fri, 23 Jan 2004 22:18:22 +0000 (22:18 -0000)
* jscript-lexer-parser.g: formal_param_list receives a parent too.

* SymbolTable.cs: added size and current_symbols properties.

* JSLocalField.cs: don't throw not ImplementedException from
constructor (same reason, testing purposes, must get implemented
for real).

* IdentificationTable.cs: added num_of_locals and current_locals properties.

* FunctionDeclaration.cs: added a LocalBuilder and DictionaryEntry
as fields. Not throw NotImplementedException for
JScriptFunctionDeclaration (testing purposes, must get implemeted
for real). Let's build our function closures! Added functions:
build_closure and build_closure_nested, build_local_fields. Keep
track of current parameters and locals defs.

* FormalParameterList.cs: made FormalParam inherit from
AST. Implement the Emit for parameters, yeah!

* CodeGenerator.cs: added a ModuleBuilder reference. New constructor.

* Closure.cs: do not throw the exception (this allow me to run the
tests  at mcs/jtests and check that at least i'm not generating
invalid CIL). Be aware that this must be really implemented.

* Block.cs: renamed field, and implement the double pass for
nested function declarations code emittion, yeah!.

svn path=/trunk/mcs/; revision=22449

mcs/class/Microsoft.JScript/Microsoft.JScript/Block.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/Closure.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/CodeGenerator.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/FormalParameterList.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/FunctionDeclaration.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/IdentificationTable.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/JSLocalField.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/SymbolTable.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/jscript-lexer-parser.g

index 429fc18e65e51b03fb5eff892cbcdfa803957e2d..1b09766bf896c210dda10fa2f3fd2c1ba4d28c51 100644 (file)
@@ -14,24 +14,24 @@ namespace Microsoft.JScript {
 
        public class Block : AST {
 
-               internal ArrayList Elements;
+               internal ArrayList elems;
 
                internal Block (AST parent)
                {
                        this.parent = parent;
-                       Elements = new ArrayList ();
+                       elems = new ArrayList ();
                }
 
                internal void Add (AST e)
                {
-                       Elements.Add (e);
+                       elems.Add (e);
                }
 
                public override string ToString ()
                {
                        StringBuilder sb = new StringBuilder ();
 
-                       foreach (AST a in Elements)
+                       foreach (AST a in elems)
                                if (a != null)
                                        sb.Append (a.ToString () + " ");
 
@@ -40,20 +40,30 @@ namespace Microsoft.JScript {
 
                internal override void Emit (EmitContext ec)
                {
-                       int i, size = Elements.Count;
+                       int i, n = elems.Count;
+                       object e;
+                       
+                       for (i = 0; i < n; i++) {
+                               e = elems [i];
+                               if (e is FunctionDeclaration)
+                                       ((FunctionDeclaration) e).Emit (ec);
+                       }
 
-                       for (i = 0; i < size; i++)
-                               ((AST) Elements [i]).Emit (ec);
+                       for (i = 0; i < n; i++) {
+                               e = elems [i];
+                               if (!(e is FunctionDeclaration))
+                                       ((AST) e).Emit (ec);
+                       }
                }
 
                internal override bool Resolve (IdentificationTable context)
                {
                        AST e;
                        bool r = true;
-                       int i, n = Elements.Count;
+                       int i, n = elems.Count;
 
                        for (i = 0; i < n; i++) {
-                               e = (AST) Elements [i];
+                               e = (AST) elems [i];
                                r &= e.Resolve (context);
                        }
                        return r;                       
index e8aaeea93d5fe28298efea6e4ef8d1b6edc9093f..87dd8851cccc483a214b63532d1ec8c9bd61e4ca 100644 (file)
@@ -17,7 +17,6 @@ namespace Microsoft.JScript {
 
                public Closure (FunctionObject func)
                {
-                       throw new NotImplementedException ();
                }
 
                public override string ToString ()
@@ -25,4 +24,4 @@ namespace Microsoft.JScript {
                        throw new NotImplementedException ();
                }
        }
-}
\ No newline at end of file
+}
index 74fa9ce9c4b0d57ac75f6e60907adf8cb74f52ac..d323c41eb9c676fca0af46b16d84003aefdd99c8 100644 (file)
@@ -21,6 +21,7 @@ namespace Microsoft.JScript {
                internal TypeBuilder type_builder;
                internal ILGenerator ig;
                internal ILGenerator gc_ig;
+               internal ModuleBuilder mod_builder;
 
                internal EmitContext (TypeBuilder type)
                {
@@ -35,6 +36,14 @@ namespace Microsoft.JScript {
                                gc_ig = global_code.GetILGenerator ();
                        }
                }
+
+               internal EmitContext (TypeBuilder type_builder, ModuleBuilder mod_builder, ILGenerator gc_ig, ILGenerator loc_ig)
+               {
+                       this.type_builder = type_builder;
+                       this.mod_builder = mod_builder;
+                       this.gc_ig = gc_ig;
+                       this.ig = loc_ig;                       
+               }
        }
 
        public class CodeGenerator {
@@ -99,6 +108,7 @@ namespace Microsoft.JScript {
                                                         (typeof (CompilerGlobalScopeAttribute).GetConstructor (new Type [] {}), new object [] {}));
 
                        EmitContext ec = new EmitContext (type_builder);
+                       ec.mod_builder = module_builder;
                        ILGenerator global_code = ec.gc_ig;
 
                        emit_default_script_constructor (ec);
index a5da530ced1254d11ef46969908706507a877658..8fe66e7d9e71fd278aae8eb6f61ac610c4c12aa2 100644 (file)
@@ -7,13 +7,14 @@
 // (C) 2003, Cesar Lopez Nataren, <cesar@ciencias.unam.mx>
 //
 
+using System.Reflection.Emit;
 using System.Collections;
 using System.Text;
 using System;
 
 namespace Microsoft.JScript {
 
-       internal class FormalParam {
+       internal class FormalParam : AST {
                internal string id;
                internal string type_annot;
 
@@ -34,13 +35,23 @@ namespace Microsoft.JScript {
                {
                        return id + " " + type_annot;
                }
+
+               internal override void Emit (EmitContext ec)
+               {
+               }
+
+               internal override bool Resolve (IdentificationTable context)
+               {
+                       context.Enter (id, this);
+                       return true;
+               }
        }
                        
        public class FormalParameterList : AST {
 
                internal ArrayList ids;
 
-               public FormalParameterList ()
+               internal FormalParameterList ()
                {
                        ids = new ArrayList ();
                }
@@ -64,19 +75,33 @@ namespace Microsoft.JScript {
                internal override bool Resolve (IdentificationTable context)
                {
                        FormalParam f;
-                       int i, size = ids.Count;
+                       int i, n = ids.Count;
 
-                       for (i = 0; i < size; i++) {
+                       for (i = 0; i < n; i++) {
                                f = (FormalParam) ids [i];
-                               context.Enter (f.id, f);
+                               f.Resolve (context);
                        }
-
                        return true;
                } 
 
                internal override void Emit (EmitContext ec)
                {
-                       throw new NotImplementedException ();
+                       int n = ids.Count;
+                       ILGenerator ig = ec.gc_ig;
+                               
+                       ig.Emit (OpCodes.Ldc_I4, n);
+                       ig.Emit (OpCodes.Newarr, typeof (string));
+
+                       for (int i = 0; i < n; i++) {
+                               ig.Emit (OpCodes.Dup);
+                               ig.Emit (OpCodes.Ldc_I4, i);
+                               ig.Emit (OpCodes.Ldstr, ((FormalParam) ids [i]).id);
+                               ig.Emit (OpCodes.Stelem_Ref);
+                       }
+               }
+
+               internal int size {
+                       get { return ids.Count; }
                }
        }
 }
index 9e7c4da0322be66b176340cc9f204fa0ab4ad032..57c5825e278e1725b9d9a627099dd42380008195 100644 (file)
@@ -12,12 +12,15 @@ using System.Text;
 using System.Reflection;
 using System.Reflection.Emit;
 using Microsoft.JScript.Vsa;
+using System.Collections;
 
 namespace Microsoft.JScript {
 
        public class FunctionDeclaration : AST {
 
                internal FunctionObject Function;
+               internal DictionaryEntry [] locals;
+               internal LocalBuilder local_func;
 
                internal FunctionDeclaration (AST parent, string name, 
                                              FormalParameterList p,
@@ -34,9 +37,9 @@ namespace Microsoft.JScript {
                                                                  bool hasArgumentsObjects, string text, 
                                                                  Object declaringObject, VsaEngine engine)
                {
-                       throw new NotImplementedException ();
+                       FunctionObject f = null;
+                       return new Closure (f);
                }
-
                
                internal FunctionDeclaration ()
                {
@@ -68,43 +71,133 @@ namespace Microsoft.JScript {
                        TypeBuilder type = ec.type_builder;
                        MethodBuilder method;
                        string name;
-
+                       
                        if (parent == null) {
                                name = Function.name;
                                type.DefineField (name, 
                                                  typeof (Microsoft.JScript.ScriptFunction),
                                                  FieldAttributes.Public | 
-                                                 FieldAttributes.Static);             
+                                                 FieldAttributes.Static);
+                               build_closure (ec);
+                               method = type.DefineMethod (name, Function.attr, 
+                                                           Function.return_type,
+                                                           Function.params_types ());
+                               ec.ig = method.GetILGenerator ();
+                               Function.body.Emit (ec);
+                               ec.ig.Emit (OpCodes.Ret);
+                               return;
                        } else {
                                name = get_composite_name ();
-                               ec.ig.DeclareLocal (typeof (Microsoft.JScript.ScriptFunction));
+                               local_func = ec.ig.DeclareLocal (typeof (Microsoft.JScript.ScriptFunction));
+                               
+                               method = type.DefineMethod (name, Function.attr, 
+                                                           Function.return_type,
+                                                           Function.params_types ());
+                               EmitContext new_ec = new EmitContext (ec.type_builder, ec.mod_builder, ec.ig, method.GetILGenerator ());
+                               build_closure_nested (new_ec);                          
+                               Function.body.Emit (new_ec);
+                               new_ec.ig.Emit (OpCodes.Ret);
+                       }
+               }
+               
+               internal void build_closure (EmitContext ec)
+               {
+                       ILGenerator ig = ec.gc_ig;
+                       string name = Function.name;
+                       Type t = ec.mod_builder.GetType ("JScript 0");
+                       ig.Emit (OpCodes.Ldtoken, t);
+                       ig.Emit (OpCodes.Ldstr, name);
+                       ig.Emit (OpCodes.Ldstr, name);
+                       Function.parameters.Emit (ec);
+                       build_local_fields (ig);
+
+                       ig.Emit (OpCodes.Ldc_I4_0); // FIXME: this hard coded for now.
+                       ig.Emit (OpCodes.Ldc_I4_0); // FIXME: this hard coded for now.
+                       ig.Emit (OpCodes.Ldstr, "STRING_REPRESENTATION_OF_THE_FUNCTION"); // FIXME
+                       ig.Emit (OpCodes.Ldnull); // FIXME: this hard coded for now.
+
+                       ig.Emit (OpCodes.Ldarg_0);
+                       ig.Emit (OpCodes.Ldfld, typeof (ScriptObject).GetField ("engine"));
+                       ig.Emit (OpCodes.Call, typeof (FunctionDeclaration).GetMethod ("JScriptFunctionDeclaration"));
+                       ig.Emit (OpCodes.Stsfld, ec.mod_builder.GetType ("JScript 0").GetField (name));
+               }
+
+               internal void build_closure_nested (EmitContext ec)
+               {
+                       ILGenerator ig = ec.gc_ig;
+                       string name = get_composite_name ();
+                       Type t = ec.mod_builder.GetType ("JScript 0");
+                       ig.Emit (OpCodes.Ldtoken, t);
+                       ig.Emit (OpCodes.Ldstr, Function.name);
+                       ig.Emit (OpCodes.Ldstr, name);
+                       Function.parameters.Emit (ec);
+                       build_local_fields (ig);
+
+                       ig.Emit (OpCodes.Ldc_I4_0); // FIXME: this hard coded for now.
+                       ig.Emit (OpCodes.Ldc_I4_0); // FIXME: this hard coded for now.
+                       ig.Emit (OpCodes.Ldstr, "STRING_REPRESENTATION_OF_THE_FUNCTION"); // FIXME
+                       ig.Emit (OpCodes.Ldnull); // FIXME: this hard coded for now.
+
+                       ig.Emit (OpCodes.Ldarg_0);
+                       ig.Emit (OpCodes.Ldfld, typeof (ScriptObject).GetField ("engine"));
+                       ig.Emit (OpCodes.Call, typeof (FunctionDeclaration).GetMethod ("JScriptFunctionDeclaration"));
+                       ig.Emit (OpCodes.Stloc, local_func);
+               }
+
+               internal void build_local_fields (ILGenerator ig)
+               {
+                       DictionaryEntry e;
+                       object v;                     
+                       int n;
+
+                       if (locals == null)
+                               n = 0;
+                       else 
+                               n = locals.Length;
+
+                       Type t = typeof (JSLocalField);
+
+                       ig.Emit (OpCodes.Ldc_I4, n);
+                       ig.Emit (OpCodes.Newarr, t);
+
+                       for (int i = 0; i < n; i++) {
+                               ig.Emit (OpCodes.Dup);
+                               ig.Emit (OpCodes.Ldc_I4, i);
+                               e = locals [i];
+                               ig.Emit (OpCodes.Ldstr, (string) e.Key);
+                               v = e.Value;
+
+                               if (v is VariableDeclaration)
+                                       ig.Emit (OpCodes.Ldtoken, ((VariableDeclaration) v).type);
+                               else if (v is FormalParam)
+                                       ig.Emit (OpCodes.Ldtoken, ((FormalParam) v).type);
+                               else if (v is FunctionDeclaration)
+                                       ig.Emit (OpCodes.Ldtoken, typeof (ScriptFunction));
+
+                               ig.Emit (OpCodes.Ldc_I4, i);
+                               ig.Emit (OpCodes.Newobj, t.GetConstructor (new Type [] { 
+                                                                               typeof (string), 
+                                                                               typeof (RuntimeTypeHandle),
+                                                                               typeof (Int32) }));
+                               ig.Emit (OpCodes.Stelem_Ref);
                        }
-                       method = type.DefineMethod (name, Function.attr, 
-                                                   Function.return_type,
-                                                   Function.params_types ());
-       
-                       ec.ig = method.GetILGenerator ();               
-                       Function.body.Emit (ec);
-                       ec.ig.Emit (OpCodes.Ret);
                }
 
                internal override bool Resolve (IdentificationTable context)
                {
                        context.Enter (Function.name, this);
                        context.OpenBlock ();
-
                        FormalParameterList p = Function.parameters;
 
                        if (p != null)
                                p.Resolve (context);
 
                        Block body = Function.body;
-
                        if (body != null)
                                body.Resolve (context);
 
-                       context.CloseBlock ();
-               
+                       locals = context.current_locals;
+                       context.CloseBlock ();          
                        return true;
                }
        }
index 0581d4a770304e91cb7243ab1b8ee82d0d4d6414..702e70b2acc0c55ca29974f9a61894f83ad2cae2 100644 (file)
@@ -66,5 +66,13 @@ namespace Microsoft.JScript {
 
                        return sb.ToString ();
                }
+
+               internal int num_of_locals {
+                       get { return  ((SymbolTable) stack.Peek ()).size; }
+               }
+
+               internal DictionaryEntry [] current_locals {
+                       get { return  ((SymbolTable) stack.Peek ()).current_symbols; }
+               }
        }
 }
index 09cfacccbdd66eeb2df197f1e865330ef4599ccd..4f2c4fd0512d95eb5a10b9141d72a4aed80bb7b5 100644 (file)
@@ -16,7 +16,6 @@ namespace Microsoft.JScript {
 
                public JSLocalField (string name, RuntimeTypeHandle handle, int number)
                {
-                       throw new NotImplementedException ();
                }
 
                public override Type FieldType {
@@ -35,4 +34,4 @@ namespace Microsoft.JScript {
                }
        }
 }
-                                             
\ No newline at end of file
+                                             
index 37d09c102eff195989f8bb4fde9fdeb799d11d42..8f5564d6da32f4f006629b2ce9a393ad4a98fc2a 100644 (file)
@@ -44,5 +44,22 @@ namespace Microsoft.JScript {
 
                        return sb.ToString ();
                }
+
+               internal int size {
+                       get { return symbols.Count; }
+               }
+
+               internal DictionaryEntry [] current_symbols {
+                       get {
+                               int n = symbols.Count;
+                               if (n == 0)
+                                       return null;
+                               else {
+                                       DictionaryEntry [] e = new DictionaryEntry [symbols.Count];
+                                       symbols.CopyTo (e, 0);
+                                       return e;
+                               }
+                       }
+               }
        }
 }
index b24366c22f7fc7dd3b7dce8fdedf082b028da21d..fac4833d1ea7c0f874ad2a421a8d7fd6ff4c0cc4 100644 (file)
@@ -48,11 +48,11 @@ function_decl_or_expr [AST parent] returns [AST func]
 {
        func = null;
        bool is_func_exp = false;
-       FormalParameterList p = null;
+       FormalParameterList p = new FormalParameterList ();
        Block body = null;
 }
        : "function" (id:IDENTIFIER | { is_func_exp = true; } ) 
-         OPEN_PARENS (p = formal_param_list | ) CLOSE_PARENS 
+         OPEN_PARENS (p = formal_param_list [parent] | ) CLOSE_PARENS 
          (COLON type_annot:IDENTIFIER | )
          {
                if (is_func_exp)
@@ -81,9 +81,10 @@ function_body [AST parent] returns [Block elems]
        : source_elements [elems]
        ;
 
-formal_param_list returns [FormalParameterList p]
+formal_param_list [AST parent] returns [FormalParameterList p]
 {
        p = new FormalParameterList ();
+    p.parent = parent;
 }
        : i:IDENTIFIER (COLON t1:IDENTIFIER { p.Add (i.getText (), t1.getText ()); } 
                       | { p.Add (i.getText (), "Object"); }