зеркало из https://github.com/mozilla/gecko-dev.git
lalala, things run, lalala. (well, kinda.)
This commit is contained in:
Родитель
e21934da7e
Коммит
fdb5df401b
|
@ -34,10 +34,15 @@
|
|||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#include "utilities.h"
|
||||
#include "icodegenerator.h"
|
||||
#include "icodeasm.h"
|
||||
|
||||
void testAlpha (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
const string &expect)
|
||||
using namespace JavaScript;
|
||||
|
||||
void
|
||||
testAlpha (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
const string &expect)
|
||||
{
|
||||
string *result;
|
||||
icp.ParseAlpha (str.begin(), str.end(), &result);
|
||||
|
@ -49,8 +54,9 @@ void testAlpha (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
|||
result->c_str());
|
||||
}
|
||||
|
||||
void testBool (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
bool expect)
|
||||
void
|
||||
testBool (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
bool expect)
|
||||
{
|
||||
bool b;
|
||||
icp.ParseBool (str.begin(), str.end(), &b);
|
||||
|
@ -61,8 +67,9 @@ void testBool (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
|||
fprintf (stderr, "string '%s' bool parsed as %i\n", str.c_str(), b);
|
||||
}
|
||||
|
||||
void testDouble (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
double expect)
|
||||
void
|
||||
testDouble (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
double expect)
|
||||
{
|
||||
double result;
|
||||
icp.ParseDouble (str.begin(), str.end(), &result);
|
||||
|
@ -74,8 +81,9 @@ void testDouble (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
|||
result);
|
||||
}
|
||||
|
||||
void testString (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
const string &expect)
|
||||
void
|
||||
testString (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
const string &expect)
|
||||
{
|
||||
string *result;
|
||||
icp.ParseString (str.begin(), str.end(), &result);
|
||||
|
@ -87,8 +95,9 @@ void testString (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
|||
result->c_str());
|
||||
}
|
||||
|
||||
void testUInt32 (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
uint32 expect)
|
||||
void
|
||||
testUInt32 (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
uint32 expect)
|
||||
{
|
||||
uint32 result;
|
||||
icp.ParseUInt32 (str.begin(), str.end(), &result);
|
||||
|
@ -100,16 +109,51 @@ void testUInt32 (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
|||
result);
|
||||
}
|
||||
|
||||
void testParse (JavaScript::ICodeASM::ICodeParser &icp, const string &str)
|
||||
void
|
||||
testParse (JavaScript::ICodeASM::ICodeParser &icp,
|
||||
JavaScript::Interpreter::Context cx,
|
||||
const string &str)
|
||||
{
|
||||
icp.ParseSourceFromString (str);
|
||||
using namespace JavaScript;
|
||||
|
||||
icp.ParseSourceFromString (str);
|
||||
ICG::ICodeModule icm = ICG::ICodeModule (icp.mInstructions,
|
||||
new ICG::VariableList(),
|
||||
icp.mMaxRegister, 0, 0, false,
|
||||
false, &JSTypes::Any_Type);
|
||||
|
||||
stdOut << icm;
|
||||
|
||||
JSTypes::JSValues args;
|
||||
cx.interpret (&icm, args);
|
||||
|
||||
}
|
||||
|
||||
static JSTypes::JSValue
|
||||
print(Interpreter::Context *, const JSTypes::JSValues &argv)
|
||||
{
|
||||
size_t n = argv.size();
|
||||
if (n > 1) { // the 'this' parameter is un-interesting
|
||||
stdOut << argv[1];
|
||||
for (size_t i = 2; i < n; ++i)
|
||||
stdOut << ' ' << argv[i];
|
||||
}
|
||||
stdOut << "\n";
|
||||
return JSTypes::kUndefinedValue;
|
||||
}
|
||||
|
||||
int
|
||||
main (int , char **)
|
||||
{
|
||||
JavaScript::ICodeASM::ICodeParser icp;
|
||||
World world;
|
||||
JSTypes::JSScope global;
|
||||
|
||||
global.defineNativeFunction(world.identifiers["print"], print);
|
||||
|
||||
Interpreter::Context cx (world, &global);
|
||||
ICodeASM::ICodeParser icp(&cx);
|
||||
|
||||
/*
|
||||
testAlpha (icp, "False", "False");
|
||||
testAlpha (icp, "fe fi fo fum", "fe");
|
||||
testAlpha (icp, " bla", "");
|
||||
|
@ -140,20 +184,56 @@ main (int , char **)
|
|||
testUInt32 (icp, "12.3", 12);
|
||||
testUInt32 (icp, "-123", 0);
|
||||
testUInt32 (icp, "-12.3", 0);
|
||||
*/
|
||||
/* XXX what to do with the overflow? */
|
||||
//testUInt32 (icp, "12123687213612873621873438754387934657834", 0);
|
||||
|
||||
string src =
|
||||
string src;
|
||||
|
||||
/*
|
||||
src =
|
||||
"some_label:\n"
|
||||
"LOAD_STRING R1, 'hello' ;test comment\n"
|
||||
"CAST R2, R1, 'any';another test comment\n"
|
||||
"SAVE_NAME 'x', R2\n"
|
||||
"LOAD_NAME R1, 'x'\n"
|
||||
"LOAD_NAME R2, 'print'\n"
|
||||
"CALL R3, R2, <NaR>, ('foo':R1, R2)\n"
|
||||
"CALL R3, R2, <NaR>, (R1)\n"
|
||||
"RETURN R3";
|
||||
|
||||
testParse (icp, src);
|
||||
testParse (icp, cx, src);
|
||||
*/
|
||||
|
||||
/* {x= 1; for (i = 10; i > 0; --i) x = x * i; print ("x is " + x);} */
|
||||
src =
|
||||
"LOAD_IMMEDIATE R1, 1\n"
|
||||
"CAST R2, R1, 'any'\n"
|
||||
"SAVE_NAME 'x', R2\n"
|
||||
"LOAD_IMMEDIATE R1, 10\n"
|
||||
"CAST R2, R1, 'any'\n"
|
||||
"SAVE_NAME 'i', R2\n"
|
||||
"BRANCH Offset 17\n"
|
||||
"LOAD_NAME R1, 'x'\n"
|
||||
"LOAD_NAME R2, 'i'\n"
|
||||
"GENERIC_BINARY_OP R3, Multiply, R1, R2\n"
|
||||
"CAST R4, R3, 'any'\n"
|
||||
"SAVE_NAME 'x', R4\n"
|
||||
"LOAD_NAME R1, 'i'\n"
|
||||
"LOAD_IMMEDIATE R2, 1\n"
|
||||
"GENERIC_BINARY_OP R3, Subtract, R1, R2\n"
|
||||
"SAVE_NAME 'i', R3\n"
|
||||
"LOAD_NAME R4, 'i'\n"
|
||||
"LOAD_IMMEDIATE R5, 0\n"
|
||||
"GENERIC_BINARY_OP R6, Less, R5, R4\n"
|
||||
"BRANCH_TRUE Offset 8, R6\n"
|
||||
"LOAD_STRING R1, 'x is '\n"
|
||||
"LOAD_NAME R2, 'x'\n"
|
||||
"GENERIC_BINARY_OP R3, Add, R1, R2\n"
|
||||
"LOAD_NAME R4, 'print'\n"
|
||||
"CALL R5, R4, <NaR>, (R3)\n"
|
||||
"RETURN <NaR>\n";
|
||||
|
||||
testParse (icp, cx, src);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ namespace ICodeASM {
|
|||
static char *keyword_offset = "offset";
|
||||
static char *keyword_binaryops[] = {"add", "subtract", "multiply", "divide",
|
||||
"remainder", "leftshift", "rightshift",
|
||||
"logicalrightshift", "bitwiseor",
|
||||
"bitwisexor", "bitwiseand", "less",
|
||||
"lessorequal", "equal", "identical", 0};
|
||||
|
||||
#define IS_ALPHA(ch) ((ch >= 'a' && ch <= 'z') || \
|
||||
|
@ -71,6 +73,7 @@ namespace ICodeASM {
|
|||
iter begin = source.begin();
|
||||
iter end = source.end();
|
||||
mMaxRegister = 0;
|
||||
mInstructionCount = 0;
|
||||
|
||||
while (begin < end)
|
||||
{
|
||||
|
@ -301,8 +304,7 @@ namespace ICodeASM {
|
|||
if (++begin != end) {
|
||||
try
|
||||
{
|
||||
end = ParseUInt32 (++begin, end,
|
||||
static_cast<uint32 *>(rval));
|
||||
end = ParseUInt32 (begin, end, static_cast<uint32 *>(rval));
|
||||
if (*rval != VM::NotARegister && *rval > mMaxRegister)
|
||||
mMaxRegister = *rval;
|
||||
return end;
|
||||
|
@ -656,17 +658,18 @@ namespace ICodeASM {
|
|||
|
||||
if (cmp_nocase(*str, keyword_offset, keyword_offset +
|
||||
strlen(keyword_offset) + 1) == 0) {
|
||||
delete str;
|
||||
/* got the "Offset" keyword, treat next thing as a jump offset
|
||||
* expressed as "Offset +/-N" */
|
||||
tl = SeekTokenStart (begin, end);
|
||||
|
||||
if ((tl.estimate != teNumeric) && (tl.estimate != teMinus) &&
|
||||
(tl.estimate != tePlus))
|
||||
if (tl.estimate != teNumeric)
|
||||
throw new ICodeParseException ("Expected numeric value after Offset keyword");
|
||||
int32 ofs;
|
||||
begin = ParseInt32 (tl.begin, end, &ofs);
|
||||
|
||||
uint32 ofs;
|
||||
begin = ParseUInt32 (tl.begin, end, &ofs);
|
||||
VM::Label *new_label = new VM::Label(mInstructions);
|
||||
new_label->mOffset = mInstructionCount + ofs;
|
||||
new_label->mOffset = ofs;
|
||||
mUnnamedLabels.push_back (new_label);
|
||||
*rval = new_label;
|
||||
} else {
|
||||
|
@ -684,6 +687,7 @@ namespace ICodeASM {
|
|||
*rval = new_label;
|
||||
mNamedLabels[str->c_str()] = new_label;
|
||||
}
|
||||
delete str;
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
|
@ -778,7 +782,8 @@ namespace ICodeASM {
|
|||
|
||||
# undef CASE_TYPE
|
||||
|
||||
mInstructions.push_back (InstructionFromNode(&node));
|
||||
VM::Instruction *i = InstructionFromNode(&node);
|
||||
mInstructions->push_back (i);
|
||||
++mInstructionCount;
|
||||
|
||||
TokenLocation tl = SeekTokenStart (curpos, end);
|
||||
|
|
|
@ -129,14 +129,17 @@ namespace ICodeASM {
|
|||
|
||||
Interpreter::Context *mCx;
|
||||
uint32 mInstructionCount;
|
||||
uint32 mMaxRegister;
|
||||
VM::InstructionStream mInstructions;
|
||||
VM::LabelList mUnnamedLabels;
|
||||
typedef std::map<const char *, VM::Label*> LabelMap;
|
||||
LabelMap mNamedLabels;
|
||||
|
||||
|
||||
public:
|
||||
ICodeParser (Interpreter::Context *aCx = 0) : mCx(aCx) {}
|
||||
uint32 mMaxRegister;
|
||||
VM::InstructionStream *mInstructions;
|
||||
|
||||
public:
|
||||
ICodeParser (Interpreter::Context *aCx) : mCx(aCx)
|
||||
{ mInstructions = new VM::InstructionStream(); }
|
||||
void ParseSourceFromString (const string &source);
|
||||
|
||||
/* locate the beginning of the next token and take a guess at what it
|
||||
|
|
|
@ -155,7 +155,7 @@ namespace ICodeASM {
|
|||
i = new BranchTrue (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 7:
|
||||
i = new Call (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0), static_cast<ArgumentList>(node->operand[3].data));
|
||||
i = new Call (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0), *(reinterpret_cast<ArgumentList *>(node->operand[3].data)));
|
||||
break;
|
||||
case 8:
|
||||
i = new Cast (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<JSType*>(node->operand[2].data));
|
||||
|
@ -188,7 +188,7 @@ namespace ICodeASM {
|
|||
i = new DeleteProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data));
|
||||
break;
|
||||
case 18:
|
||||
i = new DirectCall (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSFunction*>(node->operand[1].data), static_cast<ArgumentList>(node->operand[2].data));
|
||||
i = new DirectCall (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSFunction*>(node->operand[1].data), *(reinterpret_cast<ArgumentList *>(node->operand[2].data)));
|
||||
break;
|
||||
case 19:
|
||||
i = new Divide (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
|
|
|
@ -189,6 +189,8 @@ sub get_generator {
|
|||
for $p (@params) {
|
||||
if ($p eq "TypedRegister") {
|
||||
push (@args, "TypedRegister(static_cast<Register>(node->operand[$arg_num].data), 0)");
|
||||
} elsif ($p eq "ArgumentList") {
|
||||
push (@args, "*(reinterpret_cast<ArgumentList *>(node->operand[$arg_num].data))");
|
||||
} elsif ($p =~ /\*$/) {
|
||||
push (@args, "reinterpret_cast<$p>(node->operand[$arg_num].data)");
|
||||
} else {
|
||||
|
|
|
@ -34,10 +34,15 @@
|
|||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#include "utilities.h"
|
||||
#include "icodegenerator.h"
|
||||
#include "icodeasm.h"
|
||||
|
||||
void testAlpha (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
const string &expect)
|
||||
using namespace JavaScript;
|
||||
|
||||
void
|
||||
testAlpha (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
const string &expect)
|
||||
{
|
||||
string *result;
|
||||
icp.ParseAlpha (str.begin(), str.end(), &result);
|
||||
|
@ -49,8 +54,9 @@ void testAlpha (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
|||
result->c_str());
|
||||
}
|
||||
|
||||
void testBool (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
bool expect)
|
||||
void
|
||||
testBool (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
bool expect)
|
||||
{
|
||||
bool b;
|
||||
icp.ParseBool (str.begin(), str.end(), &b);
|
||||
|
@ -61,8 +67,9 @@ void testBool (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
|||
fprintf (stderr, "string '%s' bool parsed as %i\n", str.c_str(), b);
|
||||
}
|
||||
|
||||
void testDouble (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
double expect)
|
||||
void
|
||||
testDouble (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
double expect)
|
||||
{
|
||||
double result;
|
||||
icp.ParseDouble (str.begin(), str.end(), &result);
|
||||
|
@ -74,8 +81,9 @@ void testDouble (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
|||
result);
|
||||
}
|
||||
|
||||
void testString (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
const string &expect)
|
||||
void
|
||||
testString (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
const string &expect)
|
||||
{
|
||||
string *result;
|
||||
icp.ParseString (str.begin(), str.end(), &result);
|
||||
|
@ -87,8 +95,9 @@ void testString (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
|||
result->c_str());
|
||||
}
|
||||
|
||||
void testUInt32 (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
uint32 expect)
|
||||
void
|
||||
testUInt32 (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
||||
uint32 expect)
|
||||
{
|
||||
uint32 result;
|
||||
icp.ParseUInt32 (str.begin(), str.end(), &result);
|
||||
|
@ -100,16 +109,51 @@ void testUInt32 (JavaScript::ICodeASM::ICodeParser &icp, const string &str,
|
|||
result);
|
||||
}
|
||||
|
||||
void testParse (JavaScript::ICodeASM::ICodeParser &icp, const string &str)
|
||||
void
|
||||
testParse (JavaScript::ICodeASM::ICodeParser &icp,
|
||||
JavaScript::Interpreter::Context cx,
|
||||
const string &str)
|
||||
{
|
||||
icp.ParseSourceFromString (str);
|
||||
using namespace JavaScript;
|
||||
|
||||
icp.ParseSourceFromString (str);
|
||||
ICG::ICodeModule icm = ICG::ICodeModule (icp.mInstructions,
|
||||
new ICG::VariableList(),
|
||||
icp.mMaxRegister, 0, 0, false,
|
||||
false, &JSTypes::Any_Type);
|
||||
|
||||
stdOut << icm;
|
||||
|
||||
JSTypes::JSValues args;
|
||||
cx.interpret (&icm, args);
|
||||
|
||||
}
|
||||
|
||||
static JSTypes::JSValue
|
||||
print(Interpreter::Context *, const JSTypes::JSValues &argv)
|
||||
{
|
||||
size_t n = argv.size();
|
||||
if (n > 1) { // the 'this' parameter is un-interesting
|
||||
stdOut << argv[1];
|
||||
for (size_t i = 2; i < n; ++i)
|
||||
stdOut << ' ' << argv[i];
|
||||
}
|
||||
stdOut << "\n";
|
||||
return JSTypes::kUndefinedValue;
|
||||
}
|
||||
|
||||
int
|
||||
main (int , char **)
|
||||
{
|
||||
JavaScript::ICodeASM::ICodeParser icp;
|
||||
World world;
|
||||
JSTypes::JSScope global;
|
||||
|
||||
global.defineNativeFunction(world.identifiers["print"], print);
|
||||
|
||||
Interpreter::Context cx (world, &global);
|
||||
ICodeASM::ICodeParser icp(&cx);
|
||||
|
||||
/*
|
||||
testAlpha (icp, "False", "False");
|
||||
testAlpha (icp, "fe fi fo fum", "fe");
|
||||
testAlpha (icp, " bla", "");
|
||||
|
@ -140,20 +184,56 @@ main (int , char **)
|
|||
testUInt32 (icp, "12.3", 12);
|
||||
testUInt32 (icp, "-123", 0);
|
||||
testUInt32 (icp, "-12.3", 0);
|
||||
*/
|
||||
/* XXX what to do with the overflow? */
|
||||
//testUInt32 (icp, "12123687213612873621873438754387934657834", 0);
|
||||
|
||||
string src =
|
||||
string src;
|
||||
|
||||
/*
|
||||
src =
|
||||
"some_label:\n"
|
||||
"LOAD_STRING R1, 'hello' ;test comment\n"
|
||||
"CAST R2, R1, 'any';another test comment\n"
|
||||
"SAVE_NAME 'x', R2\n"
|
||||
"LOAD_NAME R1, 'x'\n"
|
||||
"LOAD_NAME R2, 'print'\n"
|
||||
"CALL R3, R2, <NaR>, ('foo':R1, R2)\n"
|
||||
"CALL R3, R2, <NaR>, (R1)\n"
|
||||
"RETURN R3";
|
||||
|
||||
testParse (icp, src);
|
||||
testParse (icp, cx, src);
|
||||
*/
|
||||
|
||||
/* {x= 1; for (i = 10; i > 0; --i) x = x * i; print ("x is " + x);} */
|
||||
src =
|
||||
"LOAD_IMMEDIATE R1, 1\n"
|
||||
"CAST R2, R1, 'any'\n"
|
||||
"SAVE_NAME 'x', R2\n"
|
||||
"LOAD_IMMEDIATE R1, 10\n"
|
||||
"CAST R2, R1, 'any'\n"
|
||||
"SAVE_NAME 'i', R2\n"
|
||||
"BRANCH Offset 17\n"
|
||||
"LOAD_NAME R1, 'x'\n"
|
||||
"LOAD_NAME R2, 'i'\n"
|
||||
"GENERIC_BINARY_OP R3, Multiply, R1, R2\n"
|
||||
"CAST R4, R3, 'any'\n"
|
||||
"SAVE_NAME 'x', R4\n"
|
||||
"LOAD_NAME R1, 'i'\n"
|
||||
"LOAD_IMMEDIATE R2, 1\n"
|
||||
"GENERIC_BINARY_OP R3, Subtract, R1, R2\n"
|
||||
"SAVE_NAME 'i', R3\n"
|
||||
"LOAD_NAME R4, 'i'\n"
|
||||
"LOAD_IMMEDIATE R5, 0\n"
|
||||
"GENERIC_BINARY_OP R6, Less, R5, R4\n"
|
||||
"BRANCH_TRUE Offset 8, R6\n"
|
||||
"LOAD_STRING R1, 'x is '\n"
|
||||
"LOAD_NAME R2, 'x'\n"
|
||||
"GENERIC_BINARY_OP R3, Add, R1, R2\n"
|
||||
"LOAD_NAME R4, 'print'\n"
|
||||
"CALL R5, R4, <NaR>, (R3)\n"
|
||||
"RETURN <NaR>\n";
|
||||
|
||||
testParse (icp, cx, src);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,8 @@ namespace ICodeASM {
|
|||
static char *keyword_offset = "offset";
|
||||
static char *keyword_binaryops[] = {"add", "subtract", "multiply", "divide",
|
||||
"remainder", "leftshift", "rightshift",
|
||||
"logicalrightshift", "bitwiseor",
|
||||
"bitwisexor", "bitwiseand", "less",
|
||||
"lessorequal", "equal", "identical", 0};
|
||||
|
||||
#define IS_ALPHA(ch) ((ch >= 'a' && ch <= 'z') || \
|
||||
|
@ -71,6 +73,7 @@ namespace ICodeASM {
|
|||
iter begin = source.begin();
|
||||
iter end = source.end();
|
||||
mMaxRegister = 0;
|
||||
mInstructionCount = 0;
|
||||
|
||||
while (begin < end)
|
||||
{
|
||||
|
@ -301,8 +304,7 @@ namespace ICodeASM {
|
|||
if (++begin != end) {
|
||||
try
|
||||
{
|
||||
end = ParseUInt32 (++begin, end,
|
||||
static_cast<uint32 *>(rval));
|
||||
end = ParseUInt32 (begin, end, static_cast<uint32 *>(rval));
|
||||
if (*rval != VM::NotARegister && *rval > mMaxRegister)
|
||||
mMaxRegister = *rval;
|
||||
return end;
|
||||
|
@ -656,17 +658,18 @@ namespace ICodeASM {
|
|||
|
||||
if (cmp_nocase(*str, keyword_offset, keyword_offset +
|
||||
strlen(keyword_offset) + 1) == 0) {
|
||||
delete str;
|
||||
/* got the "Offset" keyword, treat next thing as a jump offset
|
||||
* expressed as "Offset +/-N" */
|
||||
tl = SeekTokenStart (begin, end);
|
||||
|
||||
if ((tl.estimate != teNumeric) && (tl.estimate != teMinus) &&
|
||||
(tl.estimate != tePlus))
|
||||
if (tl.estimate != teNumeric)
|
||||
throw new ICodeParseException ("Expected numeric value after Offset keyword");
|
||||
int32 ofs;
|
||||
begin = ParseInt32 (tl.begin, end, &ofs);
|
||||
|
||||
uint32 ofs;
|
||||
begin = ParseUInt32 (tl.begin, end, &ofs);
|
||||
VM::Label *new_label = new VM::Label(mInstructions);
|
||||
new_label->mOffset = mInstructionCount + ofs;
|
||||
new_label->mOffset = ofs;
|
||||
mUnnamedLabels.push_back (new_label);
|
||||
*rval = new_label;
|
||||
} else {
|
||||
|
@ -684,6 +687,7 @@ namespace ICodeASM {
|
|||
*rval = new_label;
|
||||
mNamedLabels[str->c_str()] = new_label;
|
||||
}
|
||||
delete str;
|
||||
}
|
||||
return begin;
|
||||
}
|
||||
|
@ -778,7 +782,8 @@ namespace ICodeASM {
|
|||
|
||||
# undef CASE_TYPE
|
||||
|
||||
mInstructions.push_back (InstructionFromNode(&node));
|
||||
VM::Instruction *i = InstructionFromNode(&node);
|
||||
mInstructions->push_back (i);
|
||||
++mInstructionCount;
|
||||
|
||||
TokenLocation tl = SeekTokenStart (curpos, end);
|
||||
|
|
|
@ -129,14 +129,17 @@ namespace ICodeASM {
|
|||
|
||||
Interpreter::Context *mCx;
|
||||
uint32 mInstructionCount;
|
||||
uint32 mMaxRegister;
|
||||
VM::InstructionStream mInstructions;
|
||||
VM::LabelList mUnnamedLabels;
|
||||
typedef std::map<const char *, VM::Label*> LabelMap;
|
||||
LabelMap mNamedLabels;
|
||||
|
||||
|
||||
public:
|
||||
ICodeParser (Interpreter::Context *aCx = 0) : mCx(aCx) {}
|
||||
uint32 mMaxRegister;
|
||||
VM::InstructionStream *mInstructions;
|
||||
|
||||
public:
|
||||
ICodeParser (Interpreter::Context *aCx) : mCx(aCx)
|
||||
{ mInstructions = new VM::InstructionStream(); }
|
||||
void ParseSourceFromString (const string &source);
|
||||
|
||||
/* locate the beginning of the next token and take a guess at what it
|
||||
|
|
|
@ -155,7 +155,7 @@ namespace ICodeASM {
|
|||
i = new BranchTrue (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 7:
|
||||
i = new Call (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0), static_cast<ArgumentList>(node->operand[3].data));
|
||||
i = new Call (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0), *(reinterpret_cast<ArgumentList *>(node->operand[3].data)));
|
||||
break;
|
||||
case 8:
|
||||
i = new Cast (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<JSType*>(node->operand[2].data));
|
||||
|
@ -188,7 +188,7 @@ namespace ICodeASM {
|
|||
i = new DeleteProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data));
|
||||
break;
|
||||
case 18:
|
||||
i = new DirectCall (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSFunction*>(node->operand[1].data), static_cast<ArgumentList>(node->operand[2].data));
|
||||
i = new DirectCall (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSFunction*>(node->operand[1].data), *(reinterpret_cast<ArgumentList *>(node->operand[2].data)));
|
||||
break;
|
||||
case 19:
|
||||
i = new Divide (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
|
|
|
@ -189,6 +189,8 @@ sub get_generator {
|
|||
for $p (@params) {
|
||||
if ($p eq "TypedRegister") {
|
||||
push (@args, "TypedRegister(static_cast<Register>(node->operand[$arg_num].data), 0)");
|
||||
} elsif ($p eq "ArgumentList") {
|
||||
push (@args, "*(reinterpret_cast<ArgumentList *>(node->operand[$arg_num].data))");
|
||||
} elsif ($p =~ /\*$/) {
|
||||
push (@args, "reinterpret_cast<$p>(node->operand[$arg_num].data)");
|
||||
} else {
|
||||
|
|
Загрузка…
Ссылка в новой задаче