mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-26 04:09:50 +00:00
Added <function> at top level and example thereof.
This commit is contained in:
parent
9f5f1efcf7
commit
14a70a0c8c
@ -38,7 +38,6 @@
|
||||
#include "jsclasses.h"
|
||||
#include "icodegenerator.h"
|
||||
#include "interpreter.h"
|
||||
#include "xmlparser.h"
|
||||
#include "exception.h"
|
||||
#include "icodeasm.h"
|
||||
|
||||
@ -2561,6 +2560,55 @@ Formatter& operator<<(Formatter &f, string &s)
|
||||
return f;
|
||||
}
|
||||
|
||||
ICodeModule *ICodeGenerator::readFunction(XMLNode *element, String &name, JSClass *thisClass)
|
||||
{
|
||||
ICodeModule *result = NULL;
|
||||
|
||||
String resultTypeName;
|
||||
element->getValue(widenCString("type"), resultTypeName);
|
||||
ParameterList *theParameterList = new ParameterList();
|
||||
theParameterList->add(mContext->getWorld().identifiers["this"], TypedRegister(0, thisClass), false);
|
||||
uint32 pCount = 1;
|
||||
StringFormatter s;
|
||||
XMLNodeList ¶meters = element->children();
|
||||
for (XMLNodeList::const_iterator k = parameters.begin(); k != parameters.end(); k++) {
|
||||
XMLNode *parameter = *k;
|
||||
if (parameter->name().compare(widenCString("parameter")) == 0) {
|
||||
String parameterName;
|
||||
String parameterTypeName;
|
||||
element->getValue(widenCString("name"), parameterName);
|
||||
element->getValue(widenCString("type"), parameterTypeName);
|
||||
JSType *parameterType = findType(mContext->getWorld().identifiers[parameterTypeName]);
|
||||
theParameterList->add(mContext->getWorld().identifiers[parameterName], TypedRegister(pCount, parameterType), false);
|
||||
s << pCount - 1;
|
||||
theParameterList->add(mContext->getWorld().identifiers[s.getString()], TypedRegister(pCount, parameterType), false);
|
||||
s.clear();
|
||||
pCount++;
|
||||
}
|
||||
}
|
||||
theParameterList->setPositionalCount(pCount);
|
||||
|
||||
JSType *resultType = findType(mContext->getWorld().identifiers[resultTypeName]);
|
||||
String &body = element->body();
|
||||
if (body.length()) {
|
||||
std::string str(body.length(), char());
|
||||
std::transform(body.begin(), body.end(), str.begin(), narrow);
|
||||
ICodeParser icp(mContext);
|
||||
|
||||
stdOut << "Calling ICodeParser with :\n" << str << "\n";
|
||||
|
||||
icp.parseSourceFromString(str);
|
||||
|
||||
result = new ICodeModule(icp.mInstructions,
|
||||
NULL, /* VariableList *variables */
|
||||
theParameterList, /* ParameterList *parameters */
|
||||
icp.mMaxRegister,
|
||||
NULL, /* InstructionMap *instructionMap */
|
||||
resultType,
|
||||
NotABanana); /* exception register */
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ICodeModule *ICodeGenerator::readICode(const char *fileName)
|
||||
{
|
||||
@ -2594,56 +2642,16 @@ ICodeModule *ICodeGenerator::readICode(const char *fileName)
|
||||
|
||||
mContext->getGlobalObject()->defineVariable(className, &Type_Type, JSValue(thisClass));
|
||||
|
||||
// bool hasDefaultConstructor = false;
|
||||
XMLNodeList &elements = node->children();
|
||||
for (XMLNodeList::const_iterator j = elements.begin(); j != elements.end(); j++) {
|
||||
XMLNode *element = *j;
|
||||
bool isConstructor = (element->name().compare(widenCString("constructor")) == 0);
|
||||
|
||||
if (isConstructor || (element->name().compare(widenCString("method")) == 0)) {
|
||||
String methodName, resultTypeName;
|
||||
element->getValue(widenCString("name"), methodName);
|
||||
element->getValue(widenCString("type"), resultTypeName);
|
||||
ParameterList *theParameterList = new ParameterList();
|
||||
theParameterList->add(mContext->getWorld().identifiers["this"], TypedRegister(0, thisClass), false);
|
||||
uint32 pCount = 1;
|
||||
StringFormatter s;
|
||||
XMLNodeList ¶meters = element->children();
|
||||
for (XMLNodeList::const_iterator k = parameters.begin(); k != parameters.end(); k++) {
|
||||
XMLNode *parameter = *k;
|
||||
if (parameter->name().compare(widenCString("parameter")) == 0) {
|
||||
String parameterName;
|
||||
String parameterTypeName;
|
||||
element->getValue(widenCString("name"), parameterName);
|
||||
element->getValue(widenCString("type"), parameterTypeName);
|
||||
JSType *parameterType = findType(mContext->getWorld().identifiers[parameterTypeName]);
|
||||
theParameterList->add(mContext->getWorld().identifiers[parameterName], TypedRegister(pCount, parameterType), false);
|
||||
s << pCount - 1;
|
||||
theParameterList->add(mContext->getWorld().identifiers[s.getString()], TypedRegister(pCount, parameterType), false);
|
||||
s.clear();
|
||||
pCount++;
|
||||
}
|
||||
}
|
||||
theParameterList->setPositionalCount(pCount);
|
||||
|
||||
JSType *resultType = findType(mContext->getWorld().identifiers[resultTypeName]);
|
||||
String &body = element->body();
|
||||
if (body.length()) {
|
||||
std::string str(body.length(), char());
|
||||
std::transform(body.begin(), body.end(), str.begin(), narrow);
|
||||
ICodeParser icp(mContext);
|
||||
|
||||
stdOut << "Calling ICodeParser with :\n" << str << "\n";
|
||||
|
||||
icp.parseSourceFromString(str);
|
||||
|
||||
ICodeModule *icm = new ICodeModule(icp.mInstructions,
|
||||
NULL, /* VariableList *variables */
|
||||
theParameterList, /* ParameterList *parameters */
|
||||
icp.mMaxRegister,
|
||||
NULL, /* InstructionMap *instructionMap */
|
||||
resultType,
|
||||
NotABanana); /* exception register */
|
||||
String methodName;
|
||||
node->getValue(widenCString("name"), methodName);
|
||||
ICodeModule *icm = readFunction(element, methodName, thisClass);
|
||||
if (icm) {
|
||||
if (isConstructor) {
|
||||
thisClass->defineConstructor(methodName);
|
||||
scg.setStatic(thisClass, mContext->getWorld().identifiers[methodName], scg.newFunction(icm));
|
||||
@ -2669,21 +2677,6 @@ ICodeModule *ICodeGenerator::readICode(const char *fileName)
|
||||
}
|
||||
}
|
||||
scg.setStatic(thisClass, mInitName, scg.newFunction(ccg.complete(&Void_Type)));
|
||||
/*
|
||||
if (!hasDefaultConstructor) {
|
||||
TypedRegister thisValue = TypedRegister(0, thisClass);
|
||||
ArgumentList *args = new ArgumentList(0);
|
||||
ICodeGenerator icg(mContext, NULL, thisClass, kIsStaticMethod);
|
||||
icg.allocateParameter(mContext->getWorld().identifiers["this"], false, thisClass); // always parameter #0
|
||||
if (superclass)
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(superclass, superclass->getName())), args);
|
||||
if (thisClass->hasStatic(mInitName))
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(thisClass, mInitName)), args);
|
||||
icg.returnStmt(thisValue);
|
||||
thisClass->defineConstructor(className);
|
||||
scg.setStatic(thisClass, mContext->getWorld().identifiers[className], scg.newFunction(icg.complete(&Void_Type)));
|
||||
}
|
||||
*/
|
||||
thisClass->complete();
|
||||
|
||||
if (scg.getICode()->size()) {
|
||||
@ -2715,12 +2708,20 @@ ICodeModule *ICodeGenerator::readICode(const char *fileName)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (node->name().compare(widenCString("instance")) == 0) {
|
||||
// find the appropriate class and initialize the fields
|
||||
if (node->name().compare(widenCString("function")) == 0) {
|
||||
String functionName;
|
||||
node->getValue(widenCString("name"), functionName);
|
||||
ICodeModule *icm = readFunction(node, functionName, NULL);
|
||||
mContext->getGlobalObject()->defineFunction(functionName, icm);
|
||||
}
|
||||
else {
|
||||
if (node->name().compare(widenCString("object")) == 0) {
|
||||
// an object literal
|
||||
if (node->name().compare(widenCString("instance")) == 0) {
|
||||
// find the appropriate class and initialize the fields
|
||||
}
|
||||
else {
|
||||
if (node->name().compare(widenCString("object")) == 0) {
|
||||
// an object literal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "parser.h"
|
||||
#include "vmtypes.h"
|
||||
#include "jsclasses.h"
|
||||
#include "xmlparser.h"
|
||||
|
||||
|
||||
namespace JavaScript {
|
||||
@ -282,7 +283,10 @@ namespace ICG {
|
||||
TypedRegister handleIdentifier(IdentifierExprNode *p, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, ArgumentList *args, bool lvalue);
|
||||
TypedRegister handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, ArgumentList *args, bool lvalue);
|
||||
ICodeModule *genFunction(FunctionDefinition &function, bool isStatic, bool isConstructor, JSClass *superClass);
|
||||
|
||||
|
||||
|
||||
ICodeModule *readFunction(XMLNode *element, String &name, JSClass *thisClass);
|
||||
|
||||
public:
|
||||
|
||||
ICodeGenerator(Context *cx, ICodeGenerator *containingFunction = NULL, JSClass *aClass = NULL, ICodeGeneratorFlags flags = kIsTopLevel);
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "world.h"
|
||||
#include "interpreter.h"
|
||||
#include "icodegenerator.h"
|
||||
#include "xmlparser.h"
|
||||
|
||||
#ifdef DEBUGGER_FOO
|
||||
#include "debugger.h"
|
||||
|
@ -15,7 +15,35 @@
|
||||
</class>
|
||||
|
||||
|
||||
<class name="E" super="D">
|
||||
<constructor name="E">
|
||||
GET_STATIC R1, "D", 1
|
||||
BIND_THIS R2, R0, R1
|
||||
CALL R3, R2, () <!-- call to superclass constructor -->
|
||||
RETURN R0
|
||||
</constructor>
|
||||
</class>
|
||||
|
||||
<function name="fn1" type="Void">
|
||||
NEW_CLASS R2, "E"
|
||||
GET_STATIC R3, "E", 1
|
||||
BIND_THIS R4, R2, R3
|
||||
CALL R1, R4, ()
|
||||
LOAD_IMMEDIATE R2, 1
|
||||
LOAD_IMMEDIATE R3, 4
|
||||
GET_METHOD R4, R1, 0 <!-- virtual call to 'bar' in D -->
|
||||
CALL R5, R4, (R2, R3)
|
||||
GET_SLOT R2, R1, 0
|
||||
LOAD_NAME R1, "print"
|
||||
CALL R1, R1, (R2)
|
||||
RETURN_VOID
|
||||
</function>
|
||||
|
||||
|
||||
<script>
|
||||
LOAD_NAME R1, "fn1"
|
||||
CALL R1, R1, ()
|
||||
|
||||
NEW_CLASS R2, "D"
|
||||
GET_STATIC R3, "D", 1 <!-- 0'th static is __init__ -->
|
||||
<!-- 1st static is D::D constructor -->
|
||||
@ -27,6 +55,5 @@
|
||||
CALL R5, R4, (R2, R3)
|
||||
GET_SLOT R2, R1, 0
|
||||
RETURN R2
|
||||
|
||||
|
||||
</script>
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "jsclasses.h"
|
||||
#include "icodegenerator.h"
|
||||
#include "interpreter.h"
|
||||
#include "xmlparser.h"
|
||||
#include "exception.h"
|
||||
#include "icodeasm.h"
|
||||
|
||||
@ -2561,6 +2560,55 @@ Formatter& operator<<(Formatter &f, string &s)
|
||||
return f;
|
||||
}
|
||||
|
||||
ICodeModule *ICodeGenerator::readFunction(XMLNode *element, String &name, JSClass *thisClass)
|
||||
{
|
||||
ICodeModule *result = NULL;
|
||||
|
||||
String resultTypeName;
|
||||
element->getValue(widenCString("type"), resultTypeName);
|
||||
ParameterList *theParameterList = new ParameterList();
|
||||
theParameterList->add(mContext->getWorld().identifiers["this"], TypedRegister(0, thisClass), false);
|
||||
uint32 pCount = 1;
|
||||
StringFormatter s;
|
||||
XMLNodeList ¶meters = element->children();
|
||||
for (XMLNodeList::const_iterator k = parameters.begin(); k != parameters.end(); k++) {
|
||||
XMLNode *parameter = *k;
|
||||
if (parameter->name().compare(widenCString("parameter")) == 0) {
|
||||
String parameterName;
|
||||
String parameterTypeName;
|
||||
element->getValue(widenCString("name"), parameterName);
|
||||
element->getValue(widenCString("type"), parameterTypeName);
|
||||
JSType *parameterType = findType(mContext->getWorld().identifiers[parameterTypeName]);
|
||||
theParameterList->add(mContext->getWorld().identifiers[parameterName], TypedRegister(pCount, parameterType), false);
|
||||
s << pCount - 1;
|
||||
theParameterList->add(mContext->getWorld().identifiers[s.getString()], TypedRegister(pCount, parameterType), false);
|
||||
s.clear();
|
||||
pCount++;
|
||||
}
|
||||
}
|
||||
theParameterList->setPositionalCount(pCount);
|
||||
|
||||
JSType *resultType = findType(mContext->getWorld().identifiers[resultTypeName]);
|
||||
String &body = element->body();
|
||||
if (body.length()) {
|
||||
std::string str(body.length(), char());
|
||||
std::transform(body.begin(), body.end(), str.begin(), narrow);
|
||||
ICodeParser icp(mContext);
|
||||
|
||||
stdOut << "Calling ICodeParser with :\n" << str << "\n";
|
||||
|
||||
icp.parseSourceFromString(str);
|
||||
|
||||
result = new ICodeModule(icp.mInstructions,
|
||||
NULL, /* VariableList *variables */
|
||||
theParameterList, /* ParameterList *parameters */
|
||||
icp.mMaxRegister,
|
||||
NULL, /* InstructionMap *instructionMap */
|
||||
resultType,
|
||||
NotABanana); /* exception register */
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ICodeModule *ICodeGenerator::readICode(const char *fileName)
|
||||
{
|
||||
@ -2594,56 +2642,16 @@ ICodeModule *ICodeGenerator::readICode(const char *fileName)
|
||||
|
||||
mContext->getGlobalObject()->defineVariable(className, &Type_Type, JSValue(thisClass));
|
||||
|
||||
// bool hasDefaultConstructor = false;
|
||||
XMLNodeList &elements = node->children();
|
||||
for (XMLNodeList::const_iterator j = elements.begin(); j != elements.end(); j++) {
|
||||
XMLNode *element = *j;
|
||||
bool isConstructor = (element->name().compare(widenCString("constructor")) == 0);
|
||||
|
||||
if (isConstructor || (element->name().compare(widenCString("method")) == 0)) {
|
||||
String methodName, resultTypeName;
|
||||
element->getValue(widenCString("name"), methodName);
|
||||
element->getValue(widenCString("type"), resultTypeName);
|
||||
ParameterList *theParameterList = new ParameterList();
|
||||
theParameterList->add(mContext->getWorld().identifiers["this"], TypedRegister(0, thisClass), false);
|
||||
uint32 pCount = 1;
|
||||
StringFormatter s;
|
||||
XMLNodeList ¶meters = element->children();
|
||||
for (XMLNodeList::const_iterator k = parameters.begin(); k != parameters.end(); k++) {
|
||||
XMLNode *parameter = *k;
|
||||
if (parameter->name().compare(widenCString("parameter")) == 0) {
|
||||
String parameterName;
|
||||
String parameterTypeName;
|
||||
element->getValue(widenCString("name"), parameterName);
|
||||
element->getValue(widenCString("type"), parameterTypeName);
|
||||
JSType *parameterType = findType(mContext->getWorld().identifiers[parameterTypeName]);
|
||||
theParameterList->add(mContext->getWorld().identifiers[parameterName], TypedRegister(pCount, parameterType), false);
|
||||
s << pCount - 1;
|
||||
theParameterList->add(mContext->getWorld().identifiers[s.getString()], TypedRegister(pCount, parameterType), false);
|
||||
s.clear();
|
||||
pCount++;
|
||||
}
|
||||
}
|
||||
theParameterList->setPositionalCount(pCount);
|
||||
|
||||
JSType *resultType = findType(mContext->getWorld().identifiers[resultTypeName]);
|
||||
String &body = element->body();
|
||||
if (body.length()) {
|
||||
std::string str(body.length(), char());
|
||||
std::transform(body.begin(), body.end(), str.begin(), narrow);
|
||||
ICodeParser icp(mContext);
|
||||
|
||||
stdOut << "Calling ICodeParser with :\n" << str << "\n";
|
||||
|
||||
icp.parseSourceFromString(str);
|
||||
|
||||
ICodeModule *icm = new ICodeModule(icp.mInstructions,
|
||||
NULL, /* VariableList *variables */
|
||||
theParameterList, /* ParameterList *parameters */
|
||||
icp.mMaxRegister,
|
||||
NULL, /* InstructionMap *instructionMap */
|
||||
resultType,
|
||||
NotABanana); /* exception register */
|
||||
String methodName;
|
||||
node->getValue(widenCString("name"), methodName);
|
||||
ICodeModule *icm = readFunction(element, methodName, thisClass);
|
||||
if (icm) {
|
||||
if (isConstructor) {
|
||||
thisClass->defineConstructor(methodName);
|
||||
scg.setStatic(thisClass, mContext->getWorld().identifiers[methodName], scg.newFunction(icm));
|
||||
@ -2669,21 +2677,6 @@ ICodeModule *ICodeGenerator::readICode(const char *fileName)
|
||||
}
|
||||
}
|
||||
scg.setStatic(thisClass, mInitName, scg.newFunction(ccg.complete(&Void_Type)));
|
||||
/*
|
||||
if (!hasDefaultConstructor) {
|
||||
TypedRegister thisValue = TypedRegister(0, thisClass);
|
||||
ArgumentList *args = new ArgumentList(0);
|
||||
ICodeGenerator icg(mContext, NULL, thisClass, kIsStaticMethod);
|
||||
icg.allocateParameter(mContext->getWorld().identifiers["this"], false, thisClass); // always parameter #0
|
||||
if (superclass)
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(superclass, superclass->getName())), args);
|
||||
if (thisClass->hasStatic(mInitName))
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(thisClass, mInitName)), args);
|
||||
icg.returnStmt(thisValue);
|
||||
thisClass->defineConstructor(className);
|
||||
scg.setStatic(thisClass, mContext->getWorld().identifiers[className], scg.newFunction(icg.complete(&Void_Type)));
|
||||
}
|
||||
*/
|
||||
thisClass->complete();
|
||||
|
||||
if (scg.getICode()->size()) {
|
||||
@ -2715,12 +2708,20 @@ ICodeModule *ICodeGenerator::readICode(const char *fileName)
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (node->name().compare(widenCString("instance")) == 0) {
|
||||
// find the appropriate class and initialize the fields
|
||||
if (node->name().compare(widenCString("function")) == 0) {
|
||||
String functionName;
|
||||
node->getValue(widenCString("name"), functionName);
|
||||
ICodeModule *icm = readFunction(node, functionName, NULL);
|
||||
mContext->getGlobalObject()->defineFunction(functionName, icm);
|
||||
}
|
||||
else {
|
||||
if (node->name().compare(widenCString("object")) == 0) {
|
||||
// an object literal
|
||||
if (node->name().compare(widenCString("instance")) == 0) {
|
||||
// find the appropriate class and initialize the fields
|
||||
}
|
||||
else {
|
||||
if (node->name().compare(widenCString("object")) == 0) {
|
||||
// an object literal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "parser.h"
|
||||
#include "vmtypes.h"
|
||||
#include "jsclasses.h"
|
||||
#include "xmlparser.h"
|
||||
|
||||
|
||||
namespace JavaScript {
|
||||
@ -282,7 +283,10 @@ namespace ICG {
|
||||
TypedRegister handleIdentifier(IdentifierExprNode *p, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, ArgumentList *args, bool lvalue);
|
||||
TypedRegister handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, ArgumentList *args, bool lvalue);
|
||||
ICodeModule *genFunction(FunctionDefinition &function, bool isStatic, bool isConstructor, JSClass *superClass);
|
||||
|
||||
|
||||
|
||||
ICodeModule *readFunction(XMLNode *element, String &name, JSClass *thisClass);
|
||||
|
||||
public:
|
||||
|
||||
ICodeGenerator(Context *cx, ICodeGenerator *containingFunction = NULL, JSClass *aClass = NULL, ICodeGeneratorFlags flags = kIsTopLevel);
|
||||
|
@ -15,7 +15,35 @@
|
||||
</class>
|
||||
|
||||
|
||||
<class name="E" super="D">
|
||||
<constructor name="E">
|
||||
GET_STATIC R1, "D", 1
|
||||
BIND_THIS R2, R0, R1
|
||||
CALL R3, R2, () <!-- call to superclass constructor -->
|
||||
RETURN R0
|
||||
</constructor>
|
||||
</class>
|
||||
|
||||
<function name="fn1" type="Void">
|
||||
NEW_CLASS R2, "E"
|
||||
GET_STATIC R3, "E", 1
|
||||
BIND_THIS R4, R2, R3
|
||||
CALL R1, R4, ()
|
||||
LOAD_IMMEDIATE R2, 1
|
||||
LOAD_IMMEDIATE R3, 4
|
||||
GET_METHOD R4, R1, 0 <!-- virtual call to 'bar' in D -->
|
||||
CALL R5, R4, (R2, R3)
|
||||
GET_SLOT R2, R1, 0
|
||||
LOAD_NAME R1, "print"
|
||||
CALL R1, R1, (R2)
|
||||
RETURN_VOID
|
||||
</function>
|
||||
|
||||
|
||||
<script>
|
||||
LOAD_NAME R1, "fn1"
|
||||
CALL R1, R1, ()
|
||||
|
||||
NEW_CLASS R2, "D"
|
||||
GET_STATIC R3, "D", 1 <!-- 0'th static is __init__ -->
|
||||
<!-- 1st static is D::D constructor -->
|
||||
@ -27,6 +55,5 @@
|
||||
CALL R5, R4, (R2, R3)
|
||||
GET_SLOT R2, R1, 0
|
||||
RETURN R2
|
||||
|
||||
|
||||
</script>
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "world.h"
|
||||
#include "interpreter.h"
|
||||
#include "icodegenerator.h"
|
||||
#include "xmlparser.h"
|
||||
|
||||
#ifdef DEBUGGER_FOO
|
||||
#include "debugger.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user