+2005-10-11 Cesar Lopez Nataren <cnataren@novell.com>
+
+ * VsaEngine.cs: Parse all the files.
+
2005-09-13 Cesar Lopez Nataren <cnataren@novell.com>
* VsaEngine.cs: Override method Compile and SetOption from BaseVsaEngine,
throw new Exception ("FIXME: VsaItemType.AppGlobal");
}
Parser parser = new Parser (code_items);
- ScriptBlock block = (ScriptBlock) parser.ParseAll ();
- if (block != null) {
- SemanticAnalyser.Run (block, (Assembly []) GetOption ("assemblies"));
- CodeGenerator.Run ((string) GetOption ("first_source"), block);
+ ScriptBlock [] blocks = parser.ParseAll ();
+ if (blocks != null) {
+ SemanticAnalyser.Run (blocks, (Assembly []) GetOption ("assemblies"));
+ CodeGenerator.Run ((string) GetOption ("first_source"), blocks);
Console.WriteLine ("Compilation succeeded");
}
return false;
get { return elems.Count; }
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
throw new NotImplementedException ();
}
this.location = location;
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
bool r = true;
foreach (AST ast in elems.elems)
if (ast != null)
- r &= ast.Resolve (context);
+ r &= ast.Resolve (env);
return r;
}
return (uint) num1 >> num2;
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
throw new NotImplementedException ();
}
namespace Microsoft.JScript {
- public class Block : AST {
+ public class Block : AST, ICanModifyContext {
internal ArrayList elems;
- private Hashtable ocurrences;
internal Block (AST parent, Location location)
: base (parent, location)
{
elems = new ArrayList ();
- ocurrences = new Hashtable ();
}
internal void Add (AST e)
elems.Add (e);
}
- internal override void Emit (EmitContext ec)
+ void ICanModifyContext.EmitDecls (EmitContext ec)
{
- int i, n = elems.Count;
- object e;
-
//
- // Emit variable declarations first
- // because of posible free occurrences inside
- // a method.
+ // Emit variable declarations and function's closure first
+ // because of posible free occurrences inside a method.
//
- for (i = 0; i < n; i++) {
- e = elems [i];
- if (e is VariableStatement)
- ((VariableStatement) e).EmitVariableDecls (ec);
- }
+ foreach (AST ast in elems)
+ if (ast is FunctionDeclaration)
+ ((FunctionDeclaration) ast).create_closure (ec);
+ else if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).EmitDecls (ec);
+ }
+
+ internal override void Emit (EmitContext ec)
+ {
+ int n = elems.Count;
+ object e;
- //
- // Emit the function closure before any
- // expression because the ScriptFunction and
- // field created must be set properly before
- // any use. The body gets emitted later.
- //
- for (i = 0; i < n; i++) {
- e = elems [i];
- if (e is FunctionDeclaration)
- ((FunctionDeclaration) e).create_closure (ec);
- }
-
//
// Emit the rest of expressions and statements.
//
- for (i = 0; i < n; i++) {
+ for (int i = 0; i < n; i++) {
e = elems [i];
((AST) e).Emit (ec);
}
}
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ AST ast;
+ for (int i = 0; i < elems.Count; i++) {
+ ast = (AST) elems [i];
+ if (ast is FunctionDeclaration) {
+ string name = ((FunctionDeclaration) ast).func_obj.name;
+ AST binding = (AST) env.Get (ns, Symbol.CreateSymbol (name));
+
+ if (binding == null)
+ SemanticAnalyser.Ocurrences.Enter (ns, Symbol.CreateSymbol (name), new DeleteInfo (i, this));
+ else {
+ DeleteInfo delete_info = (DeleteInfo) SemanticAnalyser.Ocurrences.Get (ns, Symbol.CreateSymbol (name));
+ if (delete_info != null) {
+ delete_info.Block.elems.RemoveAt (delete_info.Index);
+ SemanticAnalyser.Ocurrences.Remove (ns, Symbol.CreateSymbol (name));
+ if (delete_info.Block == this)
+ if (delete_info.Index < i)
+ i--;
+
+ SemanticAnalyser.Ocurrences.Enter (ns, Symbol.CreateSymbol (name), new DeleteInfo (i, this));
+ }
+ }
+ }
+ if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).PopulateContext (env, ns);
+ }
+ }
+
+ internal override bool Resolve (Environment env)
{
AST e;
bool no_effect;
else
no_effect = false;
- for (i = 0; i < elems.Count; i++) {
- e = (AST) elems [i];
- //
- // Add the variables to the symbol
- // tables. If a variable declaration
- // has an initializer we postpone the
- // resolve process of the initializer
- // until we have collected all the
- // variable declarations.
- //
- if (e is VariableStatement)
- (e as VariableStatement).PopulateContext (context);
- else if (e is FunctionDeclaration) {
- //
- // In the case of function
- // declarations we add
- // function's name to the
- // table but we resolve its
- // body until later, as free
- // variables can be referenced
- // in function's body.
- //
- string name = ((FunctionDeclaration) e).func_obj.name;
- AST binding = (AST) context.Get (Symbol.CreateSymbol (name));
-
- if (binding == null) {
- ocurrences.Add (name, i);
- context.Enter (Symbol.CreateSymbol (((FunctionDeclaration) e).func_obj.name), new FunctionDeclaration ());
- } else {
- Console.WriteLine ("warning: JS1111: '{0}' has already been defined.", name);
- if (!(binding is FunctionDeclaration))
- throw new Exception ("error JS5040: '" + ((VariableDeclaration) binding).id + "' it's read only.");
- int k = (int) ocurrences [name];
- elems.RemoveAt (k);
- if (k < i)
- i -= 1;
- ocurrences [name] = i;
- }
- }
- }
n = elems.Count;
for (i = 0; i < n; i++) {
e = (AST) elems [i];
if (e is Exp)
- r &= ((Exp) e).Resolve (context, no_effect);
- else
- r &= e.Resolve (context);
+ r &= ((Exp) e).Resolve (env, no_effect);
+ else
+ r &= e.Resolve (env);
}
- return r;
+ return r;
+ }
+ }
+
+ internal class DeleteInfo {
+ private int index;
+ private Block block;
+
+ internal DeleteInfo (int index, Block block)
+ {
+ this.index = index;
+ this.block = block;
+ }
+
+ internal int Index {
+ get { return index; }
+ }
+
+ internal Block Block {
+ get { return block; }
}
}
}
+2005-10-11 Cesar Lopez Nataren <cnataren@novell.com>
+
+ * Add support for multiple files compilation. This involved addig
+ an extra pass into the AST for ensuring the resolve process, this
+ pass is named PopulateContext. The AST nodes that implement
+ ICanModifyContext call PopulateContext.
+
+ * IdentificationTable.cs: Added class Environment, which is a
+ symbol table which takes into account namespace info, this is for
+ package statement future implementation.
+
2005-09-30 Cesar Lopez Nataren <cnataren@novell.com>
* expression.cs (Expression::Resolve): check if we have an
using System.Reflection.Emit;
using System.Threading;
using Microsoft.JScript.Vsa;
-using System.Runtime.CompilerServices;
using System.Collections;
namespace Microsoft.JScript {
internal TypeBuilder type_builder;
internal ILGenerator ig;
internal ModuleBuilder mod_builder;
+ internal MethodBuilder global_code;
internal Label LoopBegin, LoopEnd;
- internal EmitContext (TypeBuilder type)
- {
- 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 EmitContext (TypeBuilder type_builder, ModuleBuilder mod_builder, ILGenerator ig)
{
this.type_builder = type_builder;
internal static AssemblyName assembly_name;
internal static AssemblyBuilder assembly_builder;
internal static ModuleBuilder module_builder;
+ private static int next_type = 0;
+ private static ArrayList global_types = new ArrayList ();
+ private static Hashtable global_methods = new Hashtable ();
+ private static Hashtable source_file_to_type = new Hashtable ();
+
+ private static string NextType {
+ get { return "JScript " + next_type++; }
+ }
internal static string Basename (string name)
{
assembly_builder.Save (CodeGenerator.Basename (target_name));
}
- internal static void Emit (AST prog)
+ internal static void EmitDecls (ScriptBlock prog)
{
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 [] {}));
+ string next_type = CodeGenerator.NextType;
- EmitContext ec = new EmitContext (type_builder);
- ec.mod_builder = module_builder;
- ILGenerator global_code = ec.ig;
+ prog.InitTypeBuilder (module_builder, next_type);
+ prog.InitGlobalCode ();
- 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 ();
- }
-
- internal static void emit_default_init_global_code (ILGenerator ig)
- {
- 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)}));
- }
-
- 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);
- }
-
- internal static void emit_default_script_constructor (EmitContext ec)
- {
- ConstructorBuilder cons_builder;
- TypeBuilder tb = ec.type_builder;
- cons_builder = tb.DefineConstructor (MethodAttributes.Public,
- CallingConventions.Standard,
- new Type [] { typeof (GlobalScope) });
+ global_types.Add (next_type);
+ global_methods.Add (next_type, prog.GlobalCode);
+ source_file_to_type.Add (prog.Location.SourceName, next_type);
- 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);
+ prog.EmitDecls (module_builder);
}
internal static void emit_jscript_main (TypeBuilder tb)
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);
+
+ foreach (string type_name in global_types) {
+ ig.Emit (OpCodes.Ldloc_0);
+ ig.Emit (OpCodes.Newobj, assembly_builder.GetType (type_name).GetConstructor (
+ new Type [] {typeof (GlobalScope)}));
+ ig.Emit (OpCodes.Call, (MethodInfo) global_methods [type_name]);
+ ig.Emit (OpCodes.Pop);
+ }
ig.Emit (OpCodes.Ret);
assembly_builder.SetEntryPoint (method);
}
- public static void Run (string file_name, AST prog)
+ public static void Run (string file_name, ScriptBlock [] blocks)
{
CodeGenerator.Init (file_name);
- CodeGenerator.Emit (prog);
+
+ //
+ // Emit first all the declarations (function and variables)
+ //
+ foreach (ScriptBlock script_block in blocks)
+ CodeGenerator.EmitDecls (script_block);
+
+ //
+ // emit everything that's not a declaration
+ //
+ foreach (ScriptBlock script_block in blocks)
+ script_block.Emit ();
+
+ //
+ // Create the types ('JScript N')
+ //
+ foreach (ScriptBlock script_block in blocks)
+ script_block.CreateType ();
+
+ //
+ // Build the default 'JScript Main' class
+ //
+ TypeBuilder main_type_builder = module_builder.DefineType ("JScript Main");
+ emit_jscript_main (main_type_builder);
+ main_type_builder.CreateType ();
+
CodeGenerator.Save (trim_extension (file_name) + ".exe");
}
ig.Emit (OpCodes.Conv_R8);
ig.Emit (OpCodes.Blt, lbl);
break;
+
+ default:
+ ast.Emit (ec);
+ ig.Emit (OpCodes.Ldc_I4_1);
+ ig.Emit (OpCodes.Call, typeof (Convert).GetMethod ("ToBoolean", new Type [] {typeof (object), typeof (bool)}));
+ ig.Emit (OpCodes.Brfalse, lbl);
+ break;
}
}
}
{
Type type = ast.GetType ();
- if (type == typeof (Expression)) {
- Expression exp = ast as Expression;
- AST last_exp = last_exp = (AST) exp.exprs [exp.exprs.Count - 1];
+ if (type == typeof (Expression)) {
+ Expression exp = ast as Expression;
+ AST last_exp = (AST) exp.exprs [exp.exprs.Count - 1];
if (exp.exprs.Count >= 2)
exp.Emit (ec);
fall_true (ec, last_exp, lbl);
ft_binary_recursion (ec, ast, lbl);
else if (type == typeof (Equality) || type == typeof (StrictEquality))
ft_emit_equality (ec, ast, lbl);
+ else if (type == typeof (Relational))
+ ft_emit_relational (ec, (Relational) ast, lbl);
else
emit_default_case (ec, ast, OpCodes.Brfalse, lbl);
}
Relational r = ast as Relational;
r.Emit (ec);
+ OpCode opcode;
+
switch (r.op) {
case JSToken.LessThan:
- ig.Emit (OpCodes.Ldc_I4_0);
- ig.Emit (OpCodes.Conv_R8);
- ig.Emit (OpCodes.Blt, lbl);
+ opcode = OpCodes.Blt;
+ break;
+
+ case JSToken.GreaterThan:
+ opcode = OpCodes.Bgt;
+ break;
+
+ case JSToken.LessThanEqual:
+ opcode = OpCodes.Ble;
+ break;
+
+ case JSToken.GreaterThanEqual:
+ opcode = OpCodes.Bge;
+ break;
+
+ default:
+ throw new Exception ("unexpected token");
+ }
+
+ ig.Emit (OpCodes.Ldc_I4_0);
+ ig.Emit (OpCodes.Conv_R8);
+ ig.Emit (opcode, lbl);
+ }
+
+ static void ft_emit_relational (EmitContext ec, Relational re, Label lbl)
+ {
+ ILGenerator ig = ec.ig;
+
+ re.Emit (ec);
+ JSToken op = re.op;
+
+ OpCode opcode;
+
+ switch (op) {
+ case JSToken.LessThan:
+ opcode = OpCodes.Bge_Un;
break;
+
+ case JSToken.GreaterThan:
+ opcode = OpCodes.Ble_Un;
+ break;
+
+ case JSToken.LessThanEqual:
+ opcode = OpCodes.Bgt_Un;
+ break;
+
+ case JSToken.GreaterThanEqual:
+ opcode = OpCodes.Blt_Un;
+ break;
+
+ default:
+ Console.WriteLine (re.Location.LineNumber);
+ throw new NotImplementedException ();
}
+
+ ig.Emit (OpCodes.Ldc_I4_0);
+ ig.Emit (OpCodes.Conv_R8);
+ ig.Emit (opcode, lbl);
}
static void ff_binary_recursion (EmitContext ec, AST ast, Label lbl)
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 ());
+ throw new Exception ("unknown type: " + last_exp.GetType ().ToString ());
}
} else if (type == typeof (Binary))
ff_binary_recursion (ec, ast, lbl);
+ else if (type == typeof (Relational))
+ ff_emit_relational (ec, ast, lbl);
else
emit_default_case (ec, ast, OpCodes.Brtrue, lbl);
}
Console.WriteLine (re.Location.LineNumber);
throw new NotImplementedException ();
}
+
ig.Emit (opcode, true_case);
ig.Emit (OpCodes.Ldc_I4_0);
ig.Emit (OpCodes.Br, box_to_bool);
ig.MarkLabel (box_to_bool);
ig.Emit (OpCodes.Box, typeof (bool));
}
+
+ internal static string GetTypeName (string srcName)
+ {
+ return (string) source_file_to_type [srcName];
+ }
}
}
{
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
throw new NotImplementedException ();
}
newCapacity = minimalCapacity;
char [] tmp = new char [newCapacity];
- // System.arraycopy (sourceBuffer, 0, tmp, 0, sourceTop);
Array.Copy (sourceBuffer, 0, tmp, 0, sourceTop);
sourceBuffer = tmp;
}
return sb.ToString ();
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
throw new NotImplementedException ();
}
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (left != null)
- r &= left.Resolve (context);
+ r &= left.Resolve (env);
if (right != null)
- r &= right.Resolve (context);
+ r &= right.Resolve (env);
return r;
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
- return Resolve (context);
+ return Resolve (env);
}
internal override void Emit (EmitContext ec)
}
#endif
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
throw new NotImplementedException ();
}
namespace Microsoft.JScript {
- public class ForIn : AST {
+ public class ForIn : AST, ICanModifyContext {
AST lhs, obj, body;
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ if (lhs is ICanModifyContext)
+ ((ICanModifyContext) lhs).PopulateContext (env, ns);
+
+ if (body is ICanModifyContext)
+ ((ICanModifyContext) body).PopulateContext (env, ns);
+ }
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ if (lhs is ICanModifyContext)
+ ((ICanModifyContext) lhs).EmitDecls (ec);
+
+ if (body is ICanModifyContext)
+ ((ICanModifyContext) body).EmitDecls (ec);
+ }
+
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (lhs != null)
if (lhs is VariableStatement)
- ((VariableStatement) lhs).PopulateContext (context);
+ ((ICanModifyContext) lhs).PopulateContext (env, String.Empty);
else
- r &= lhs.Resolve (context);
+ r &= lhs.Resolve (env);
if (obj != null)
- r &= obj.Resolve (context);
+ r &= obj.Resolve (env);
if (body != null)
- r &= body.Resolve (context);
+ r &= body.Resolve (env);
return r;
}
if (lhs is VariableStatement) {
VariableStatement stm = (VariableStatement) lhs;
- stm.EmitVariableDecls (ec);
ig = ec.ig;
ig.Emit (OpCodes.Ldnull);
object var = TypeManager.Get (((VariableDeclaration) stm.var_decls [0]).id);
internal override void Emit (EmitContext ec)
{
}
-
- internal override bool Resolve (IdentificationTable context)
+
+ internal override bool Resolve (Environment env)
{
- context.Enter (Symbol.CreateSymbol (id), this);
+ env.Enter (String.Empty, Symbol.CreateSymbol (id), this);
return true;
}
}
internal void Add (string id, string type_annot, Location location)
{
FormalParam p = new FormalParam (id, type_annot, location);
- ids.Add (p);
+ ids.Add (p);
}
public override string ToString ()
return sb.ToString ();
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
FormalParam f;
int i, n = ids.Count;
for (i = 0; i < n; i++) {
f = (FormalParam) ids [i];
f.pos = (byte) (i + 2);
- f.Resolve (context);
+ f.Resolve (env);
}
return true;
}
namespace Microsoft.JScript {
- public class FunctionDeclaration : Function {
+ public class FunctionDeclaration : Function, ICanModifyContext {
private int lexical_depth;
TypeManager.BeginScope ();
ILGenerator old_ig = ec.ig;
ec.ig = this.ig;
+
+ ((ICanModifyContext) func_obj.body).EmitDecls (ec);
func_obj.body.Emit (ec);
string func_name = func_obj.name;
{
ILGenerator ig = ec.ig;
string name = func_obj.name;
-
- Type t = ec.mod_builder.GetType ("JScript 0");
+ Type t = ec.mod_builder.GetType (CodeGenerator.GetTypeName (Location.SourceName));
ig.Emit (OpCodes.Ldtoken, t);
ig.Emit (OpCodes.Ldstr, name);
ig.Emit (OpCodes.Ldstr, full_name);
emit_return_local_field (ig, ctr_info, n);
}
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
{
- set_function_type ();
-
//
- // outer scope has already added the symbol to the
- // table but not the correct binding.
+ // In the case of function
+ // declarations we add
+ // function's name to the
+ // table but we resolve its
+ // body until later, as free
+ // variables can be referenced
+ // in function's body.
//
- FunctionDeclaration func_decl = (FunctionDeclaration) context.Get (Symbol.CreateSymbol (func_obj.name));
- func_decl.Init (this.parent, this.func_obj.name, this.func_obj.parameters, this.func_obj.type_annot, this.func_obj.body);
+ string name = func_obj.name;
+ AST binding = (AST) env.Get (String.Empty, Symbol.CreateSymbol (name));
+
+ if (binding == null)
+ env.Enter (String.Empty, Symbol.CreateSymbol (name), this);
+ else if (binding is FunctionDeclaration || binding is VariableDeclaration) {
+ Console.WriteLine ("{0}({1},0) : warning JS1111: '{2}' is already defined",
+ Location.SourceName, Location.LineNumber, name);
+ }
+
+ if (binding is VariableDeclaration) {
+ VariableDeclaration var_decl = (VariableDeclaration) binding;
+ string error_msg = Location.SourceName + "(" + var_decl.Location.LineNumber + ",0) : "
+ + "error JS5040: '" + var_decl.id + "' is read-only";
+ throw new Exception (error_msg);
+ }
+ }
- context.BeginScope ();
- lexical_depth = context.depth;
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ ((ICanModifyContext) func_obj.body).EmitDecls (ec);
+ }
+
+ internal override bool Resolve (Environment env)
+ {
+ set_function_type ();
+ env.BeginScope (String.Empty);
+ lexical_depth = env.Depth (String.Empty);
+
+ ((ICanModifyContext) func_obj).PopulateContext (env, String.Empty);
FormalParameterList p = func_obj.parameters;
if (p != null)
- p.Resolve (context);
-
+ p.Resolve (env);
+
Block body = func_obj.body;
if (body != null)
- body.Resolve (context);
+ body.Resolve (env);
- locals = context.CurrentLocals;
- context.EndScope ();
+ locals = env.CurrentLocals (String.Empty);
+ env.EndScope (String.Empty);
return true;
}
}
namespace Microsoft.JScript {
- public class FunctionExpression : Function {
+ public class FunctionExpression : Function, ICanModifyContext {
internal LocalBuilder local_script_func;
internal FieldBuilder field;
internal FunctionExpression (AST parent, string name, Location location)
: this (parent, name, null, String.Empty, null, location)
{
+ this.location = location;
}
internal FunctionExpression (AST parent, string name,
return fun;
}
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ //
+ // In the case of function
+ // expressions we add
+ // function's name to the
+ // table but we resolve its
+ // body until later, as free
+ // variables can be referenced
+ // in function's body.
+ //
+ string name = func_obj.name;
+ AST binding = null;
+
+ if (name != null && name != String.Empty)
+ binding = (AST) env.Get (ns, Symbol.CreateSymbol (name));
+
+ if (binding == null)
+ env.Enter (ns, Symbol.CreateSymbol (name), new FunctionDeclaration ());
+ else {
+ Console.WriteLine ("repeated functions are not handled yet");
+ throw new NotImplementedException ();
+ }
+ }
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ ((ICanModifyContext) func_obj.body).EmitDecls (ec);
+ }
+
+ internal override bool Resolve (Environment env)
{
set_function_type ();
+
if (func_obj.name != null && func_obj.name != String.Empty)
- context.Enter (Symbol.CreateSymbol (func_obj.name), this);
- context.BeginScope ();
+ env.Enter (String.Empty, Symbol.CreateSymbol (func_obj.name), this);
+ env.BeginScope (String.Empty);
+
+ ((ICanModifyContext) func_obj).PopulateContext (env, String.Empty);
+
FormalParameterList p = func_obj.parameters;
if (p != null)
- p.Resolve (context);
+ p.Resolve (env);
Block body = func_obj.body;
if (body != null)
- body.Resolve (context);
+ body.Resolve (env);
- locals = context.CurrentLocals;
- context.EndScope ();
+ locals = env.CurrentLocals (String.Empty);
+ env.EndScope (String.Empty);
return true;
}
ILGenerator ig = ec.ig;
string name = func_obj.name;
- Type t = ec.mod_builder.GetType ("JScript 0");
+ Type t = ec.mod_builder.GetType (CodeGenerator.GetTypeName (Location.SourceName));
ig.Emit (OpCodes.Ldtoken, t);
if (name != String.Empty)
namespace Microsoft.JScript {
- public class FunctionObject : ScriptFunction {
+ public class FunctionObject : ScriptFunction, ICanModifyContext {
internal string type_annot;
internal Block body;
return types;
}
}
+
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ ((ICanModifyContext) body).PopulateContext (env, ns);
+ }
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ ((ICanModifyContext) body).EmitDecls (ec);
+ }
}
}
// Cesar Lopez Nataren (cnataren@novell.com)
//
// (C) 2003, Cesar Lopez Nataren
-// (C) 2005 Novell Inc.
+// Copyright (C) 2005 Novell Inc (http://novell.com)
//
//
/// Delete symbol from the table
/// </summary>
internal void Remove (Symbol key)
- {
+ {
Binder e = (Binder) dict [key];
if (e != null)
if (e.Tail != null)
((Hashtable) locals.Peek ()).Add (name, o);
}
+ internal DictionaryEntry [] LocalsAtDepth (int depth)
+ {
+ object [] hashes = new object [locals.Count];
+ locals.CopyTo (hashes, 0);
+ Hashtable hash = (Hashtable) hashes [locals.Count - depth - 1];
+ DictionaryEntry [] _locals = new DictionaryEntry [hash.Count];
+ hash.CopyTo (_locals, 0);
+ return _locals;
+ }
+ }
+
+
+ //
+ // Lookup table with namespace context.
+ //
+ internal class Environment {
+
+ private Hashtable namespaces;
+
+ internal Environment ()
+ {
+ namespaces = new Hashtable ();
+
+ //
+ // global variables identification table
+ //
+ namespaces.Add (String.Empty, new IdentificationTable ());
+ }
+
+ internal Environment (ScriptBlock [] blocks)
+ : this ()
+ {
+ //
+ // FIXME: when we implement the package stm. For each package
+ // name we must add a identification table that will store
+ // id's defined inside it.
+ //
+
+ //
+ // integrate the builtin functions, objects, ...
+ //
+ BuildGlobalEnv ();
+ }
+
+ //
+ // retrieves the identification table for the ns namespace
+ //
+ internal IdentificationTable GetIdentificationTable (string ns)
+ {
+ return (IdentificationTable) namespaces [ns];
+ }
+
+ internal bool Contains (string ns, Symbol key)
+ {
+ IdentificationTable symbols = (IdentificationTable) namespaces [ns];
+
+ if (symbols == null)
+ return false;
+
+ return symbols.Contains (key);
+ }
+
+ internal object Get (string ns, Symbol key)
+ {
+ IdentificationTable symbols = (IdentificationTable) namespaces [ns];
+
+ if (symbols == null)
+ return null;
+
+ return symbols.Get (key);
+ }
+
+ internal void Enter (string ns, Symbol key, object value)
+ {
+ IdentificationTable symbols = (IdentificationTable) namespaces [ns];
+
+ if (symbols == null)
+ throw new Exception (ns + " does not exist");
+
+ symbols.Enter (key, value);
+ }
+
+ internal void Remove (string ns, Symbol key)
+ {
+ IdentificationTable symbols = (IdentificationTable) namespaces [ns];
+
+ if (symbols == null)
+ throw new Exception (ns + " does not exist");
+
+ symbols.Remove (key);
+ }
+
+ internal void BeginScope (string ns)
+ {
+ IdentificationTable symbols = (IdentificationTable) namespaces [ns];
+
+ if (symbols == null)
+ throw new Exception (ns + " does not exist");
+
+ symbols.BeginScope ();
+ }
+
+ internal void BeginScope (string ns, bool catchScope)
+ {
+ IdentificationTable symbols = (IdentificationTable) namespaces [ns];
+
+ if (symbols == null)
+ throw new Exception (ns + " does not exist");
+
+ symbols.BeginScope (catchScope);
+ }
+
+ internal void EndScope (string ns)
+ {
+ IdentificationTable symbols = (IdentificationTable) namespaces [ns];
+
+ if (symbols == null)
+ throw new Exception (ns + " does not exist");
+
+ symbols.EndScope ();
+ }
+
+ internal object [] CurrentLocals (string ns)
+ {
+ IdentificationTable symbols = (IdentificationTable) namespaces [ns];
+
+ if (symbols == null)
+ throw new Exception (ns + " does not exist");
+
+ return symbols.CurrentLocals;
+ }
+
+ internal int Depth (string ns)
+ {
+ IdentificationTable symbols = (IdentificationTable) namespaces [ns];
+
+ if (symbols == null)
+ throw new Exception (ns + " does not exist");
+
+ return symbols.depth;
+ }
+
+ internal bool InCurrentScope (string ns, Symbol id)
+ {
+ IdentificationTable symbols = (IdentificationTable) namespaces [ns];
+
+ if (symbols == null)
+ throw new Exception (ns + " does not exist");
+
+ return symbols.InCurrentScope (id);
+ }
+
+ internal bool CatchScope (string ns)
+ {
+ IdentificationTable symbols = (IdentificationTable) namespaces [ns];
+
+ if (symbols == null)
+ throw new Exception (ns + " does not exist");
+
+ return symbols.CatchScope;
+ }
+
internal void BuildGlobalEnv ()
{
//
// built in print function
//
if (SemanticAnalyser.print)
- Enter (Symbol.CreateSymbol ("print"), new BuiltIn ("print", false, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("print"), new BuiltIn ("print", false, true));
/* value properties of the Global Object */
- Enter (Symbol.CreateSymbol ("NaN"), new BuiltIn ("NaN", false, false));
- Enter (Symbol.CreateSymbol ("Infinity"), new BuiltIn ("Infinity", false, false));
- Enter (Symbol.CreateSymbol ("undefined"), new BuiltIn ("undefined", false, false));
- Enter (Symbol.CreateSymbol ("null"), new BuiltIn ("null", false, false));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("NaN"), new BuiltIn ("NaN", false, false));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("Infinity"), new BuiltIn ("Infinity", false, false));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("undefined"), new BuiltIn ("undefined", false, false));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("null"), new BuiltIn ("null", false, false));
/* function properties of the Global Object */
object [] custom_attrs;
custom_attrs = mi.GetCustomAttributes (typeof (JSFunctionAttribute), false);
foreach (JSFunctionAttribute attr in custom_attrs)
if (attr.IsBuiltIn)
- Enter (Symbol.CreateSymbol (mi.Name), new BuiltIn (SemanticAnalyser.ImplementationName (attr.BuiltIn.ToString ()), false, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol (mi.Name), new BuiltIn (SemanticAnalyser.ImplementationName (attr.BuiltIn.ToString ()), false, true));
}
/* built in objects */
- Enter (Symbol.CreateSymbol ("Object"), new BuiltIn ("Object", true, true));
- Enter (Symbol.CreateSymbol ("Function"), new BuiltIn ("Function", true, true));
- Enter (Symbol.CreateSymbol ("Array"), new BuiltIn ("Array", true, true));
- Enter (Symbol.CreateSymbol ("String"), new BuiltIn ("String", true, true));
- Enter (Symbol.CreateSymbol ("Boolean"), new BuiltIn ("Boolean", true, true));
- Enter (Symbol.CreateSymbol ("Number"), new BuiltIn ("Number", true, true));
- Enter (Symbol.CreateSymbol ("Math"), new BuiltIn ("Math", false, false));
- Enter (Symbol.CreateSymbol ("Date"), new BuiltIn ("Date", true, true));
- Enter (Symbol.CreateSymbol ("RegExp"), new BuiltIn ("RegExp", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("Object"), new BuiltIn ("Object", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("Function"), new BuiltIn ("Function", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("Array"), new BuiltIn ("Array", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("String"), new BuiltIn ("String", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("Boolean"), new BuiltIn ("Boolean", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("Number"), new BuiltIn ("Number", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("Math"), new BuiltIn ("Math", false, false));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("Date"), new BuiltIn ("Date", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("RegExp"), new BuiltIn ("RegExp", true, true));
/* built in Error objects */
- Enter (Symbol.CreateSymbol ("Error"), new BuiltIn ("Error", true, true));
- Enter (Symbol.CreateSymbol ("EvalError"), new BuiltIn ("EvalError", true, true));
- Enter (Symbol.CreateSymbol ("RangeError"), new BuiltIn ("RangeError", true, true));
- Enter (Symbol.CreateSymbol ("ReferenceError"), new BuiltIn ("ReferenceError", true, true));
- Enter (Symbol.CreateSymbol ("SyntaxError"), new BuiltIn ("SyntaxError", true, true));
- Enter (Symbol.CreateSymbol ("TypeError"), new BuiltIn ("TypeError", true, true));
- Enter (Symbol.CreateSymbol ("URIError"), new BuiltIn ("URIError", true, true));
- }
-
- internal DictionaryEntry [] LocalsAtDepth (int depth)
- {
- object [] hashes = new object [locals.Count];
- locals.CopyTo (hashes, 0);
- Hashtable hash = (Hashtable) hashes [locals.Count - depth - 1];
- DictionaryEntry [] _locals = new DictionaryEntry [hash.Count];
- hash.CopyTo (_locals, 0);
- return _locals;
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("Error"), new BuiltIn ("Error", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("EvalError"), new BuiltIn ("EvalError", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("RangeError"), new BuiltIn ("RangeError", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("ReferenceError"), new BuiltIn ("ReferenceError", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("SyntaxError"), new BuiltIn ("SyntaxError", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("TypeError"), new BuiltIn ("TypeError", true, true));
+ Enter (SemanticAnalyser.GlobalNamespace, Symbol.CreateSymbol ("URIError"), new BuiltIn ("URIError", true, true));
}
}
}
// Author: Cesar Octavio Lopez Nataren
//
// (C) 2003, Cesar Octavio Lopez Nataren, <cesar@ciencias.unam.mx>
-// (C) 2005 Copyright , Novell Inc (http://novell.com)
+// Copyright (C) 2005 , Novell Inc (http://novell.com)
//
//
{
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
if (InFunction) {
string err = location.SourceName + "(" + location.LineNumber + ",0) : " +
return LateBinding.HasObjectProperty (obj, key);
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
throw new NotImplementedException ();
}
throw new JScriptException (JSError.TypeMismatch);
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
throw new NotImplementedException ();
}
{
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
return true;
}
{
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
return true;
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
- return Resolve (context);
+ return Resolve (env);
}
}
this.Value = val;
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
return true;
this.elems = elems;
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
- return Resolve (context);
+ return Resolve (env);
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
bool r = true;
foreach (AST ast in elems)
- r &= ast.Resolve (context);
+ r &= ast.Resolve (env);
return r;
}
property_name = obj.ToString ();
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
- return exp.Resolve (context);
+ return exp.Resolve (env);
}
internal override void Emit (EmitContext ec)
this.flags = flags;
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
return true;
}
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
- return Resolve (context);
+ return Resolve (env);
}
internal override void Emit (EmitContext ec)
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
throw new NotImplementedException ();
}
public static void JScriptPackage (string rootName, VsaEngine engine)
{}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
throw new NotImplementedException ();
}
//
using System.Collections;
+using Microsoft.Vsa;
using System.IO;
using System;
TokenStream ts;
bool ok; // did the parse encounter an error?
- ScriptBlock current_script_or_fn;
int nesting_of_function;
int nesting_of_with;
bool allow_member_expr_as_function_name;
internal Parser ()
{
}
-
+
internal Parser (ArrayList code_items)
{
this.code_items = code_items;
}
-
- internal AST ParseAll ()
+
+ internal ScriptBlock [] ParseAll ()
{
- ScriptBlock block = new ScriptBlock ();
+ int i = 0, n = code_items.Count;
+ ScriptBlock [] blocks = new ScriptBlock [n];
foreach (VsaCodeItem item in code_items)
- block.Add (Parse (item.SourceText, item.Name, 0));
+ blocks [i++] = Parse (item.SourceText, item.Name, 0);
- return block;
+ return blocks;
}
internal Decompiler CreateDecompiler ()
/// </summary>
///
/// <remarks>
- /// return an AST representing the parsed program.
- /// If the parse fails, null will be returned.
+ /// return an ScriptBlock representing the parsed program
+ /// that corresponds to a source file.
+ /// If the parse fails, null will be returned.
/// </remarks>
- internal AST Parse (string source_string, string source_location, int line_number)
+ internal ScriptBlock Parse (string source_string, string source_location, int line_number)
{
ts = new TokenStream (null, source_string, source_location, line_number);
try {
throw new ParserException ();
}
- AST Parse ()
+ ScriptBlock Parse ()
{
decompiler = CreateDecompiler ();
- current_script_or_fn = new ScriptBlock (new Location (ts.SourceName, ts.LineNumber));
+ ScriptBlock current_script_or_fn = new ScriptBlock (new Location (ts.SourceName, ts.LineNumber));
decompiler.GetCurrentOffset ();
decompiler.AddToken (Token.SCRIPT);
ok = true;
{
++nesting_of_function;
Block pn = new Block (parent, new Location (ts.SourceName, ts.LineNumber));
+
try {
int tt;
while ((tt = ts.PeekToken ()) > Token.EOF && tt != Token.RC) {
if (name != "")
decompiler.AddName (name);
- ScriptBlock saved_script_or_fn = current_script_or_fn;
int saved_nesting_of_with = nesting_of_with;
nesting_of_with = 0;
decompiler.AddEOL (Token.SEMI);
}
} finally {
- current_script_or_fn = saved_script_or_fn;
nesting_of_with = saved_nesting_of_with;
}
// FIXME
pn = fn;
pn = new Assign (null, member_expr, pn, JSToken.Assign, false, new Location (ts.SourceName, ts.LineNumber));
+
// FIXME, research about createExprStatement
if (ft != FunctionType.Expression)
;
if (tt == Token.IF) {
skip_semi = true;
-
decompiler.AddToken (Token.IF);
-
AST cond = Condition (parent);
decompiler.AddEOL (Token.LC);
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
throw new NotImplementedException ();
}
return value - 1;
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
- return operand.Resolve (context);
+ return operand.Resolve (env);
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
if (operand is Exp)
- return ((Exp) operand).Resolve (context, no_effect);
+ return ((Exp) operand).Resolve (env, no_effect);
else
- return operand.Resolve (context);
+ return operand.Resolve (env);
}
internal override void Emit (EmitContext ec)
return exp.ToString ();
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
throw new NotImplementedException ();
}
}
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
if (left != null)
- left.Resolve (context);
+ left.Resolve (env);
if (right != null)
- right.Resolve (context);
+ right.Resolve (env);
return true;
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
- return Resolve (context);
+ return Resolve (env);
}
internal override void Emit (EmitContext ec)
//
-// ScriptBlock.cs:
+// ScriptBlock.cs: Represents a file, which maps to a 'JScript N' class in the assembly.
//
// Author: Cesar Octavio Lopez Nataren
//
// (C) Cesar Octavio Lopez Nataren, <cesar@ciencias.unam.mx>
+// Copyright (C) 2005 Novell Inc (http://novell.com)
//
//
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System;
+using System.Reflection;
+using Microsoft.JScript.Vsa;
+using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
+
namespace Microsoft.JScript {
- public class ScriptBlock : AST {
+ public class ScriptBlock : AST, ICanModifyContext {
+ private TypeBuilder type_builder;
+ private MethodBuilder global_code;
+ private ILGenerator global_code_ig;
+ private EmitContext base_emit_context;
internal Block src_elems;
+
+ internal MethodBuilder GlobalCode {
+ get { return global_code; }
+ }
+
+ internal TypeBuilder TypeBuilder {
+ get { return type_builder; }
+ }
internal ScriptBlock ()
: base (null, null)
src_elems.Add (e);
}
+ internal void EmitDecls (ModuleBuilder mb)
+ {
+ base_emit_context = new EmitContext (type_builder, mb, global_code_ig);
+ EmitInitGlobalCode ();
+ ((ICanModifyContext) src_elems).EmitDecls (base_emit_context);
+ }
+
+ internal void Emit ()
+ {
+ Emit (base_emit_context);
+ EmitEndGlobalCode ();
+ }
+
internal override void Emit (EmitContext ec)
{
+ EmitTypeCtr ();
src_elems.Emit (ec);
}
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ ((ICanModifyContext) src_elems).PopulateContext (env, ns);
+ }
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ }
+
+ internal override bool Resolve (Environment env)
+ {
+ return src_elems.Resolve (env);
+ }
+
+
+ internal void InitTypeBuilder (ModuleBuilder moduleBuilder, string next_type)
+ {
+ type_builder = moduleBuilder.DefineType (next_type, TypeAttributes.Public);
+ type_builder.SetParent (typeof (GlobalScope));
+ type_builder.SetCustomAttribute (new CustomAttributeBuilder
+ (typeof (CompilerGlobalScopeAttribute).GetConstructor (new Type [] {}), new object [] {}));
+ }
+
+ internal void CreateType ()
+ {
+ type_builder.CreateType ();
+ }
+
+ internal void EmitTypeCtr ()
+ {
+ ConstructorBuilder cons_builder;
+ cons_builder = type_builder.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);
+ }
+
+ internal void InitGlobalCode ()
{
- return src_elems.Resolve (context);
+ global_code = type_builder.DefineMethod ("Global Code", MethodAttributes.Public,
+ typeof (System.Object), new Type [] {});
+ global_code_ig = global_code.GetILGenerator ();
+ }
+
+ private void EmitInitGlobalCode ()
+ {
+ ILGenerator ig = global_code_ig;
+
+ 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)}));
+ }
+
+ private void EmitEndGlobalCode ()
+ {
+ ILGenerator ig = global_code_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);
}
}
}
internal static bool print = true;
internal static bool allow_member_expr_as_function_name;
- static IdentificationTable context;
+ static Environment env;
static IdentificationTable label_set;
private static Hashtable obj_ctrs;
internal static Hashtable methods_with_eval = new Hashtable ();
internal static Hashtable methods_with_outter_scope_refs = new Hashtable ();
internal static Hashtable methods_with_vars_used_nested = new Hashtable ();
+ internal static Environment Ocurrences = new Environment ();
//
// Type to GlobalObject
internal static bool NoFast = true;
private static Assembly [] assemblies;
+ private static readonly string global_namespace = String.Empty;
+ internal static string GlobalNamespace {
+ get { return global_namespace; }
+ }
+
static SemanticAnalyser ()
{
label_set = new IdentificationTable ();
return name.Substring (i + 1);
}
- internal static bool Run (ScriptBlock prog, Assembly [] ref_items)
+ internal static bool Run (ScriptBlock [] blocks, Assembly [] ref_items)
{
- assemblies = ref_items;
+ assemblies = ref_items;
ComputeNamespaces ();
+ env = new Environment (blocks);
+ bool r = true;
+
+ foreach (ScriptBlock script_block in blocks)
+ ((ICanModifyContext) script_block).PopulateContext (env, String.Empty);
- context = new IdentificationTable ();
- context.BuildGlobalEnv ();
- return prog.Resolve (context);
+ foreach (ScriptBlock script_block in blocks)
+ r &= script_block.Resolve (env);
+
+ return r;
}
static int anon_method_counter = -1;
// Cesar Octavio Lopez Nataren
//
// (C) 2003, 2004 Cesar Octavio Lopez Nataren, <cesar@ciencias.unam.mx>
+// Copyright (C) 2005 Novell Inc (http://novell.com)
//
//
namespace Microsoft.JScript {
- internal class If : AST {
+ internal interface ICanModifyContext {
+ //
+ // Populate the symbol table before resolving references
+ //
+ void PopulateContext (Environment env, string ns);
+ void EmitDecls (EmitContext ec);
+ }
+
+ internal class If : AST, ICanModifyContext {
internal AST cond, true_stm, false_stm;
return sb.ToString ();
}
+
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ if (true_stm is ICanModifyContext)
+ ((ICanModifyContext) true_stm).PopulateContext (env, ns);
+
+ if (false_stm is ICanModifyContext)
+ ((ICanModifyContext) false_stm).PopulateContext (env, ns);
+ }
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ if (true_stm is ICanModifyContext)
+ ((ICanModifyContext) true_stm).EmitDecls (ec);
+
+ if (false_stm is ICanModifyContext)
+ ((ICanModifyContext) false_stm).EmitDecls (ec);
+ }
+
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (cond != null)
if (cond is Exp)
- r &= ((Exp) cond).Resolve (context, false);
+ r &= ((Exp) cond).Resolve (env, false);
if (true_stm != null)
if (true_stm is Exp)
- r &= ((Exp) true_stm).Resolve (context, true);
+ r &= ((Exp) true_stm).Resolve (env, true);
else
- r &= true_stm.Resolve (context);
+ r &= true_stm.Resolve (env);
if (false_stm != null)
if (false_stm is Exp)
- r &= ((Exp) false_stm).Resolve (context, true);
+ r &= ((Exp) false_stm).Resolve (env, true);
else
- r &= false_stm.Resolve (context);
+ r &= false_stm.Resolve (env);
return r;
}
this.label += label;
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
if (!InLoop)
throw new Exception ("A continue can't be outside a iteration stm");
this.label += label;
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
if (!InLoop && !InSwitch)
throw new Exception ("A break statement can't be outside a switch or iteration stm");
return String.Empty;
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
if (!InFunction)
throw new Exception ("error JS1018: 'return' statement outside of function");
if (expression != null) {
OnNotVoidReturn (null);
- return expression.Resolve (context);
+ return expression.Resolve (env);
} else
return true;
}
}
}
- internal class DoWhile : AST {
+ internal class DoWhile : AST, ICanModifyContext {
AST stm, exp;
this.exp = exp;
}
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ if (stm is ICanModifyContext)
+ ((ICanModifyContext) stm).PopulateContext (env, ns);
+ }
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ if (stm is ICanModifyContext)
+ ((ICanModifyContext) stm).EmitDecls (ec);
+ }
+
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (stm != null)
- r &= stm.Resolve (context);
+ r &= stm.Resolve (env);
if (exp != null)
- r &= exp.Resolve (context);
+ r &= exp.Resolve (env);
return r;
}
}
- internal class While : AST {
+ internal class While : AST, ICanModifyContext {
AST exp, stm;
internal While (Location location)
this.stm = stm;
}
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ if (stm is ICanModifyContext)
+ ((ICanModifyContext) stm).PopulateContext (env, ns);
+ }
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ if (stm is ICanModifyContext)
+ ((ICanModifyContext) stm).EmitDecls (ec);
+ }
+
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (exp != null)
if (exp is Exp)
- r &= ((Exp) exp).Resolve (context, false);
+ r &= ((Exp) exp).Resolve (env, false);
else
- r &= exp.Resolve (context);
+ r &= exp.Resolve (env);
if (stm != null)
- r &= stm.Resolve (context);
+ r &= stm.Resolve (env);
return r;
}
}
}
- internal class For : AST {
+ internal class For : AST, ICanModifyContext {
AST [] exprs = new AST [3];
AST stms;
stms = body;
}
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ foreach (AST ast in exprs)
+ if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).PopulateContext (env, ns);
+
+ if (stms is ICanModifyContext)
+ ((ICanModifyContext) stms).PopulateContext (env, ns);
+ }
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ foreach (AST ast in exprs)
+ if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).EmitDecls (ec);
+
+ if (stms is ICanModifyContext)
+ ((ICanModifyContext) stms).EmitDecls (ec);
+ }
+
+ internal override bool Resolve (Environment env)
{
bool r = true;
foreach (AST ast in exprs)
- if (ast is VariableStatement)
- ((VariableStatement) ast).PopulateContext (context);
- else
- r &= ast.Resolve (context);
+ r &= ast.Resolve (env);
if (stms != null)
- r &= stms.Resolve (context);
+ r &= stms.Resolve (env);
return true;
}
/* emit init expr */
tmp = exprs [0];
- if (tmp != null) {
- if (tmp is VariableStatement) {
- VariableStatement stm = (VariableStatement) tmp;
- stm.EmitVariableDecls (ec);
- }
+ if (tmp != null)
tmp.Emit (ec);
- }
+
ec.LoopBegin = ig.DefineLabel ();
ec.LoopEnd = ig.DefineLabel ();
}
}
- internal class Switch : AST {
+ internal class Switch : AST, ICanModifyContext {
internal AST exp;
internal ArrayList case_clauses;
sec_case_clauses.Add (clause);
}
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ foreach (AST ast in case_clauses)
+ if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).PopulateContext (env, ns);
+
+ foreach (AST ast in default_clauses)
+ if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).PopulateContext (env, ns);
+
+ foreach (AST ast in sec_case_clauses)
+ if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).PopulateContext (env, ns);
+ }
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ foreach (AST ast in case_clauses)
+ if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).EmitDecls (ec);
+
+ foreach (AST ast in default_clauses)
+ if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).EmitDecls (ec);
+
+ foreach (AST ast in sec_case_clauses)
+ if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).EmitDecls (ec);
+ }
+
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (exp != null)
- r &= exp.Resolve (context);
+ r &= exp.Resolve (env);
if (case_clauses != null)
foreach (Clause c in case_clauses)
- r &= c.Resolve (context);
+ r &= c.Resolve (env);
if (default_clauses != null)
foreach (AST dc in default_clauses)
- r &= dc.Resolve (context);
+ r &= dc.Resolve (env);
if (sec_case_clauses != null)
foreach (Clause sc in sec_case_clauses)
- r &= sc.Resolve (context);
+ r &= sc.Resolve (env);
return r;
}
}
}
- internal class Clause : AST {
+ internal class Clause : AST, ICanModifyContext {
internal AST exp;
internal ArrayList stm_list;
internal Label matched_block;
stm_list.Add (stm);
}
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ foreach (AST ast in stm_list)
+ if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).PopulateContext (env, ns);
+ }
+
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ foreach (AST ast in stm_list)
+ if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).EmitDecls (ec);
+ }
+
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (exp != null)
- r &= exp.Resolve (context);
+ r &= exp.Resolve (env);
foreach (AST ast in stm_list)
- r &= ast.Resolve (context);
+ r &= ast.Resolve (env);
return r;
}
}
}
- internal class Catch : AST {
+ internal class Catch : AST, ICanModifyContext {
internal string id;
internal AST catch_cond;
internal AST stms;
this.stms = stms;
}
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ if (stms is ICanModifyContext)
+ ((ICanModifyContext) stms).PopulateContext (env, ns);
+ }
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ if (stms is ICanModifyContext)
+ ((ICanModifyContext) stms).EmitDecls (ec);
+ }
+
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (stms != null)
- r &= stms.Resolve (context);
+ r &= stms.Resolve (env);
return r;
}
}
}
- internal class Labelled : AST {
+ internal class Labelled : AST, ICanModifyContext {
string name;
Label init_addrs;
Label end_addrs;
this.location = location;
}
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ if (stm is ICanModifyContext)
+ ((ICanModifyContext) stm).PopulateContext (env, ns);
+ }
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ if (stm is ICanModifyContext)
+ ((ICanModifyContext) stm).EmitDecls (ec);
+ }
+
+ internal override bool Resolve (Environment env)
{
try {
SemanticAnalyser.AddLabel (name, this);
throw new Exception ("error JS1025: Label redefined");
}
if (stm != null)
- stm.Resolve (context);
+ stm.Resolve (env);
SemanticAnalyser.RemoveLabel (name);
return true;
}
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (left != null)
- r &= left.Resolve (context);
+ r &= left.Resolve (env);
if (right != null)
- r &= right.Resolve (context);
+ r &= right.Resolve (env);
return r;
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
- return Resolve (context);
+ return Resolve (env);
}
internal override void Emit (EmitContext ec)
str = s;
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
return true;
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
return true;
return new JScriptException (Convert.ToString (value));
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
- return expression.Resolve (context);
+ return expression.Resolve (env);
}
internal override void Emit (EmitContext ec)
namespace Microsoft.JScript {
- public sealed class Try : AST {
+ public sealed class Try : AST, ICanModifyContext {
internal FieldBuilder field_info;
internal LocalBuilder local_builder;
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (guarded_block != null)
- r &= guarded_block.Resolve (context);
-
+ r &= guarded_block.Resolve (env);
+
if (catch_blocks != null && catch_blocks.Count > 0) {
foreach (Catch c in catch_blocks) {
- context.BeginScope (true);
- context.Enter (Symbol.CreateSymbol (c.id), c);
- r &= c.Resolve (context);
- context.EndScope ();
+ env.BeginScope (String.Empty, true);
+ env.Enter (String.Empty, Symbol.CreateSymbol (c.id), c);
+ r &= c.Resolve (env);
+ env.EndScope (String.Empty);
}
}
if (finally_block != null)
- r &= finally_block.Resolve (context);
+ r &= finally_block.Resolve (env);
return r;
}
}
ig.EndExceptionBlock ();
}
+
+
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ if (guarded_block is ICanModifyContext)
+ ((ICanModifyContext) guarded_block).PopulateContext (env, ns);
+
+ foreach (AST ast in catch_blocks)
+ if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).PopulateContext (env, ns);
+
+ if (finally_block is ICanModifyContext)
+ ((ICanModifyContext) finally_block).PopulateContext (env, ns);
+ }
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ if (guarded_block is ICanModifyContext)
+ ((ICanModifyContext) guarded_block).EmitDecls (ec);
+
+ foreach (AST ast in catch_blocks)
+ if (ast is ICanModifyContext)
+ ((ICanModifyContext) ast).EmitDecls (ec);
+
+ if (finally_block is ICanModifyContext)
+ ((ICanModifyContext) finally_block).EmitDecls (ec);
+ }
}
}
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
throw new NotImplementedException ();
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
- return Resolve (context);
+ return Resolve (env);
}
internal override void Emit (EmitContext ec)
namespace Microsoft.JScript {
- internal class VariableDeclaration : AST {
+ internal class VariableDeclaration : AST, ICanModifyContext {
internal string id;
internal Type type;
return "var " + sb.ToString ();
}
- internal void EmitDecl (EmitContext ec)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ Symbol _id = Symbol.CreateSymbol (id);
+
+ if (!env.InCurrentScope (ns, _id))
+ env.Enter (ns, _id, this);
+ }
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
{
object var;
}
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (val != null)
- r = val.Resolve (context);
- lexical_depth = context.depth;
+ r = val.Resolve (env);
+ lexical_depth = env.Depth (String.Empty);
func_decl = GetContainerFunction;
return r;
}
namespace Microsoft.JScript {
- internal class VariableStatement : AST {
+ internal class VariableStatement : AST, ICanModifyContext {
internal ArrayList var_decls;
return sb.ToString ();
}
- internal void EmitVariableDecls (EmitContext ec)
+ void ICanModifyContext.EmitDecls (EmitContext ec)
{
- int n = var_decls.Count;
- for (int i = 0; i < n; i++)
- ((VariableDeclaration) var_decls [i]).EmitDecl (ec);
+ foreach (VariableDeclaration var_decl in var_decls)
+ ((ICanModifyContext) var_decl).EmitDecls (ec);
}
internal override void Emit (EmitContext ec)
((VariableDeclaration) var_decls [i]).Emit (ec);
}
- internal void PopulateContext (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
{
- VariableDeclaration tmp_decl;
- int n = var_decls.Count;
- Symbol id;
-
- for (int i = 0; i < n; i++) {
- tmp_decl = (VariableDeclaration) var_decls [i];
- id = Symbol.CreateSymbol (tmp_decl.id);
- if (context.InCurrentScope (id))
- continue;
- context.Enter (id, tmp_decl);
- }
+ foreach (VariableDeclaration var_decl in var_decls)
+ ((ICanModifyContext) var_decl).PopulateContext (env, ns);
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
VariableDeclaration tmp_decl;
int n = var_decls.Count;
for (int i = 0; i < n; i++) {
tmp_decl = (VariableDeclaration) var_decls [i];
- r &= tmp_decl.Resolve (context);
+ r &= tmp_decl.Resolve (env);
}
return r;
}
namespace Microsoft.JScript {
- public class With : AST {
+ public class With : AST, ICanModifyContext {
AST exp, stm;
return withObj;
}
- internal override bool Resolve (IdentificationTable context)
+ void ICanModifyContext.PopulateContext (Environment env, string ns)
+ {
+ if (stm is ICanModifyContext)
+ ((ICanModifyContext) stm).PopulateContext (env, ns);
+ }
+
+ void ICanModifyContext.EmitDecls (EmitContext ec)
+ {
+ if (stm is ICanModifyContext)
+ ((ICanModifyContext) stm).EmitDecls (ec);
+ }
+
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (exp != null)
- r &= exp.Resolve (context);
+ r &= exp.Resolve (env);
if (stm != null)
- r &= stm.Resolve (context);
+ r &= stm.Resolve (env);
return r;
}
// Here the actual IL code generation happens.
//
internal abstract void Emit (EmitContext ec);
-
+
//
// Perform type checks and associates expressions
// with their declarations
//
- internal abstract bool Resolve (IdentificationTable context);
+ internal abstract bool Resolve (Environment env);
internal bool InLoop {
get {
public abstract class Exp : AST {
internal bool no_effect;
- internal abstract bool Resolve (IdentificationTable context, bool no_effect);
+ internal abstract bool Resolve (Environment env, bool no_effect);
internal Exp (AST parent, Location location)
: base (parent, location)
return sb.ToString ();
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
bool r = false;
Binary bin = (Binary) operand;
if (oper == JSToken.Delete && bin.AccessField)
this.deletable = bin.IsDeletable (out isCtr);
- bin.Resolve (context);
+ bin.Resolve (env);
} else if (operand is Exp) {
if (oper != JSToken.Increment && oper != JSToken.Decrement)
- r = ((Exp) operand).Resolve (context, no_effect);
+ r = ((Exp) operand).Resolve (env, no_effect);
} else
- r = operand.Resolve (context);
+ r = operand.Resolve (env);
return r;
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
- return Resolve (context);
+ return Resolve (env);
}
internal override void Emit (EmitContext ec)
get { return late_bind; }
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
bool found = true;
if (!found)
late_bind = true;
} else
- found &= left.Resolve (context);
+ found &= left.Resolve (env);
if (right != null)
if (op == JSToken.AccessField && right is IAccessible) {
found &= ((IAccessible) right).ResolveFieldAccess (left);
if (!found)
late_bind = true;
} else
- found &= right.Resolve (context);
+ found &= right.Resolve (env);
return found;
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
- return Resolve (context);
+ return Resolve (env);
}
- public bool ResolveAssign (IdentificationTable context, AST right_side)
+ public bool ResolveAssign (Environment env, AST right_side)
{
if (op == JSToken.LeftBracket || op == JSToken.AccessField) {
this.no_effect = false;
this.assign = true;
this.right_side = right_side;
- return Resolve (context);
+ return Resolve (env);
} else
throw new Exception (location.SourceName + " (" + location.LineNumber + ",0): error JS5008: Illegal assignment");
}
return sb.ToString ();
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (cond_exp != null)
- r &= cond_exp.Resolve (context);
+ r &= cond_exp.Resolve (env);
if (true_exp != null)
- r &= true_exp.Resolve (context);
+ r &= true_exp.Resolve (env);
if (false_exp != null)
- r &= false_exp.Resolve (context);
+ r &= false_exp.Resolve (env);
return r;
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
- return Resolve (context);
+ return Resolve (env);
}
internal override void Emit (EmitContext ec)
args.Add (arg);
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
bool r = true;
if (member_exp != null) {
if (member_exp is Identifier) {
- member_exp.Resolve (context);
- binding = context.Get ((member_exp as Identifier).name);
+ member_exp.Resolve (env);
+ binding = env.Get (String.Empty, (member_exp as Identifier).name);
bind_type = binding.GetType ();
if (bind_type == typeof (BuiltIn)) {
}
}
} else if (member_exp is Binary) {
- member_exp.Resolve (context);
+ member_exp.Resolve (env);
Binary bin = (Binary) member_exp;
if (bin.AccessField)
binding = bin.Binding;
if (binding is MethodInfo)
NeedThis ((MethodInfo) binding);
} else
- r &= member_exp.Resolve (context);
+ r &= member_exp.Resolve (env);
args.BoundToMethod = binding;
if (args != null)
- r &= args.Resolve (context);
+ r &= args.Resolve (env);
} else
throw new Exception ("Call.Resolve, member_exp can't be null");
return r;
need_this = SemanticAnalyser.Needs (JSFunctionAttributeEnum.HasThisObject, method);
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
- return Resolve (context);
+ return Resolve (env);
}
internal override void Emit (EmitContext ec)
} else if (bind_type == typeof (FunctionDeclaration) || bind_type == typeof (FunctionExpression)) {
Function function = binding as Function;
MethodBuilder method = (MethodBuilder) TypeManager.Get (function.func_obj.name);
-
+
if (SemanticAnalyser.MethodContainsEval (function.func_obj.name) ||
SemanticAnalyser.MethodReferenceOutterScopeVar (function.func_obj.name) ||
SemanticAnalyser.MethodVarsUsedNested (function.func_obj.name)) {
return name.Value;
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
- bool contained = context.Contains (this.name);
+ bool contained = env.Contains (String.Empty, this.name);
if (contained) {
- binding = (AST) context.Get (this.name);
+ binding = (AST) env.Get (String.Empty, this.name);
if (binding is VariableDeclaration) {
VariableDeclaration decl = (VariableDeclaration) binding;
- lexical_difference = context.depth - decl.lexical_depth;
+ lexical_difference = env.Depth (String.Empty) - decl.lexical_depth;
no_field = decl.lexical_depth != 0;
- if (no_field && lexical_difference > 0 && !context.CatchScope) {
+
+ if (no_field && lexical_difference > 0 && !env.CatchScope (String.Empty)) {
Function container_func = GetContainerFunction;
SemanticAnalyser.AddMethodReferenceOutterScopeVar (container_func.func_obj.name, decl);
- context.Enter (Symbol.CreateSymbol (decl.id), decl);
+ env.Enter (String.Empty, Symbol.CreateSymbol (decl.id), decl);
SemanticAnalyser.AddMethodVarsUsedNested (decl.GetContainerFunction.func_obj.name, decl);
}
}
} else if (SemanticAnalyser.NoFast) {
undeclared = true;
Console.WriteLine ("warning JS1135: Variable '" + name + "' has not been declared");
- } else
+ } else {
+ //
+ // Identifier not into stand-alone JScript, we'll search into
+ // referenced assemblies and namespaces
+ //
throw new Exception (location.SourceName + "(" + location.LineNumber +
",0) : error JS1135: Variable '" + name + "' has not been declared");
+ }
return true;
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
- return Resolve (context);
+ return Resolve (env);
}
- public bool ResolveAssign (IdentificationTable context, AST right_side)
+ public bool ResolveAssign (Environment env, AST right_side)
{
this.assign = true;
this.no_effect = false;
this.right_side = right_side;
if (name.Value != String.Empty)
- return Resolve (context);
+ return Resolve (env);
return true;
}
}
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
AST tmp;
bool r = true;
tmp = (AST) elems [i];
if (tmp != null)
if (tmp is Exp)
- r &= ((Exp) tmp).Resolve (context, false);
- r &= tmp.Resolve (context);
+ r &= ((Exp) tmp).Resolve (env, false);
+ else
+ r &= tmp.Resolve (env);
}
return r;
}
} else return String.Empty;
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
int i, n;
object e;
e = exprs [i];
if (e is Exp)
if (e is Assign)
- r &= ((Assign) e).Resolve (context);
+ r &= ((Assign) e).Resolve (env);
else
- r &= ((Exp) e).Resolve (context, true);
+ r &= ((Exp) e).Resolve (env, true);
}
e = exprs [n];
if (e is Exp)
if (e is Assign)
- r &= ((Assign) e).Resolve (context);
+ r &= ((Assign) e).Resolve (env);
else
- r &= ((Exp) e).Resolve (context, no_effect);
+ r &= ((Exp) e).Resolve (env, no_effect);
else
- ((AST) e).Resolve (context);
+ ((AST) e).Resolve (env);
return r;
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
this.no_effect = no_effect;
- return Resolve (context);
+ return Resolve (env);
}
internal override void Emit (EmitContext ec)
// after calling Resolve, left contains all the
// information about the assignment
//
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
bool r;
if (left is IAssignable)
- r = ((IAssignable) left).ResolveAssign (context, right);
+ r = ((IAssignable) left).ResolveAssign (env, right);
else
throw new Exception (location.SourceName + " (" + location.LineNumber + ",0): error JS5008: Illegal assignment");
if (right is Exp)
- r &=((Exp) right).Resolve (context, false);
+ r &=((Exp) right).Resolve (env, false);
else
- r &= right.Resolve (context);
+ r &= right.Resolve (env);
return r;
}
- internal override bool Resolve (IdentificationTable context, bool no_effect)
+ internal override bool Resolve (Environment env, bool no_effect)
{
return true;
}
if (op == JSToken.Assign) {
if (is_embedded) {
Console.WriteLine ("embedded assignments not supported yet");
- Environment.Exit (-1);
+ System.Environment.Exit (-1);
}
left.Emit (ec);
} else {
args.Add (arg);
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
bool r = true;
Identifier id = (Identifier) exp;
late_bind = !SemanticAnalyser.is_js_object (id.name.Value);
}
- exp.Resolve (context);
+ exp.Resolve (env);
if (args != null) {
args.InNew = true;
- r &= args.Resolve (context);
+ r &= args.Resolve (env);
}
return r;
}
}
internal interface IAssignable {
- bool ResolveAssign (IdentificationTable context, AST right_side);
+ bool ResolveAssign (Environment env, AST right_side);
}
internal class BuiltIn : AST {
this.allowed_as_func = allowed_as_func;
}
- internal override bool Resolve (IdentificationTable context)
+ internal override bool Resolve (Environment env)
{
return true;
}