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 () + " ");
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;
// (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;
{
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 ();
}
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; }
}
}
}
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,
bool hasArgumentsObjects, string text,
Object declaringObject, VsaEngine engine)
{
- throw new NotImplementedException ();
+ FunctionObject f = null;
+ return new Closure (f);
}
-
internal FunctionDeclaration ()
{
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;
}
}