/** JavaScript -- DOT NET Javascript Library
* Copyright (C) 2005 John Garrison
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
using System;
using System.Collections;
using System.Diagnostics;
namespace JavaScript
{
public enum Op
{
NOP,
POP,
PUSH,
ROT,
ROT3,
DUP,
CLEAR_STK,
ADD,
SUB,
NEGATE,
MULT,
DIV,
MOD,
AND,
BINAND,
OR,
BINOR,
XOR,
COMPL,
NOT,
LT,
GT,
LTEQ,
GTEQ,
EQ,
NEQ,
NEWPROP,
NEWITER,
ITERNEXT,
ASSIGN,
STORE,
REF_PROP,
CLONE,
THIS,
MARK,
UNMARK,
PUSH_CONTEXT,
RVALUE,
DEREF_PROP,
ENTER,
LEAVE,
CALL,
RETURN,
NEW,
DEFTYPE,
DEFARG,
DEFBODY,
NATIVE,
DEBUGGER,
JMPZ,
JMP,
BREAK,
SETBREAK,
JMPNZ,
DISPATCH
}
public enum Mode
{
IM, // command arg hold a value
INDIR, // argument holds the name of a property to load
STK_IM, // value from the stack
STK_INDIR // stack hold the name of a property
}
public class Command
{
public Command( Op opcode, Mode mode, int linenum )
{
m_opcode = opcode;
m_line = (linenum < 0) ? 0 : linenum;
m_mode = mode;
}
public Command( Op opcode, Mode mode, JsObject arg, int linenum ) : this ( opcode, mode, linenum )
{
m_opcode = opcode;
m_arg = arg;
}
public Command( Op opcode, Mode mode, JsObject arg, int linenum, string debugHint ) : this( opcode, mode, arg, linenum )
{
m_debughint = debugHint;
}
public Op OpCode
{
get
{
return m_opcode;
}
}
public JsObject Arg
{
get
{
return m_arg;
}
set
{
m_arg = value;
}
}
public Mode AddressMode
{
get
{
return m_mode;
}
}
public override string ToString()
{
string ret = m_opcode.ToString();
if ( m_arg != null )
{
ret += ":" + m_arg.ToString();
}
if ( m_debughint != null )
{
ret += " (" + m_debughint + ":" + m_line.ToString() + ")";
}
return ret;
}
public Command Dup()
{
if ( m_arg == null )
{
return new Command( m_opcode, m_mode, TypeUndefined.Instance, m_line, m_debughint );
}
else
{
//return new Command( m_opcode, m_mode, m_arg.Dup(), m_line, m_debughint );
return new Command(m_opcode, m_mode, m_arg, m_line, m_debughint);
}
}
public int LineNumber
{
get
{
return m_line;
}
}
public string DebugHint
{
get { return m_debughint; }
set { m_debughint = value; }
}
public object Deref( StackFrame ctx )
{
object ret = null;
switch ( m_mode )
{
case Mode.IM:
// arg hold a value
ret = m_arg;
break;
case Mode.INDIR:
// argument holds the name of a property to load
ret = ctx.LValue(m_arg.ToString());
break;
case Mode.STK_IM:
// value from the stack
ret = ctx.Stack.Pop();
break;
case Mode.STK_INDIR:
// stack hold the name of a property
JsObject obj = LValue.CheckRValue( ctx.Stack.Pop() );
ret = ctx.LValue( obj.ToString() );
break;
}
Debug.Assert(ret != null);
if (ret is LValue && ((LValue)ret).Get() is TypeFunction && ((TypeFunction)((LValue)ret).Get()).IsAnonFunction)
{
((TypeFunction)((LValue)ret).Get()).OuterObject = ctx.This;
}
return ret;
}
protected Op m_opcode;
protected JsObject m_arg;
protected Mode m_mode;
protected int m_line;
protected string m_debughint = "";
}
}