Fixes and enhancements to get class references, constructors and scripts

working from .xml input.
This commit is contained in:
rogerl%netscape.com 2001-01-19 23:56:37 +00:00
Родитель 46e1348f16
Коммит 5ef03957d6
18 изменённых файлов: 328 добавлений и 372 удалений

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

@ -1,51 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the JavaScript 2 Prototype.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
#include "exception.h"
namespace JavaScript {
extern const char* exception_types[];
extern const char* exception_msgs[];
void
JSException::toString8 (string8 &rval)
{
rval = *exception_types[mType] + " Exception: " +
*exception_msgs[mID];
if (mSource.size() != 0)
rval += " in " + mSource;
}
}

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

@ -1,115 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the JavaScript 2 Prototype.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
#ifndef exception_h___
#define exception_h___
#include "utilities.h"
namespace JavaScript {
enum ExceptionType {
etUnknown = 0,
etLexer,
etParser,
etRuntime,
etCount
};
enum ExceptionID {
eidExpectBool = 0,
eidExpectDouble,
eidExpectInt32,
eidExpectUInt32,
eidExpectRegister,
eidExpectArgList,
eidExpectColon,
eidExpectCloseParen,
eidExpectBinaryOp,
eidExpectString,
eidExpectLabel,
eidExpectComma,
eidExpectNewline,
eidExpectIdentifier,
eidDuplicateLabel,
eidUnknownICode,
eidUnknownBinaryOp,
eidUnterminatedString,
eidCount
};
class JSException {
public:
JSException (ExceptionID ID, string8_citer pos = 0,
string8 source = 0, ExceptionType type = etUnknown)
: mID(ID), mType(type), mPos(pos), mSource(source) {}
ExceptionID mID;
ExceptionType mType;
string8_citer mPos;
string8 mSource;
public:
void toString8(string8 &rval);
/*
private:
JSException(const JSException&);
*/
};
class JSLexException : public JSException {
public:
JSLexException (ExceptionID ID, string8_citer pos = 0,
string8 source = "") :
JSException(ID, pos, source, etLexer) {}
/*
private:
JSLexException (const JSLexException&);
*/
};
class JSParseException : public JSException {
public:
JSParseException (ExceptionID ID, string8_citer pos = 0,
string8 source = 0) :
JSException(ID, pos, source, etParser) {}
/*
private:
JSParseException (const JSParseException&);
*/
};
}
#endif /* exception_h___ */

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

@ -108,6 +108,7 @@ namespace ICodeASM {
throw JSParseException (eidExpectArgList);
tl = seekTokenStart (tl.begin + 1, end);
StringFormatter s_fmt;
while (tl.estimate == teString || tl.estimate == teAlpha) {
string *argName = 0;
@ -143,6 +144,15 @@ namespace ICodeASM {
sap = &(mCx->getWorld().identifiers[argName->c_str()]);
delete argName;
}
else {
/* if an argument name was not specified, use the position
* to build a default name.
*/
s_fmt << (uint32)al->size();
sap = &(mCx->getWorld().identifiers[s_fmt.getString()]);
s_fmt.clear();
}
VM::Argument arg = VM::Argument (tr, sap);
al->push_back(arg);
@ -176,7 +186,7 @@ namespace ICodeASM {
for (int i = 0; keyword_exprNodeKinds[i] != 0; ++i)
if (cmp_nocase (*str, keyword_exprNodeKinds[i], keyword_exprNodeKinds[i] +
strlen (keyword_exprNodeKinds[i]) + 1) == 0) {
strlen (keyword_exprNodeKinds[i])) == 0) {
*rval = exprNodeOps[i];
delete str;
return end;
@ -220,11 +230,28 @@ namespace ICodeASM {
}
string8_citer
ICodeParser::parseJSClassOperand (string8_citer /*begin*/,
string8_citer end, string ** /*rval*/)
ICodeParser::parseJSClassOperand (string8_citer begin,
string8_citer end, JSTypes::JSType **rval)
{
NOT_REACHED ("JSClasses are hard, lets go shopping.");
TokenLocation tl = seekTokenStart (begin, end);
if (tl.estimate != teString)
throw JSParseException (eidExpectString);
string8 *str;
end = lexString8 (tl.begin, end, &str);
StringAtom &typename_atom = mCx->getWorld().identifiers[str->c_str()];
delete str;
JSTypes::JSValue jsv =
mCx->getGlobalObject()->getVariable(typename_atom);
if (jsv.isType())
*rval = jsv.type;
else
*rval = &(JSTypes::Any_Type);
return end;
// NOT_REACHED ("JSClasses are hard, lets go shopping.");
// return end;
}
string8_citer
@ -287,7 +314,7 @@ namespace ICodeASM {
begin = lexAlpha (tl.begin, end, &str);
if (cmp_nocase(*str, keyword_offset, keyword_offset +
strlen(keyword_offset) + 1) == 0) {
strlen(keyword_offset)) == 0) {
delete str;
/* got the "Offset" keyword, treat next thing as a jump offset
* expressed as "Offset +/-N" */
@ -391,7 +418,7 @@ namespace ICodeASM {
CASE_TYPE(Bool, bool, static_cast);
CASE_TYPE(Double, double, static_cast);
CASE_TYPE(ICodeModule, string *, reinterpret_cast);
CASE_TYPE(JSClass, string *, reinterpret_cast);
CASE_TYPE(JSClass, JSTypes::JSType *, reinterpret_cast);
CASE_TYPE(JSString, JSTypes::JSString *, reinterpret_cast);
CASE_TYPE(JSFunction, string *, reinterpret_cast);
CASE_TYPE(JSType, JSTypes::JSType *, reinterpret_cast);
@ -491,7 +518,7 @@ namespace ICodeASM {
for (uint i = 0; i < icodemap_size; ++i)
if (cmp_nocase(icode_str, &icodemap[i].name[0],
&icodemap[i].name[0] +
strlen(icodemap[i].name) + 1) == 0)
strlen(icodemap[i].name)) == 0)
/* if match found, parse it's operands */
return parseInstruction (i, firstTokenEnd, end);
/* otherwise, choke on it */

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

@ -121,7 +121,7 @@ namespace ICodeASM {
string8 **rval);
string8_citer
parseJSClassOperand (string8_citer begin, string8_citer end,
string8 **rval);
JSTypes::JSType **rval);
string8_citer
parseJSStringOperand (string8_citer begin, string8_citer end,
JSTypes::JSString **rval);

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

@ -39,6 +39,7 @@
#include "icodegenerator.h"
#include "interpreter.h"
#include "xmlparser.h"
#include "exception.h"
#include "icodeasm.h"
#include <stdexcept>
@ -2552,8 +2553,10 @@ Formatter& operator<<(Formatter &f, string &s)
}
void ICodeGenerator::readICode(const char *fileName)
ICodeModule *ICodeGenerator::readICode(const char *fileName)
{
ICodeModule *result = NULL;
XMLParser xp(fileName);
XMLNode *top = xp.parseDocument();
stdOut << *top;
@ -2582,12 +2585,13 @@ void ICodeGenerator::readICode(const char *fileName)
mContext->getGlobalObject()->defineVariable(className, &Type_Type, JSValue(thisClass));
bool hasDefaultConstructor = false;
// 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 (element->name().compare(widenCString("method")) == 0) {
if (isConstructor || (element->name().compare(widenCString("method")) == 0)) {
String methodName, resultTypeName;
element->getValue(widenCString("name"), methodName);
element->getValue(widenCString("type"), resultTypeName);
@ -2631,6 +2635,11 @@ void ICodeGenerator::readICode(const char *fileName)
NULL, /* InstructionMap *instructionMap */
resultType,
NotABanana); /* exception register */
if (isConstructor) {
thisClass->defineConstructor(methodName);
scg.setStatic(thisClass, mContext->getWorld().identifiers[methodName], scg.newFunction(icm));
}
else
thisClass->defineMethod(methodName, new JSFunction(icm));
}
}
@ -2651,7 +2660,7 @@ void 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);
@ -2665,6 +2674,7 @@ void ICodeGenerator::readICode(const char *fileName)
thisClass->defineConstructor(className);
scg.setStatic(thisClass, mContext->getWorld().identifiers[className], scg.newFunction(icg.complete(&Void_Type)));
}
*/
thisClass->complete();
if (scg.getICode()->size()) {
@ -2676,7 +2686,24 @@ void ICodeGenerator::readICode(const char *fileName)
}
else {
if (node->name().compare(widenCString("script")) == 0) {
// build an icode module and execute it
String &body = node->body();
if (body.length()) {
std::string str(body.length(), char());
std::transform(body.begin(), body.end(), str.begin(), narrow);
ICodeParser icp(mContext);
stdOut << "(script) Calling ICodeParser with :\n" << str << "\n";
icp.parseSourceFromString(str);
result = new ICodeModule(icp.mInstructions,
NULL, /* VariableList *variables */
NULL, /* ParameterList *parameters */
icp.mMaxRegister,
NULL, /* InstructionMap *instructionMap */
&Void_Type,
NotABanana); /* exception register */
}
}
else {
if (node->name().compare(widenCString("instance")) == 0) {
@ -2691,7 +2718,7 @@ void ICodeGenerator::readICode(const char *fileName)
}
}
return result;
}

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

@ -297,7 +297,7 @@ namespace ICG {
}
ICodeModule *complete(JSType *resultType);
void readICode(const char *fileName);
ICodeModule *readICode(const char *fileName);
JSType *extractType(ExprNode *t);
JSType *getParameterType(FunctionDefinition &function, int index);

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

@ -162,10 +162,10 @@ ICodeModule* Context::genCode(StmtNode *p, const String &fileName)
return icm;
}
void Context::loadClass(const char *fileName)
ICodeModule* Context::loadClass(const char *fileName)
{
ICodeGenerator icg(this);
icg.readICode(fileName); // loads it into the global object
return icg.readICode(fileName); // loads it into the global object
}
JSValues& Context::getRegisters() { return mActivation->mRegisters; }
@ -604,6 +604,9 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
else {
ICodeModule *icm = target->getICode();
ArgumentList *args = op3(call);
ArgumentList *callArgs = NULL;
if (icm->itsParameters) {
// if all the parameters are positional
// if (icm->itsParameters->mPositionalCount == icm->itsParameters->size())
@ -613,7 +616,7 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
uint32 pCount = icm->itsParameters->size() - 1; // we won't be passing 'this' via the arg list array
// callArgs will be the actual args passed to the target, put into correct register order.
// It has room for the rest parameter.
ArgumentList *callArgs = new ArgumentList(pCount, Argument(TypedRegister(NotARegister, &Null_Type), NULL));
callArgs = new ArgumentList(pCount, Argument(TypedRegister(NotARegister, &Null_Type), NULL));
// don't want to count the rest parameter while processing the others
if (icm->itsParameters->mRestParameter != ParameterList::NoRestParameter) pCount--;
@ -693,7 +696,7 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
throw new JSException("No argument supplied for non-optional parameter");
}
}
}
mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, op1(call), mICode, mCurrentClosure);
mICode = icm;
mActivation = new Activation(mICode->itsMaxRegister, mActivation, target->getThis(), callArgs);

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

@ -81,7 +81,7 @@ namespace Interpreter {
ICodeModule* genCode(StmtNode *p, const String &fileName);
JSValue readEvalFile(FILE* in, const String& fileName);
void loadClass(const char *fileName);
ICodeModule* loadClass(const char *fileName);
const JSValue findBinaryOverride(JSValue &operand1, JSValue &operand2, ExprNode::Kind op);
@ -142,6 +142,7 @@ namespace Interpreter {
// copy caller's parameter list to initial registers.
JSValues::iterator dest = mRegisters.begin();
*dest++ = thisArg;
if (list) {
const JSValues& params = caller->mRegisters;
for (ArgumentList::const_iterator src = list->begin(),
end = list->end(); src != end; ++src, ++dest) {
@ -152,6 +153,7 @@ namespace Interpreter {
*dest = JSValue(JSValue::uninitialized_tag);
}
}
}
// calling a binary operator, no 'this'
Activation(uint32 highRegister, const JSValue thisArg, const JSValue arg1, const JSValue arg2)

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

@ -182,7 +182,9 @@ static JSValue loadxml(Context *cx, const JSValues &argv)
JSString& fileName = *val.string;
std::string str(fileName.length(), char());
std::transform(fileName.begin(), fileName.end(), str.begin(), narrow);
cx->loadClass(str.c_str());
ICodeModule *icm = cx->loadClass(str.c_str());
if (icm)
result = JSValue(new JSFunction(icm));
}
}
}

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

@ -41,8 +41,8 @@ namespace JavaScript {
void
JSException::toString8 (string8 &rval)
{
rval = *exception_types[mType] + " Exception: " +
*exception_msgs[mID];
rval = string8(exception_types[mType]) + " Exception: " +
string8(exception_msgs[mID]);
if (mSource.size() != 0)
rval += " in " + mSource;
}

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

@ -70,7 +70,7 @@ namespace JavaScript {
class JSException {
public:
JSException (ExceptionID ID, string8_citer pos = 0,
string8 source = 0, ExceptionType type = etUnknown)
string8 source = "", ExceptionType type = etUnknown)
: mID(ID), mType(type), mPos(pos), mSource(source) {}
ExceptionID mID;
ExceptionType mType;
@ -100,7 +100,7 @@ namespace JavaScript {
class JSParseException : public JSException {
public:
JSParseException (ExceptionID ID, string8_citer pos = 0,
string8 source = 0) :
string8 source = "") :
JSException(ID, pos, source, etParser) {}
/*
private:

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

@ -108,6 +108,7 @@ namespace ICodeASM {
throw JSParseException (eidExpectArgList);
tl = seekTokenStart (tl.begin + 1, end);
StringFormatter s_fmt;
while (tl.estimate == teString || tl.estimate == teAlpha) {
string *argName = 0;
@ -143,6 +144,15 @@ namespace ICodeASM {
sap = &(mCx->getWorld().identifiers[argName->c_str()]);
delete argName;
}
else {
/* if an argument name was not specified, use the position
* to build a default name.
*/
s_fmt << (uint32)al->size();
sap = &(mCx->getWorld().identifiers[s_fmt.getString()]);
s_fmt.clear();
}
VM::Argument arg = VM::Argument (tr, sap);
al->push_back(arg);
@ -176,7 +186,7 @@ namespace ICodeASM {
for (int i = 0; keyword_exprNodeKinds[i] != 0; ++i)
if (cmp_nocase (*str, keyword_exprNodeKinds[i], keyword_exprNodeKinds[i] +
strlen (keyword_exprNodeKinds[i]) + 1) == 0) {
strlen (keyword_exprNodeKinds[i])) == 0) {
*rval = exprNodeOps[i];
delete str;
return end;
@ -220,11 +230,28 @@ namespace ICodeASM {
}
string8_citer
ICodeParser::parseJSClassOperand (string8_citer /*begin*/,
string8_citer end, string ** /*rval*/)
ICodeParser::parseJSClassOperand (string8_citer begin,
string8_citer end, JSTypes::JSType **rval)
{
NOT_REACHED ("JSClasses are hard, lets go shopping.");
TokenLocation tl = seekTokenStart (begin, end);
if (tl.estimate != teString)
throw JSParseException (eidExpectString);
string8 *str;
end = lexString8 (tl.begin, end, &str);
StringAtom &typename_atom = mCx->getWorld().identifiers[str->c_str()];
delete str;
JSTypes::JSValue jsv =
mCx->getGlobalObject()->getVariable(typename_atom);
if (jsv.isType())
*rval = jsv.type;
else
*rval = &(JSTypes::Any_Type);
return end;
// NOT_REACHED ("JSClasses are hard, lets go shopping.");
// return end;
}
string8_citer
@ -287,7 +314,7 @@ namespace ICodeASM {
begin = lexAlpha (tl.begin, end, &str);
if (cmp_nocase(*str, keyword_offset, keyword_offset +
strlen(keyword_offset) + 1) == 0) {
strlen(keyword_offset)) == 0) {
delete str;
/* got the "Offset" keyword, treat next thing as a jump offset
* expressed as "Offset +/-N" */
@ -391,7 +418,7 @@ namespace ICodeASM {
CASE_TYPE(Bool, bool, static_cast);
CASE_TYPE(Double, double, static_cast);
CASE_TYPE(ICodeModule, string *, reinterpret_cast);
CASE_TYPE(JSClass, string *, reinterpret_cast);
CASE_TYPE(JSClass, JSTypes::JSType *, reinterpret_cast);
CASE_TYPE(JSString, JSTypes::JSString *, reinterpret_cast);
CASE_TYPE(JSFunction, string *, reinterpret_cast);
CASE_TYPE(JSType, JSTypes::JSType *, reinterpret_cast);
@ -491,7 +518,7 @@ namespace ICodeASM {
for (uint i = 0; i < icodemap_size; ++i)
if (cmp_nocase(icode_str, &icodemap[i].name[0],
&icodemap[i].name[0] +
strlen(icodemap[i].name) + 1) == 0)
strlen(icodemap[i].name)) == 0)
/* if match found, parse it's operands */
return parseInstruction (i, firstTokenEnd, end);
/* otherwise, choke on it */

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

@ -121,7 +121,7 @@ namespace ICodeASM {
string8 **rval);
string8_citer
parseJSClassOperand (string8_citer begin, string8_citer end,
string8 **rval);
JSTypes::JSType **rval);
string8_citer
parseJSStringOperand (string8_citer begin, string8_citer end,
JSTypes::JSString **rval);

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

@ -39,6 +39,7 @@
#include "icodegenerator.h"
#include "interpreter.h"
#include "xmlparser.h"
#include "exception.h"
#include "icodeasm.h"
#include <stdexcept>
@ -2552,8 +2553,10 @@ Formatter& operator<<(Formatter &f, string &s)
}
void ICodeGenerator::readICode(const char *fileName)
ICodeModule *ICodeGenerator::readICode(const char *fileName)
{
ICodeModule *result = NULL;
XMLParser xp(fileName);
XMLNode *top = xp.parseDocument();
stdOut << *top;
@ -2582,12 +2585,13 @@ void ICodeGenerator::readICode(const char *fileName)
mContext->getGlobalObject()->defineVariable(className, &Type_Type, JSValue(thisClass));
bool hasDefaultConstructor = false;
// 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 (element->name().compare(widenCString("method")) == 0) {
if (isConstructor || (element->name().compare(widenCString("method")) == 0)) {
String methodName, resultTypeName;
element->getValue(widenCString("name"), methodName);
element->getValue(widenCString("type"), resultTypeName);
@ -2631,6 +2635,11 @@ void ICodeGenerator::readICode(const char *fileName)
NULL, /* InstructionMap *instructionMap */
resultType,
NotABanana); /* exception register */
if (isConstructor) {
thisClass->defineConstructor(methodName);
scg.setStatic(thisClass, mContext->getWorld().identifiers[methodName], scg.newFunction(icm));
}
else
thisClass->defineMethod(methodName, new JSFunction(icm));
}
}
@ -2651,7 +2660,7 @@ void 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);
@ -2665,6 +2674,7 @@ void ICodeGenerator::readICode(const char *fileName)
thisClass->defineConstructor(className);
scg.setStatic(thisClass, mContext->getWorld().identifiers[className], scg.newFunction(icg.complete(&Void_Type)));
}
*/
thisClass->complete();
if (scg.getICode()->size()) {
@ -2676,7 +2686,24 @@ void ICodeGenerator::readICode(const char *fileName)
}
else {
if (node->name().compare(widenCString("script")) == 0) {
// build an icode module and execute it
String &body = node->body();
if (body.length()) {
std::string str(body.length(), char());
std::transform(body.begin(), body.end(), str.begin(), narrow);
ICodeParser icp(mContext);
stdOut << "(script) Calling ICodeParser with :\n" << str << "\n";
icp.parseSourceFromString(str);
result = new ICodeModule(icp.mInstructions,
NULL, /* VariableList *variables */
NULL, /* ParameterList *parameters */
icp.mMaxRegister,
NULL, /* InstructionMap *instructionMap */
&Void_Type,
NotABanana); /* exception register */
}
}
else {
if (node->name().compare(widenCString("instance")) == 0) {
@ -2691,7 +2718,7 @@ void ICodeGenerator::readICode(const char *fileName)
}
}
return result;
}

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

@ -297,7 +297,7 @@ namespace ICG {
}
ICodeModule *complete(JSType *resultType);
void readICode(const char *fileName);
ICodeModule *readICode(const char *fileName);
JSType *extractType(ExprNode *t);
JSType *getParameterType(FunctionDefinition &function, int index);

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

@ -162,10 +162,10 @@ ICodeModule* Context::genCode(StmtNode *p, const String &fileName)
return icm;
}
void Context::loadClass(const char *fileName)
ICodeModule* Context::loadClass(const char *fileName)
{
ICodeGenerator icg(this);
icg.readICode(fileName); // loads it into the global object
return icg.readICode(fileName); // loads it into the global object
}
JSValues& Context::getRegisters() { return mActivation->mRegisters; }
@ -604,6 +604,9 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
else {
ICodeModule *icm = target->getICode();
ArgumentList *args = op3(call);
ArgumentList *callArgs = NULL;
if (icm->itsParameters) {
// if all the parameters are positional
// if (icm->itsParameters->mPositionalCount == icm->itsParameters->size())
@ -613,7 +616,7 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
uint32 pCount = icm->itsParameters->size() - 1; // we won't be passing 'this' via the arg list array
// callArgs will be the actual args passed to the target, put into correct register order.
// It has room for the rest parameter.
ArgumentList *callArgs = new ArgumentList(pCount, Argument(TypedRegister(NotARegister, &Null_Type), NULL));
callArgs = new ArgumentList(pCount, Argument(TypedRegister(NotARegister, &Null_Type), NULL));
// don't want to count the rest parameter while processing the others
if (icm->itsParameters->mRestParameter != ParameterList::NoRestParameter) pCount--;
@ -693,7 +696,7 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
throw new JSException("No argument supplied for non-optional parameter");
}
}
}
mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, op1(call), mICode, mCurrentClosure);
mICode = icm;
mActivation = new Activation(mICode->itsMaxRegister, mActivation, target->getThis(), callArgs);

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

@ -81,7 +81,7 @@ namespace Interpreter {
ICodeModule* genCode(StmtNode *p, const String &fileName);
JSValue readEvalFile(FILE* in, const String& fileName);
void loadClass(const char *fileName);
ICodeModule* loadClass(const char *fileName);
const JSValue findBinaryOverride(JSValue &operand1, JSValue &operand2, ExprNode::Kind op);
@ -142,6 +142,7 @@ namespace Interpreter {
// copy caller's parameter list to initial registers.
JSValues::iterator dest = mRegisters.begin();
*dest++ = thisArg;
if (list) {
const JSValues& params = caller->mRegisters;
for (ArgumentList::const_iterator src = list->begin(),
end = list->end(); src != end; ++src, ++dest) {
@ -152,6 +153,7 @@ namespace Interpreter {
*dest = JSValue(JSValue::uninitialized_tag);
}
}
}
// calling a binary operator, no 'this'
Activation(uint32 highRegister, const JSValue thisArg, const JSValue arg1, const JSValue arg2)

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

@ -182,7 +182,9 @@ static JSValue loadxml(Context *cx, const JSValues &argv)
JSString& fileName = *val.string;
std::string str(fileName.length(), char());
std::transform(fileName.begin(), fileName.end(), str.begin(), narrow);
cx->loadClass(str.c_str());
ICodeModule *icm = cx->loadClass(str.c_str());
if (icm)
result = JSValue(new JSFunction(icm));
}
}
}