Re-structuring some ICG details.

This commit is contained in:
rogerl%netscape.com 2001-02-02 01:04:22 +00:00
parent e50c963b41
commit 61579b22f3
12 changed files with 4246 additions and 4060 deletions

1985
js/js2/icodeEmitter.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -124,53 +124,10 @@ namespace ICG {
};
class ICodeModule;
typedef std::map<uint32, uint32, std::less<uint32> > InstructionMap;
class ICodeModule {
public:
ICodeModule(InstructionStream *iCode, VariableList *variables,
ParameterList *parameters,
uint32 maxRegister,
InstructionMap *instructionMap,
JSType *resultType, uint32 exceptionRegister) :
its_iCode(iCode), itsVariables(variables), itsParameters(parameters),
itsMaxRegister(maxRegister),
mID(++sMaxID), mInstructionMap(instructionMap),
mParameterInit(NULL),
mEntryPoint(0),
mResultType(resultType),
mExceptionRegister(exceptionRegister)
{
}
~ICodeModule()
{
delete its_iCode;
delete itsVariables;
delete mInstructionMap;
if (mParameterInit) delete mParameterInit;
}
Formatter& print(Formatter& f);
void setFileName (String aFileName) { mFileName = aFileName; }
String getFileName () { return mFileName; }
InstructionStream *its_iCode;
VariableList *itsVariables;
ParameterList *itsParameters;
uint32 itsMaxRegister;
uint32 mID;
InstructionMap *mInstructionMap;
String mFileName;
uint32 *mParameterInit;
uint32 mEntryPoint;
JSType *mResultType;
uint32 mExceptionRegister;
static uint32 sMaxID;
};
typedef std::vector<const StringAtom *> LabelSet;
class LabelEntry {
public:
@ -198,6 +155,7 @@ namespace ICG {
class ICodeGenerator {
public:
friend ICodeModule;
typedef enum { kNoFlags = 0, kIsTopLevel = 0x01, kIsStaticMethod = 0x02, kIsWithinWith = 0x04 } ICodeGeneratorFlags;
private:
InstructionStream *iCode;
@ -221,6 +179,7 @@ namespace ICG {
const StringAtom &mInitName;
ICodeGenerator *mContainingFunction;// outer function for nested functions
JSType *mResultType;
std::vector<bool> mPermanentRegister;
@ -241,7 +200,6 @@ namespace ICG {
TypedRegister allocateRegister(JSType *type);
JSType *findType(const StringAtom& typeName);
void addParameterLabel(Label *label) { if (pLabels == NULL) pLabels = new LabelList(); pLabels->push_back(label); }
@ -289,7 +247,11 @@ namespace ICG {
public:
ICodeGenerator(Context *cx, ICodeGenerator *containingFunction = NULL, JSClass *aClass = NULL, ICodeGeneratorFlags flags = kIsTopLevel);
ICodeGenerator(Context *cx,
ICodeGenerator *containingFunction = NULL,
JSClass *aClass = NULL,
ICodeGeneratorFlags flags = kIsTopLevel,
JSType *resultType = &Any_Type);
~ICodeGenerator()
{
@ -300,11 +262,8 @@ namespace ICG {
}
}
ICodeModule *complete(JSType *resultType);
ICodeModule *complete();
ICodeModule *readICode(const char *fileName);
JSType *extractType(ExprNode *t);
JSType *getParameterType(FunctionDefinition &function, int index);
TypedRegister genExpr(ExprNode *p,
bool needBoolValueInBranch = false,
@ -322,10 +281,7 @@ namespace ICG {
return allocateVariable(name, &Any_Type);
}
TypedRegister allocateVariable(const StringAtom& name, const StringAtom& typeName)
{
return allocateVariable(name, findType(typeName));
}
TypedRegister allocateVariable(const StringAtom& name, const StringAtom& typeName);
TypedRegister allocateVariable(const StringAtom& name, JSType *type)
{
@ -345,10 +301,7 @@ namespace ICG {
return allocateParameter(name, isOptional, &Any_Type);
}
TypedRegister allocateParameter(const StringAtom& name, bool isOptional, const StringAtom& typeName)
{
return allocateParameter(name, isOptional, findType(typeName));
}
TypedRegister allocateParameter(const StringAtom& name, bool isOptional, const StringAtom& typeName);
TypedRegister allocateParameter(const StringAtom& name, bool isOptional, JSType *type)
{
@ -421,10 +374,63 @@ namespace ICG {
Formatter& operator<<(Formatter &f, ICodeGenerator &i);
Formatter& operator<<(Formatter &f, ICodeModule &i);
Formatter& operator<<(Formatter &f, std::string &s);
/*
std::ostream &operator<<(std::ostream &s, ICodeGenerator &i);
std::ostream &operator<<(std::ostream &s, StringAtom &str);
*/
class ICodeModule {
public:
ICodeModule(InstructionStream *iCode, VariableList *variables,
ParameterList *parameters,
uint32 maxRegister,
InstructionMap *instructionMap,
JSType *resultType, uint32 exceptionRegister) :
its_iCode(iCode), itsVariables(variables), itsParameters(parameters),
itsMaxRegister(maxRegister),
mID(++sMaxID), mInstructionMap(instructionMap),
mParameterInit(NULL),
mEntryPoint(0),
mResultType(resultType),
mExceptionRegister(exceptionRegister)
{
}
ICodeModule(ICodeGenerator &icg) :
its_iCode(icg.iCode), itsVariables(icg.variableList), itsParameters(icg.parameterList),
itsMaxRegister(icg.mPermanentRegister.size()),
mID(++sMaxID), mInstructionMap(icg.mInstructionMap),
mParameterInit(NULL),
mEntryPoint(0),
mResultType(icg.mResultType),
mExceptionRegister(icg.mExceptionRegister.first)
{
}
~ICodeModule()
{
delete its_iCode;
delete itsVariables;
delete mInstructionMap;
if (mParameterInit) delete mParameterInit;
}
Formatter& print(Formatter& f);
void setFileName (String aFileName) { mFileName = aFileName; }
String getFileName () { return mFileName; }
InstructionStream *its_iCode;
VariableList *itsVariables;
ParameterList *itsParameters;
uint32 itsMaxRegister;
uint32 mID;
InstructionMap *mInstructionMap;
String mFileName;
uint32 *mParameterInit;
uint32 mEntryPoint;
JSType *mResultType;
uint32 mExceptionRegister;
static uint32 sMaxID;
};

View File

@ -82,9 +82,9 @@ ICodeModule* Context::compileFunction(const String &source)
String filename = widenCString("Some source source");
Parser p(getWorld(), a, source, filename);
ExprNode* e = p.parseExpression(false);
ICodeGenerator icg(this);
ASSERT(e->getKind() == ExprNode::functionLiteral);
FunctionExprNode* f = static_cast<FunctionExprNode*>(e);
ICodeGenerator icg(this, NULL, NULL, ICodeGenerator::kIsTopLevel, extractType(f->function.resultType));
icg.allocateParameter(getWorld().identifiers["this"], false); // always parameter #0
VariableBinding* v = f->function.parameters;
while (v) {
@ -93,7 +93,7 @@ ICodeModule* Context::compileFunction(const String &source)
v = v->next;
}
icg.genStmt(f->function.body);
ICodeModule* result = icg.complete(icg.extractType(f->function.resultType));
ICodeModule* result = icg.complete();
result->setFileName(filename);
return result;
}
@ -143,7 +143,7 @@ JSValue Context::readEvalFile(FILE* in, const String& fileName)
ICodeModule* Context::genCode(StmtNode *p, const String &fileName)
{
ICodeGenerator icg(this);
ICodeGenerator icg(this, NULL, NULL, ICodeGenerator::kIsTopLevel, &Void_Type);
TypedRegister ret(NotARegister, &None_Type);
while (p) {
@ -152,7 +152,7 @@ ICodeModule* Context::genCode(StmtNode *p, const String &fileName)
}
icg.returnStmt(ret);
ICodeModule *icm = icg.complete(&Void_Type);
ICodeModule *icm = icg.complete();
icm->setFileName(fileName);
return icm;
}
@ -1595,6 +1595,40 @@ void Context::broadcast(Event event)
}
}
/* Helper functions for extracting types from expression trees */
JSType *Context::findType(const StringAtom& typeName)
{
const JSValue& type = getGlobalObject()->getVariable(typeName);
if (type.isType())
return type.type;
return &Any_Type;
}
JSType *Context::extractType(ExprNode *t)
{
JSType* type = &Any_Type;
if (t && (t->getKind() == ExprNode::identifier)) {
IdentifierExprNode* typeExpr = static_cast<IdentifierExprNode*>(t);
type = findType(typeExpr->name);
}
return type;
}
JSType *Context::getParameterType(FunctionDefinition &function, int index)
{
VariableBinding *v = function.parameters;
while (v) {
if (index-- == 0)
return extractType(v->type);
else
v = v->next;
}
return NULL;
}
Context::Frame* Context::getFrames()
{
return mLinkage;

View File

@ -85,6 +85,10 @@ namespace Interpreter {
const JSValue findBinaryOverride(JSValue &operand1, JSValue &operand2, ExprNode::Kind op);
JSType *findType(const StringAtom& typeName);
JSType *extractType(ExprNode *t);
JSType *getParameterType(FunctionDefinition &function, int index);
private:
void broadcast(Event event);
void initOperatorsPackage();

View File

@ -361,13 +361,13 @@ static void testCompile()
Arena a;
Parser p(world, a, testScript, widenCString("testCompile"));
StmtNode *parsedStatements = p.parseProgram();
ICodeGenerator icg(&cx);
ICodeGenerator icg(&cx, NULL, NULL, ICodeGenerator::kIsTopLevel, &Void_Type);
StmtNode *s = parsedStatements;
while (s) {
icg.genStmt(s);
s = s->next;
}
JSValue result = cx.interpret(icg.complete(&Void_Type), JSValues());
JSValue result = cx.interpret(icg.complete(), JSValues());
stdOut << "result = " << result << "\n";
}
}

1985
js2/src/icodeEmitter.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -124,53 +124,10 @@ namespace ICG {
};
class ICodeModule;
typedef std::map<uint32, uint32, std::less<uint32> > InstructionMap;
class ICodeModule {
public:
ICodeModule(InstructionStream *iCode, VariableList *variables,
ParameterList *parameters,
uint32 maxRegister,
InstructionMap *instructionMap,
JSType *resultType, uint32 exceptionRegister) :
its_iCode(iCode), itsVariables(variables), itsParameters(parameters),
itsMaxRegister(maxRegister),
mID(++sMaxID), mInstructionMap(instructionMap),
mParameterInit(NULL),
mEntryPoint(0),
mResultType(resultType),
mExceptionRegister(exceptionRegister)
{
}
~ICodeModule()
{
delete its_iCode;
delete itsVariables;
delete mInstructionMap;
if (mParameterInit) delete mParameterInit;
}
Formatter& print(Formatter& f);
void setFileName (String aFileName) { mFileName = aFileName; }
String getFileName () { return mFileName; }
InstructionStream *its_iCode;
VariableList *itsVariables;
ParameterList *itsParameters;
uint32 itsMaxRegister;
uint32 mID;
InstructionMap *mInstructionMap;
String mFileName;
uint32 *mParameterInit;
uint32 mEntryPoint;
JSType *mResultType;
uint32 mExceptionRegister;
static uint32 sMaxID;
};
typedef std::vector<const StringAtom *> LabelSet;
class LabelEntry {
public:
@ -198,6 +155,7 @@ namespace ICG {
class ICodeGenerator {
public:
friend ICodeModule;
typedef enum { kNoFlags = 0, kIsTopLevel = 0x01, kIsStaticMethod = 0x02, kIsWithinWith = 0x04 } ICodeGeneratorFlags;
private:
InstructionStream *iCode;
@ -221,6 +179,7 @@ namespace ICG {
const StringAtom &mInitName;
ICodeGenerator *mContainingFunction;// outer function for nested functions
JSType *mResultType;
std::vector<bool> mPermanentRegister;
@ -241,7 +200,6 @@ namespace ICG {
TypedRegister allocateRegister(JSType *type);
JSType *findType(const StringAtom& typeName);
void addParameterLabel(Label *label) { if (pLabels == NULL) pLabels = new LabelList(); pLabels->push_back(label); }
@ -289,7 +247,11 @@ namespace ICG {
public:
ICodeGenerator(Context *cx, ICodeGenerator *containingFunction = NULL, JSClass *aClass = NULL, ICodeGeneratorFlags flags = kIsTopLevel);
ICodeGenerator(Context *cx,
ICodeGenerator *containingFunction = NULL,
JSClass *aClass = NULL,
ICodeGeneratorFlags flags = kIsTopLevel,
JSType *resultType = &Any_Type);
~ICodeGenerator()
{
@ -300,11 +262,8 @@ namespace ICG {
}
}
ICodeModule *complete(JSType *resultType);
ICodeModule *complete();
ICodeModule *readICode(const char *fileName);
JSType *extractType(ExprNode *t);
JSType *getParameterType(FunctionDefinition &function, int index);
TypedRegister genExpr(ExprNode *p,
bool needBoolValueInBranch = false,
@ -322,10 +281,7 @@ namespace ICG {
return allocateVariable(name, &Any_Type);
}
TypedRegister allocateVariable(const StringAtom& name, const StringAtom& typeName)
{
return allocateVariable(name, findType(typeName));
}
TypedRegister allocateVariable(const StringAtom& name, const StringAtom& typeName);
TypedRegister allocateVariable(const StringAtom& name, JSType *type)
{
@ -345,10 +301,7 @@ namespace ICG {
return allocateParameter(name, isOptional, &Any_Type);
}
TypedRegister allocateParameter(const StringAtom& name, bool isOptional, const StringAtom& typeName)
{
return allocateParameter(name, isOptional, findType(typeName));
}
TypedRegister allocateParameter(const StringAtom& name, bool isOptional, const StringAtom& typeName);
TypedRegister allocateParameter(const StringAtom& name, bool isOptional, JSType *type)
{
@ -421,10 +374,63 @@ namespace ICG {
Formatter& operator<<(Formatter &f, ICodeGenerator &i);
Formatter& operator<<(Formatter &f, ICodeModule &i);
Formatter& operator<<(Formatter &f, std::string &s);
/*
std::ostream &operator<<(std::ostream &s, ICodeGenerator &i);
std::ostream &operator<<(std::ostream &s, StringAtom &str);
*/
class ICodeModule {
public:
ICodeModule(InstructionStream *iCode, VariableList *variables,
ParameterList *parameters,
uint32 maxRegister,
InstructionMap *instructionMap,
JSType *resultType, uint32 exceptionRegister) :
its_iCode(iCode), itsVariables(variables), itsParameters(parameters),
itsMaxRegister(maxRegister),
mID(++sMaxID), mInstructionMap(instructionMap),
mParameterInit(NULL),
mEntryPoint(0),
mResultType(resultType),
mExceptionRegister(exceptionRegister)
{
}
ICodeModule(ICodeGenerator &icg) :
its_iCode(icg.iCode), itsVariables(icg.variableList), itsParameters(icg.parameterList),
itsMaxRegister(icg.mPermanentRegister.size()),
mID(++sMaxID), mInstructionMap(icg.mInstructionMap),
mParameterInit(NULL),
mEntryPoint(0),
mResultType(icg.mResultType),
mExceptionRegister(icg.mExceptionRegister.first)
{
}
~ICodeModule()
{
delete its_iCode;
delete itsVariables;
delete mInstructionMap;
if (mParameterInit) delete mParameterInit;
}
Formatter& print(Formatter& f);
void setFileName (String aFileName) { mFileName = aFileName; }
String getFileName () { return mFileName; }
InstructionStream *its_iCode;
VariableList *itsVariables;
ParameterList *itsParameters;
uint32 itsMaxRegister;
uint32 mID;
InstructionMap *mInstructionMap;
String mFileName;
uint32 *mParameterInit;
uint32 mEntryPoint;
JSType *mResultType;
uint32 mExceptionRegister;
static uint32 sMaxID;
};

View File

@ -82,9 +82,9 @@ ICodeModule* Context::compileFunction(const String &source)
String filename = widenCString("Some source source");
Parser p(getWorld(), a, source, filename);
ExprNode* e = p.parseExpression(false);
ICodeGenerator icg(this);
ASSERT(e->getKind() == ExprNode::functionLiteral);
FunctionExprNode* f = static_cast<FunctionExprNode*>(e);
ICodeGenerator icg(this, NULL, NULL, ICodeGenerator::kIsTopLevel, extractType(f->function.resultType));
icg.allocateParameter(getWorld().identifiers["this"], false); // always parameter #0
VariableBinding* v = f->function.parameters;
while (v) {
@ -93,7 +93,7 @@ ICodeModule* Context::compileFunction(const String &source)
v = v->next;
}
icg.genStmt(f->function.body);
ICodeModule* result = icg.complete(icg.extractType(f->function.resultType));
ICodeModule* result = icg.complete();
result->setFileName(filename);
return result;
}
@ -143,7 +143,7 @@ JSValue Context::readEvalFile(FILE* in, const String& fileName)
ICodeModule* Context::genCode(StmtNode *p, const String &fileName)
{
ICodeGenerator icg(this);
ICodeGenerator icg(this, NULL, NULL, ICodeGenerator::kIsTopLevel, &Void_Type);
TypedRegister ret(NotARegister, &None_Type);
while (p) {
@ -152,7 +152,7 @@ ICodeModule* Context::genCode(StmtNode *p, const String &fileName)
}
icg.returnStmt(ret);
ICodeModule *icm = icg.complete(&Void_Type);
ICodeModule *icm = icg.complete();
icm->setFileName(fileName);
return icm;
}
@ -1595,6 +1595,40 @@ void Context::broadcast(Event event)
}
}
/* Helper functions for extracting types from expression trees */
JSType *Context::findType(const StringAtom& typeName)
{
const JSValue& type = getGlobalObject()->getVariable(typeName);
if (type.isType())
return type.type;
return &Any_Type;
}
JSType *Context::extractType(ExprNode *t)
{
JSType* type = &Any_Type;
if (t && (t->getKind() == ExprNode::identifier)) {
IdentifierExprNode* typeExpr = static_cast<IdentifierExprNode*>(t);
type = findType(typeExpr->name);
}
return type;
}
JSType *Context::getParameterType(FunctionDefinition &function, int index)
{
VariableBinding *v = function.parameters;
while (v) {
if (index-- == 0)
return extractType(v->type);
else
v = v->next;
}
return NULL;
}
Context::Frame* Context::getFrames()
{
return mLinkage;

View File

@ -85,6 +85,10 @@ namespace Interpreter {
const JSValue findBinaryOverride(JSValue &operand1, JSValue &operand2, ExprNode::Kind op);
JSType *findType(const StringAtom& typeName);
JSType *extractType(ExprNode *t);
JSType *getParameterType(FunctionDefinition &function, int index);
private:
void broadcast(Event event);
void initOperatorsPackage();

View File

@ -361,13 +361,13 @@ static void testCompile()
Arena a;
Parser p(world, a, testScript, widenCString("testCompile"));
StmtNode *parsedStatements = p.parseProgram();
ICodeGenerator icg(&cx);
ICodeGenerator icg(&cx, NULL, NULL, ICodeGenerator::kIsTopLevel, &Void_Type);
StmtNode *s = parsedStatements;
while (s) {
icg.genStmt(s);
s = s->next;
}
JSValue result = cx.interpret(icg.complete(&Void_Type), JSValues());
JSValue result = cx.interpret(icg.complete(), JSValues());
stdOut << "result = " << result << "\n";
}
}