⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsdas.js

📁 一个类似windows
💻 JS
📖 第 1 页 / 共 2 页
字号:
/*
 * Byte-code file handling.
 * Copyright (c) 1998 New Generation Software (NGS) Oy
 *
 * Author: Markku Rossi <mtr@ngs.fi>
 */

/*
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA
 */

/*
 * $Source: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/jsdas/jsdas.js,v $
 * $Id: jsdas.js 21681 2006-04-21 15:00:24Z peterw $
 */

function ByteCode$SymtabEntry (name, offset)
{
  this.name = name;
  this.offset = offset;
}


function ByteCode ()
{
  /* Private methods. */
  this.sectionName = ByteCode$sectionName;
  this.lookupSection = ByteCode$lookupSection;
  this.parseConstants = ByteCode$parseConstants;
  this.parseSymtab = ByteCode$parseSymtab;
  this.prettyPrintString = ByteCode$prettyPrintString;
  this.opIsSymbol = ByteCode$opIsSymbol;
  this.opIsJump = ByteCode$opIsJump;

  /* Public methods. */
  this.parse = ByteCode$parse;
  this.write = ByteCode$write;
  this.printInfo = ByteCode$printInfo;
  this.printCode = ByteCode$printCode;
  this.printConstants = ByteCode$printConstants;
  this.printSymtab = ByteCode$printSymtab;
  this.printDebug = ByteCode$printDebug;
  this.linkSection = ByteCode$linkSection;
  this.removeSection = ByteCode$removeSection;
}


function ByteCode$sectionName (type)
{
  var name = type.toString ();

  if (type == JSC$BC_SECT_CODE)
    name += " (code)";
  else if (type == JSC$BC_SECT_CONSTANTS)
    name += " (constants)";
  else if (type == JSC$BC_SECT_SYMTAB)
    name +=  " (symtab)";
  else if (type == JSC$BC_SECT_DEBUG)
    name += " (debug)";

  return name;
}


function ByteCode$lookupSection (sect)
{
  var i;
  for (i = 0; i < this.sect_types.length; i++)
    if (this.sect_types[i] == sect)
      return this.sect_data[i];

  System.print ("jsdas: no section ", this.sectionName (sect), "\n");
  return false;
}


function ByteCode$parseConstants ()
{
  if (this.constants)
    return this.constants;

  var data = this.lookupSection (JSC$BC_SECT_CONSTANTS);
  if (!data)
    return false;

  this.constants = new Array ();
  var pos, count = 0;
  for (pos = 0; pos < data.length; count++)
    {
      var type = data[pos++];
      var val;

      if (type == JSC$CONST_INT)
	{
	  val = data.substr (pos, 4).unpack ("N")[0];
	  pos += 4;
	}
      else if (type == JSC$CONST_STRING)
	{
	  var len = data.substr (pos, 4).unpack ("N")[0];
	  pos += 4;

	  val = "\"" + data.substr (pos, len);
	  pos += len;
	}
      else if (type == JSC$CONST_FLOAT)
	{
	  val = data.substr (pos, 8).unpack ("d")[0];
	  pos += 8;
	}
      else if (type == JSC$CONST_SYMBOL)
	{
	  val = new String ("S");
	  for (; data[pos] != #'\0'; pos++)
	    val.append (data.charAt (pos));
	  pos++;
	}
      else if (type == JSC$CONST_NAN)
	{
	  val = parseFloat ("****");
	}
      else if (type == JSC$CONST_REGEXP)
	{
	  var flags = data.substr (pos, 1).unpack ("C")[0];
	  pos++;

	  var len = data.substr (pos, 4).unpack ("N")[0];
	  pos += 4;

	  val = "/" + File.byteToString (flags) + data.substr (pos, len);
	  pos += len;
	}
      else
	{
	  /* Unknown constant type. */
	  this.constants = false;
	  return false;
	}

      this.constants[count] = val;
    }

  return this.constants;
}


function ByteCode$parseSymtab ()
{
  if (this.symtab)
    return this.symtab;

  var data = this.lookupSection (JSC$BC_SECT_SYMTAB);
  if (!data)
    return false;

  this.symtab = new Array ();

  /* Fetch the number of symtab entries. */
  var nentries = data.unpack ("N")[0];

  var pos, count = 0;
  for (pos = 4; pos < data.length; count++)
    {
      /* Read the symbol name. */
      var name = new String ("");
      for (; data[pos] != #'\0'; pos++)
	name.append (data.charAt (pos));
      pos++;

      /* Read the offset. */
      var offset = data.substr (pos, 4).unpack ("N")[0];
      pos += 4;

      this.symtab.push (new ByteCode$SymtabEntry (name, offset));
    }

  if (count != nentries)
    System.print ("jsdas: warning: expected ", nentries,
		  " symtab entries, but got ", count, "\n");

  return this.symtab;
}


function ByteCode$prettyPrintString (str)
{
  var i;
  var tail = "";
  var ender;

  /* Determine the type. */
  if (str[0] == #'"')
    {
      i = 1;
      ender = "\"";
    }
  else
    {
      /* Regexp. */
      var flags = str[1];
      ender = "/";

      if (flags & JSC$CONST_REGEXP_FLAG_G)
	tail += "g";
      if (flags & JSC$CONST_REGEXP_FLAG_I)
	tail += "i";

      i = 2;
    }

  System.print (ender);
  for (; i < str.length; i++)
    {
      if (str[i] == ender[0] || str[i] ==  #'\\')
	System.print ("\\" + str.charAt (i));
      else if (str[i] == #'\n')
	System.print ("\\n");
      else if (str[i] == #'\t')
	System.print ("\\t");
      else if (str[i] == #'\v')
	System.print ("\\v");
      else if (str[i] == #'\b')
	System.print ("\\b");
      else if (str[i] == #'\r')
	System.print ("\\r");
      else if (str[i] == #'\f')
	System.print ("\\f");
      else if (str[i] == #'\a')
	System.print ("\\a");
      else if (str[i] == #'\'')
	System.print ("\\\'");
      else if (str[i] == #'\"')
	System.print ("\\\"");
      else
	System.print (str.charAt (i));
    }
  System.print (ender, tail);
}

function ByteCode$opIsSymbol (op)
{
  return (DASM$op_flags[op] & 0x01) != 0;
}

function ByteCode$opIsJump (op)
{
  return (DASM$op_flags[op] & 0x02) != 0;
}


function ByteCode$parse (stream)
{
  var ch;
  var buf;

  ch = stream.readByte ();
  if (ch == #'#')
    {
      if (stream.readByte () != #'!')
	return false;

      /* Skip the first comment line. */
      this.first_line = "#!" + stream.readln ();
    }
  else
    {
      stream.ungetByte (ch);
      this.first_line = false;
    }

  buf = stream.read (4);
  if (buf.length != 4)
    return false;

  var a = buf.unpack ("N");
  if (a[0] != JSC$BC_MAGIC)
    {
      System.print ("jsdas: illegal magic: ", a[0].toString (16),
		    ", should be: ", JSC$BC_MAGIC.toString (16), "\n");
      return false;
    }

  buf = stream.read (4);
  if (buf.length != 4)
    return false;

  var num_sections = buf.unpack ("N")[0];
  this.sect_types = new Array ();
  this.sect_data = new Array ();

  /* Read sections. */
  for (i = 0; i < num_sections; i++)
    {
      /* Type and length. */
      buf = stream.read (8);
      if (buf.length != 8)
	return false;

      a = buf.unpack ("NN");

      this.sect_types[i] = a[0];

      var len = a[1];
      buf = stream.read (len);
      if (buf.length != len)
	{
	  System.stdout.writeln ("couldn't read section " + i.toString ()
				 + ", expected=" + len.toString ()
				 + ", got=" + buf.length.toString ());
	  return false;
	}

      this.sect_data[i] = buf;
    }

  return true;
}


function ByteCode$printInfo ()
{
  var i;

  for (i = 0; i < this.sect_types.length; i++)
    {
      var sectname = this.sectionName (this.sect_types[i]);
      System.print ("  section ", i, ": ");
      System.print ("type=", sectname);
      System.print (", length=", this.sect_data[i].length, "\n");
    }
}


function ByteCode$printConstants ()
{
  if (!this.parseConstants ())
    {
      System.print ("jsdas: couldn't find a parse the constants section\n");
      return;
    }

  var i;
  for (i = 0; i < this.constants.length; i++)
    {
      System.print ("  ", i, ":\t");

      var c = this.constants[i];
      if (typeof c == "number")
	System.print (c);
      else if (typeof c == "string")
	{
	  /* Must be a string, regexp or symbol. */
	  if (c[0] == #'S')
	    /* Symbol. */
	    System.print (c.substr (1));
	  else
	    this.prettyPrintString (c);
	}
      else
	{
	  System.print ("jsdas: illegal element in the constans array: type=",
			typeof c, "\n");
	  return;
	}

      System.print ("\n");
    }
}


function ByteCode$printSymtab ()
{
  var symtab = this.parseSymtab ();
  if (!symtab)
    {
      System.print ("jsdas: couldn't find or parse symtab section\n");
      return;
    }

  var i;
  for (i = 0; i < symtab.length; i++)
    {
      var name = symtab[i].name;
      var offset = symtab[i].offset;

      System.print ("  ", name);

      var pad = name.length;
      for (; pad < 40; pad++)
	System.print (" ");

      System.print (offset, "\n");
    }
}


function ByteCode$printDebug ()
{
  var data = this.lookupSection (JSC$BC_SECT_DEBUG);
  if (!data)
    return;

  var pos, count = 0;
  var filename = "<unknown>";
  for (pos = 0; pos < data.length; count++)
    {
      var type = data[pos++];

      if (type == JSC$DEBUG_FILENAME)
	{
	  var len = data.substr (pos, 4).unpack ("N")[0];
	  pos += 4;

	  filename = data.substr (pos, len);
	  pos += len;
	}
      else if (type == JSC$DEBUG_LINENUMBER)
	{
	  var a = data.substr (pos, 8).unpack ("NN");
	  pos += 8;

	  System.print ("  ", a[0], "\t", filename, ":", a[1], "\n");
	}
      else
	{
	  System.print ("jsdas: unknown debug entry: ",
			"skipping all remaining data\n");
	  return;
	}
    }
}


function ByteCode$printCode ()
{
  var data = this.lookupSection (JSC$BC_SECT_CODE);
  if (!data)
    return;

  var consts = this.parseConstants ();
  if (!consts)
    {
      System.print ("jsdas: couldn't find or parse constants\n");
      return;
    }

  var symtab = this.parseSymtab ();
  if (!symtab)
    {
      System.print ("jsdas: couldn't find or parse symtab\n");
      return;
    }

  var symtab_pos = -1;
  var next_symtab_offset = -1;

  var pos;
  for (pos = 0; pos < data.length; )
    {
      /* Handle symtab entries. */
      if (pos >= next_symtab_offset)
	{
	  while (pos > next_symtab_offset)
	    {
	      /* Lookup the next offset. */
	      symtab_pos++;
	      if (symtab_pos >= symtab.length)
		next_symtab_offset = data.length + 1;
	      else
		next_symtab_offset = symtab[symtab_pos].offset;
	    }

	  if (pos == next_symtab_offset)
	    System.print (pos == 0 ? "" : "\n",
			  symtab[symtab_pos].name, ":\n");
	}

      System.print ("  ", pos, "\t");

      var op = data[pos++];
      if (!DASM$op_names[op])
	{
	  System.print ("jsdas: unknown operand: ",
			"skipping all remaining data\n");
	  return;
	}

      System.print (DASM$op_names[op], "\t");
      if (DASM$op_names[op].length < 8)
	System.print ("\t");

      var ds = DASM$op_data[op];
      var val;

      if (ds == 1)
	val = data[pos];
      else if (ds == 2)
	val = data.substr (pos, 2).unpack ("n")[0];
      else if (ds == 4)
	val = data.substr (pos, 4).unpack ("N")[0];

      if (op == JSC$OP_CONST || this.opIsSymbol (op))
	{
	  /* Handle symbols and constants. */

	  var c = consts[val];
	  if (typeof c == "string")
	    {
	      if (c[0] == #'S')
		System.print (c.substr (1));
	      else
		this.prettyPrintString (c);
	    }
	  else
	    System.print (c);
	}
      else if (this.opIsJump (op))
	{
	  /* Local jumps. */
	  val += pos + ds;
	  System.print (val);
	}
      else
	{
	  /* Handle all the rest. */
	  if (ds != 0)
	    System.print (val);
	}

      pos += ds;

      System.print ("\n");
    }
}


function ByteCode$linkSection (type, data)
{
  var i;
  for (i = 0; i < this.sect_types.length; i++)
    if (this.sect_types[i] == type)
      {
	this.sect_data[i] = data;
	return;
      }

  /* Create a new section. */
  this.sect_types.push (type);
  this.sect_data.push (data);
}


function ByteCode$removeSection (type)
{
  var i;
  for (i = 0; i < this.sect_types.length; i++)
    if (this.sect_types[i] == type)
      {
	/* Found it. */
	this.sect_types.splice (i, 1);
	this.sect_data.splice (i, 1);
	return true;
      }

  return false;
}


function ByteCode$write (name)
{
  var fp = new File (name);
  if (fp.open ("w"))
    {
      /* Possible first line. */
      if (this.first_line)
	fp.writeln (this.first_line);

      /* Magic. */
      fp.write (String.pack ("N", JSC$BC_MAGIC));

      /* Number of sections. */
      fp.write (String.pack ("N", this.sect_types.length));

      var i;
      for (i = 0; i < this.sect_types.length; i++)
	{
	  /* Write type and the length of the section. */
	  fp.write (String.pack ("NN", this.sect_types[i],
				 this.sect_data[i].length));

	  /* Write the data. */
	  fp.write (this.sect_data[i]);
	}

      return fp.close ();
    }

  return false;
}


/*
Local variables:
mode: c
End:
*/
/*                                                              -*- c -*-
 * Operand definitions for the JavaScript byte-code.
 *
 * This file is automatically create from the operands.def file.
 * Editing is strongly discouraged.  You should edit the file
 * `extract-op-names.js' instead.
 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -