This commit is contained in:
rogerl%netscape.com 2002-08-20 06:02:27 +00:00
Родитель 37ba77fecf
Коммит 6cfbc1ea9d
9 изменённых файлов: 96 добавлений и 70 удалений

Просмотреть файл

@ -42,10 +42,6 @@
#ifndef bytecodecontainer_h___
#define bytecodecontainer_h___
#include "world.h"
#include "utilities.h"
#include "js2value.h"
namespace JavaScript {
@ -60,7 +56,7 @@ public:
BytecodeContainer::~BytecodeContainer() ;
JS2Op *getCodeStart() { return (JS2Op *)(mBuffer->begin()); }
uint8 *getCodeStart() { return mBuffer->begin(); }
void emitOp(JS2Op op) { adjustStack(op); addByte((uint8)op); }
@ -71,11 +67,14 @@ public:
void addPointer(void *v) { ASSERT(sizeof(void *) == sizeof(uint32)); addLong((uint32)(v)); }
void addFloat64(float64 v) { mBuffer->insert(mBuffer->end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(float64)); }
static float64 getFloat64(void *pc) { return *((float64 *)pc); }
void addLong(uint32 v) { mBuffer->insert(mBuffer->end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(uint32)); }
static uint32 getLong(void *pc) { return *((uint32 *)pc); }
void addMultiname(Multiname *mn) { mMultinameList.push_back(mn); addPointer(mn); }
static Multiname *getMultiname(void *pc){ return (Multiname *)getLong(pc); }
typedef std::vector<uint8> CodeBuffer;
CodeBuffer *mBuffer;

Просмотреть файл

@ -31,11 +31,18 @@
#include <algorithm>
#include <assert.h>
#include "js2metadata.h"
#include "world.h"
#include "utilities.h"
#include "js2value.h"
#include <map>
#include <algorithm>
#include "reader.h"
#include "parser.h"
#include "js2engine.h"
#include "bytecodecontainer.h"
#include "js2metadata.h"
#ifdef DEBUG
#include "tracer.h"
@ -140,7 +147,7 @@ static int readEvalPrint(FILE *in)
metadata->setCurrentParser(&p); // for error reporting
metadata->ValidateStmtList(parsedStatements);
js2val rval = metadata->EvalStmtList(MetaData::RunPhase, parsedStatements);
js2val rval = metadata->EvalStmtList(RunPhase, parsedStatements);
if (!JS2VAL_IS_VOID(rval))
stdOut << *metadata->engine->toString(rval) << '\n';
}

Просмотреть файл

@ -41,26 +41,44 @@
#pragma warning(disable: 4710)
#endif
#include "numerics.h"
#include "js2metadata.h"
#include <algorithm>
#include <assert.h>
#include "world.h"
#include "utilities.h"
#include "js2value.h"
#include "numerics.h"
#include <map>
#include <algorithm>
#include "reader.h"
#include "parser.h"
#include "js2engine.h"
#include "bytecodecontainer.h"
#include "js2metadata.h"
namespace JavaScript {
namespace MetaData {
js2val JS2Engine::interpret(JS2Op *start)
js2val JS2Engine::interpret(JS2Metadata *metadata, Phase execPhase, uint8 *start)
{
pc = start;
meta = metadata;
phase = execPhase;
return interpreterLoop();
}
js2val JS2Engine::interpreterLoop()
{
js2val retval;
js2val retval = JS2VAL_VOID;
while (true) {
switch (*pc) {
JS2Op op = (JS2Op)*pc++;
switch (op) {
#include "js2op_arithmetic.cpp"
#include "js2op_invocation.cpp"
#include "js2op_access.cpp"
#include "js2op_literal.cpp"
}
}
return retval;
@ -69,7 +87,7 @@ js2val JS2Engine::interpreterLoop()
// return a pointer to an 8 byte chunk in the gc heap
void *JS2Engine::gc_alloc_8()
{
return NULL;
return STD::malloc(8);
}
// See if the double value is in the hash table, return it's pointer if so
@ -202,6 +220,7 @@ int JS2Engine::getStackEffect(JS2Op op)
return -1;
case eTrue:
case eFalse:
case eNumber:
return 1;
case eLexicalRead:
@ -209,6 +228,9 @@ int JS2Engine::getStackEffect(JS2Op op)
case eLexicalWrite:
return -1;
case eReturnVoid:
return 0;
default:
ASSERT(false);
}

Просмотреть файл

@ -52,19 +52,23 @@ enum JS2Op {
ePlus,
eTrue,
eFalse,
eNumber,
eLexicalRead, // <multiname index>
eLexicalWrite, // <multiname index>
eReturn
eReturn,
eReturnVoid
};
class JS2Metadata;
class JS2Engine {
public:
JS2Engine(World &world);
js2val interpret(JS2Op *start);
js2val interpret(JS2Metadata *metadata, Phase execPhase, uint8 *start);
js2val interpreterLoop();
@ -86,7 +90,9 @@ public:
js2val toPrimitive(js2val x) { if (JS2VAL_IS_PRIMITIVE(x)) return x; else return convertValueToPrimitive(x); }
float64 toNumber(js2val x) { if (JS2VAL_IS_INT(x)) return JS2VAL_TO_INT(x); else if (JS2VAL_IS_DOUBLE(x)) return *JS2VAL_TO_DOUBLE(x); else return convertValueToDouble(x); }
JS2Op *pc;
uint8 *pc;
JS2Metadata *meta;
Phase phase;
float64 *nanValue;
float64 *float64Table[256];

Просмотреть файл

@ -40,9 +40,6 @@
#endif
#include "js2metadata.h"
namespace JavaScript {
namespace MetaData {

Просмотреть файл

@ -41,8 +41,19 @@
#include <algorithm>
#include <assert.h>
#include "world.h"
#include "utilities.h"
#include "js2value.h"
#include <map>
#include <algorithm>
#include "reader.h"
#include "parser.h"
#include "js2engine.h"
#include "bytecodecontainer.h"
#include "js2metadata.h"
@ -150,15 +161,14 @@ namespace MetaData {
* Evaluate the linked list of statement nodes beginning at 'p' (generate bytecode)
* and then execute that bytecode
*/
js2val JS2Metadata::EvalStmtList(Phase phase, StmtNode *p) {
js2val retval = JS2VAL_VOID;
js2val JS2Metadata::EvalStmtList(Phase phase, StmtNode *p)
{
while (p) {
retval = EvalStmt(&env, phase, p);
EvalStmt(&env, phase, p);
p = p->next;
}
bCon->emitOp(eReturn);
engine->interpret(bCon->getCodeStart());
return retval;
bCon->emitOp(eReturnVoid);
return engine->interpret(this, phase, bCon->getCodeStart());
}
/*
@ -166,21 +176,24 @@ namespace MetaData {
* - this generates bytecode for each statement, but doesn't actually
* execute it.
*/
js2val JS2Metadata::EvalStmt(Environment *env, Phase phase, StmtNode *p)
void JS2Metadata::EvalStmt(Environment *env, Phase phase, StmtNode *p)
{
js2val retval = JS2VAL_VOID;
switch (p->getKind()) {
case StmtNode::block:
case StmtNode::group:
{
BlockStmtNode *b = checked_cast<BlockStmtNode *>(p);
retval = EvalStmtList(phase, b->statements);
StmtNode *bp = b->statements;
while (bp) {
EvalStmt(env, phase, bp);
bp = bp->next;
}
}
break;
case StmtNode::label:
{
LabelStmtNode *l = checked_cast<LabelStmtNode *>(p);
retval = EvalStmt(env, phase, l->stmt);
EvalStmt(env, phase, l->stmt);
}
break;
case StmtNode::Var:
@ -198,17 +211,13 @@ namespace MetaData {
case StmtNode::expression:
{
ExprStmtNode *e = checked_cast<ExprStmtNode *>(p);
retval = EvalExpression(env, phase, e->expr);
if (JS2VAL_IS_OBJECT(retval)) {
JS2Object *obj = JS2VAL_TO_OBJECT(retval);
}
Reference *r = EvalExprNode(env, phase, e->expr);
if (r) r->emitReadBytecode(bCon);
}
break;
default:
NOT_REACHED("Not Yet Implemented");
} // switch (p->getKind())
return retval;
}
@ -468,23 +477,18 @@ namespace MetaData {
/*
* Evaluate the expression rooted at p.
* Works by generating a JS string that represents the expression and then using
* the JS interpreter to execute that string against the current environment. The
* result is the value of this expression.
*
* Evaluate an expression 'p' and execute the assocaited bytecode
*/
js2val JS2Metadata::EvalExpression(Environment *env, Phase phase, ExprNode *p)
{
Reference *rVal = EvalExprNode(env, phase, p);
try {
}
catch (const char *err) {
reportError(Exception::internalError, err, p->pos);
return JS2VAL_VOID;
}
EvalExprNode(env, phase, p);
bCon->emitOp(eReturnVoid);
return engine->interpret(this, phase, bCon->getCodeStart());
}
/*
* Evaluate the expression rooted at p.
*/
Reference *JS2Metadata::EvalExprNode(Environment *env, Phase phase, ExprNode *p)
{
Reference *returnRef = NULL;
@ -499,11 +503,11 @@ namespace MetaData {
{
if (phase == CompilePhase) reportError(Exception::compileExpressionError, "Inappropriate compile time expression", p->pos);
BinaryExprNode *b = checked_cast<BinaryExprNode *>(p);
Reference *lVal = EvalExprNode(env, phase, b->op1);
if (lVal) {
returnRef = EvalExprNode(env, phase, b->op1);
if (returnRef) {
Reference *rVal = EvalExprNode(env, phase, b->op2);
if (rVal) rVal->emitReadBytecode(bCon);
lVal->emitWriteBytecode(bCon);
returnRef->emitWriteBytecode(bCon);
}
else
reportError(Exception::semanticError, "Assignment needs an lValue", p->pos);
@ -531,6 +535,8 @@ namespace MetaData {
case ExprNode::number:
{
bCon->emitOp(eNumber);
bCon->addFloat64(checked_cast<NumberExprNode *>(p)->value);
}
break;
case ExprNode::identifier:

Просмотреть файл

@ -36,18 +36,6 @@
#define js2metadata_h___
#include "world.h"
#include "utilities.h"
#include "parser.h"
#include "js2value.h"
#include "js2engine.h"
#include "bytecodecontainer.h"
#include <map>
namespace JavaScript {
namespace MetaData {
@ -60,14 +48,13 @@ class StaticBinding;
class Environment;
class Context;
class CompoundAttribute;
class BytecodeContainer;
typedef void (Invokable)();
typedef Invokable Callor;
typedef JS2Object *(Constructor)();
enum Phase { CompilePhase, RunPhase };
enum Access { ReadAccess, WriteAccess, ReadWriteAccess };
class JS2Object {
// Every object is either undefined, null, a Boolean,
@ -554,7 +541,7 @@ public:
js2val EvalExpression(Environment *env, Phase phase, ExprNode *p);
Reference *EvalExprNode(Environment *env, Phase phase, ExprNode *p);
Attribute *EvalAttributeExpression(Environment *env, Phase phase, ExprNode *p);
js2val EvalStmt(Environment *env, Phase phase, StmtNode *p);
void EvalStmt(Environment *env, Phase phase, StmtNode *p);
JS2Class *objectType(js2val obj);

Просмотреть файл

@ -136,6 +136,8 @@
#define JS2VAL_UNDEFINED JS2VAL_VOID
typedef uint32 js2val;
enum Phase { CompilePhase, RunPhase };
enum Access { ReadAccess, WriteAccess, ReadWriteAccess };
#endif

Просмотреть файл

@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "../../../src" /D "NDEBUG" /D "XP_" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "XP_PC" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "../../../src" /D "NDEBUG" /D "XP_" /D "_CONSOLE" /D "XP_PC" /D "WIN32" /D "_MBCS" /D "DIKDIK" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GR /GX /ZI /Od /I "../../../src" /I "../../../src/regexp" /D "_DEBUG" /D "XP_PC" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "DEBUG" /FR /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GR /GX /ZI /Od /I "../../../src" /I "../../../src/regexp" /D "_DEBUG" /D "_CONSOLE" /D "DEBUG" /D "XP_PC" /D "WIN32" /D "_MBCS" /D "DIKDIK" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe