Incrementals

This commit is contained in:
rogerl%netscape.com 2002-08-05 01:38:23 +00:00
parent 427dffcdd5
commit c5247a541f
5 changed files with 259 additions and 101 deletions

View File

@ -97,8 +97,6 @@ const bool showTokens = false;
#define INTERPRET_INPUT 1
//#define SHOW_ICODE 1
MetaData::GlobalObject glob(world);
MetaData::Environment env(new MetaData::SystemFrame(), &glob);
MetaData::JS2Metadata *metadata;
@ -140,10 +138,9 @@ static int readEvalPrint(FILE *in)
}
metadata->setCurrentParser(&p); // for error reporting
MetaData::Context cxt;
metadata->ValidateStmtList(&cxt, &env, parsedStatements);
metadata->EvalStmtList(&env, MetaData::RunPhase, parsedStatements);
metadata->ValidateStmtList(parsedStatements);
metadata->EvalStmtList(MetaData::RunPhase, parsedStatements);
}
clear(buffer);

View File

@ -59,7 +59,8 @@ namespace JavaScript
userException,
definitionError,
badValueError,
compileExpressionError
compileExpressionError,
propertyAccessError
};
Kind kind; // The exception's kind

View File

@ -69,20 +69,21 @@ namespace JavaScript {
namespace MetaData {
JSRuntime *gMonkeyRuntime;
JSContext *gMonkeyContext;
JSObject *gMonkeyGlobalObject;
JSClass gMonkeyGlobalClass = { "MyClass", 0, JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub };
JSClass gMonkeyMultinameClass =
{ "Multiname", 0, JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub };
// forward ref.
// forward refs.
static void Multiname_finalize(JSContext *cx, JSObject *obj);
static void LexicalReference_finalize(JSContext *cx, JSObject *obj);
static void Namespace_finalize(JSContext *cx, JSObject *obj);
JSClass gMonkeyMultinameClass =
{ "Multiname", JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
JS_ResolveStub, JS_ConvertStub, Multiname_finalize };
JSClass gMonkeyLexicalReferenceClass =
{ "LexicalReference", JSCLASS_HAS_PRIVATE,
@ -90,6 +91,12 @@ namespace MetaData {
JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
JS_ResolveStub, JS_ConvertStub, LexicalReference_finalize };
JSClass gMonkeyNamespaceClass =
{ "Namespace", JSCLASS_HAS_PRIVATE,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
JS_ResolveStub, JS_ConvertStub, Namespace_finalize };
// member functions at global scope
JSFunctionSpec jsfGlobal [] =
{
@ -112,7 +119,7 @@ namespace MetaData {
static JSBool
LexicalReference_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
ExecutionState *eState = static_cast<ExecutionState *>(JS_GetContextPrivate(cx));
JS2Metadata *meta = static_cast<JS2Metadata *>(JS_GetContextPrivate(cx));
ASSERT(argc == 2);
ASSERT(JSVAL_IS_BOOLEAN(argv[0])); // the 'strict' flag (XXX what's that for?)
@ -122,7 +129,7 @@ namespace MetaData {
ASSERT(OBJ_GET_CLASS(cx, multiNameObj) == &gMonkeyMultinameClass);
Multiname *mName = static_cast<Multiname *>(JS_GetPrivate(cx, multiNameObj));
if (!JS_SetPrivate(cx, obj, new LexicalReference(mName, eState->env, (JSVAL_TO_BOOLEAN(argv[0])) == JS_TRUE) ))
if (!JS_SetPrivate(cx, obj, new LexicalReference(mName, &meta->env, (JSVAL_TO_BOOLEAN(argv[0])) == JS_TRUE) ))
return JS_FALSE;
return JS_TRUE;
@ -142,10 +149,10 @@ namespace MetaData {
readLexicalReference(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
ASSERT(OBJ_GET_CLASS(cx, obj) == &gMonkeyLexicalReferenceClass);
ExecutionState *eState = static_cast<ExecutionState *>(JS_GetContextPrivate(cx));
JS2Metadata *meta = static_cast<JS2Metadata *>(JS_GetContextPrivate(cx));
LexicalReference *lRef = static_cast<LexicalReference *>(JS_GetPrivate(cx, obj));
eState->env->lexicalRead(eState, lRef->variableMultiname, RunPhase);
meta->env.lexicalRead(meta, lRef->variableMultiname, RunPhase);
return JS_TRUE;
}
@ -154,7 +161,7 @@ namespace MetaData {
writeLexicalReference(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
ASSERT(OBJ_GET_CLASS(cx, obj) == &gMonkeyLexicalReferenceClass);
ExecutionState *eState = static_cast<ExecutionState *>(JS_GetContextPrivate(cx));
JS2Metadata *meta = static_cast<JS2Metadata *>(JS_GetContextPrivate(cx));
LexicalReference *lRef = static_cast<LexicalReference *>(JS_GetPrivate(cx, obj));
@ -179,35 +186,67 @@ namespace MetaData {
static JSBool
Multiname_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JS2Metadata *meta = static_cast<JS2Metadata *>(JS_GetContextPrivate(cx));
ASSERT(argc >= 1); // could be just the base name
ASSERT(OBJ_GET_CLASS(cx, obj) == &gMonkeyMultinameClass);
ASSERT(JSVAL_IS_STRING(argv[0]));
JSString *str = JSVAL_TO_STRING(argv[0]);
// XXX use reserved slots instead
if (!JS_SetProperty(cx, obj, "name", &argv[0]))
Multiname *mName = new Multiname(meta->world.identifiers[String(JS_GetStringChars(str), JS_GetStringLength(str))]);
if (!JS_SetPrivate(cx, obj, mName))
return JS_FALSE;
jsval qualifierVal = JSVAL_NULL;
if (argc > 1) {
JSObject *qualArray = JS_NewArrayObject(cx, argc - 1, &argv[1]);
if (!qualArray)
return JS_FALSE;
qualifierVal = OBJECT_TO_JSVAL(qualArray);
for (uintN i = 1; i < argc; i++) {
ASSERT(JSVAL_IS_OBJECT(argv[i]));
JSObject *obj = JSVAL_TO_OBJECT(argv[i]);
ASSERT(OBJ_GET_CLASS(cx, obj) == &gMonkeyNamespaceClass);
Namespace *ns = static_cast<Namespace *>(JS_GetPrivate(cx, obj));
mName->addNamespace(ns);
}
if (!JS_SetProperty(cx, obj, "qualifiers", &qualifierVal))
return JS_FALSE;
return JS_TRUE;
}
// member functions in a Multiname
JSFunctionSpec jsfMultiname [] =
// finalize a Multiname - called by Monkey gc
static void
Multiname_finalize(JSContext *cx, JSObject *obj)
{
{ 0 }
};
ASSERT(OBJ_GET_CLASS(cx, obj) == &gMonkeyMultinameClass);
Multiname *mName = static_cast<Multiname *>(JS_GetPrivate(cx, obj));
if (mName) delete mName;
}
/******************************************************************************
Namespace
******************************************************************************/
// finish constructing a Namespace
static JSBool
Namespace_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JS2Metadata *meta = static_cast<JS2Metadata *>(JS_GetContextPrivate(cx));
ASSERT(argc == 1);
ASSERT(JSVAL_IS_STRING(argv[0]));
JSString *str = JSVAL_TO_STRING(argv[0]);
Namespace *ns = new Namespace(meta->world.identifiers[String(JS_GetStringChars(str), JS_GetStringLength(str))]);
if (!JS_SetPrivate(cx, obj, ns))
return JS_FALSE;
return JS_TRUE;
}
// finalize a Namespace - called by Monkey gc
static void
Namespace_finalize(JSContext *cx, JSObject *obj)
{
ASSERT(OBJ_GET_CLASS(cx, obj) == &gMonkeyNamespaceClass);
Namespace *ns = static_cast<Namespace *>(JS_GetPrivate(cx, obj));
if (ns) delete ns;
}
@ -216,45 +255,50 @@ namespace MetaData {
// Initialize the SpiderMonkey engine
void JS2Metadata::initializeMonkey()
{
gMonkeyRuntime = JS_NewRuntime( 1000000L );
if (!gMonkeyRuntime)
monkeyRuntime = JS_NewRuntime(1000000L);
if (!monkeyRuntime)
throw "Monkey start failure";
gMonkeyContext = JS_NewContext( gMonkeyRuntime, 8192 );
if (!gMonkeyContext)
monkeyContext = JS_NewContext(monkeyRuntime, 8192);
if (!monkeyContext)
throw "Monkey start failure";
gMonkeyGlobalObject = JS_NewObject(gMonkeyContext, &gMonkeyGlobalClass, NULL, NULL);
if (!gMonkeyGlobalObject)
monkeyGlobalObject = JS_NewObject(monkeyContext, &gMonkeyGlobalClass, NULL, NULL);
if (!monkeyGlobalObject)
throw "Monkey start failure";
JS_SetErrorReporter(gMonkeyContext, MonkeyError);
JS_SetErrorReporter(monkeyContext, MonkeyError);
JS_InitStandardClasses(gMonkeyContext, gMonkeyGlobalObject);
if (!JS_InitStandardClasses(monkeyContext, monkeyGlobalObject))
throw "Monkey start failure";
JS_InitClass(gMonkeyContext, gMonkeyGlobalObject, NULL,
JS_InitClass(monkeyContext, monkeyGlobalObject, NULL,
&gMonkeyLexicalReferenceClass, LexicalReference_constructor, 0,
NULL, jsfLexicalReference, NULL, NULL);
JS_InitClass(gMonkeyContext, gMonkeyGlobalObject, NULL,
JS_InitClass(monkeyContext, monkeyGlobalObject, NULL,
&gMonkeyMultinameClass, Multiname_constructor, 0,
NULL, jsfMultiname, NULL, NULL);
NULL, NULL, NULL, NULL);
JS_DefineFunctions(gMonkeyContext, gMonkeyGlobalObject, jsfGlobal);
JS_InitClass(monkeyContext, monkeyGlobalObject, NULL,
&gMonkeyNamespaceClass, Namespace_constructor, 0,
NULL, NULL, NULL, NULL);
if (!JS_DefineFunctions(monkeyContext, monkeyGlobalObject, jsfGlobal))
throw "Monkey start failure";
}
// Execute a JS string against the given environment
// Errors are thrown back to C++ by the error handler
jsval JS2Metadata::execute(String *str, Environment *env, JS2Metadata *meta, size_t pos)
jsval JS2Metadata::execute(String *str, size_t pos)
{
jsval retval;
ExecutionState eState(gMonkeyContext, env, meta, pos);
JS_SetContextPrivate(gMonkeyContext, &eState);
errorPos = pos;
JS_SetContextPrivate(monkeyContext, this);
JS_EvaluateUCScript(gMonkeyContext, gMonkeyGlobalObject, str->c_str(), str->length(), "file", 1, &retval);
JS_EvaluateUCScript(monkeyContext, monkeyGlobalObject, str->c_str(), str->length(), "file", 1, &retval);
return retval;
}

View File

@ -61,6 +61,15 @@ namespace MetaData {
/*
* Validate the linked list of statement nodes beginning at 'p'
*/
void JS2Metadata::ValidateStmtList(StmtNode *p) {
cxt.openNamespaces.clear();
cxt.openNamespaces.push_back(publicNamespace);
while (p) {
ValidateStmt(&cxt, &env, p);
p = p->next;
}
}
void JS2Metadata::ValidateStmtList(Context *cxt, Environment *env, StmtNode *p) {
while (p) {
ValidateStmt(cxt, env, p);
@ -92,10 +101,10 @@ namespace MetaData {
Attribute *attr = NULL;
VariableStmtNode *vs = checked_cast<VariableStmtNode *>(p);
ValidateAttributeExpression(cxt, env, vs->attributes);
if (vs->attributes)
if (vs->attributes) {
ValidateAttributeExpression(cxt, env, vs->attributes);
attr = EvalAttributeExpression(env, CompilePhase, vs->attributes);
}
VariableBinding *v = vs->bindings;
Frame *regionalFrame = env->getRegionalFrame();
@ -130,10 +139,10 @@ namespace MetaData {
/*
* Evaluate the linked list of statement nodes beginning at 'p'
*/
jsval JS2Metadata::EvalStmtList(Environment *env, Phase phase, StmtNode *p) {
jsval JS2Metadata::EvalStmtList(Phase phase, StmtNode *p) {
jsval retval = JSVAL_VOID;
while (p) {
retval = EvalStmt(env, phase, p);
retval = EvalStmt(&env, phase, p);
p = p->next;
}
return retval;
@ -150,7 +159,7 @@ namespace MetaData {
case StmtNode::group:
{
BlockStmtNode *b = checked_cast<BlockStmtNode *>(p);
retval = EvalStmtList(env, phase, b->statements);
retval = EvalStmtList(phase, b->statements);
}
break;
case StmtNode::label:
@ -438,9 +447,10 @@ namespace MetaData {
jsval JS2Metadata::EvalExpression(Environment *env, Phase phase, ExprNode *p)
{
String s;
EvalExprNode(env, phase, p, s);
if (EvalExprNode(env, phase, p, s))
s += ".readReference()";
try {
return execute(&s, env, this, p->pos);
return execute(&s, p->pos);
}
catch (const char *err) {
reportError(Exception::internalError, err, p->pos);
@ -495,10 +505,10 @@ namespace MetaData {
{
if (phase == CompilePhase) reportError(Exception::compileExpressionError, "Inappropriate compile time expression", p->pos);
UnaryExprNode *u = checked_cast<UnaryExprNode *>(p);
// rather than inserting "(r = , a = readRef(), r.writeRef(a + 1), a)" with
// all the attendant performance overhead and temp. handling issues.
if (!EvalExprNode(env, phase, u->op, s))
ASSERT(false); // not an lvalue
// rather than inserting "(r = , a = readRef(), r.writeRef(a + 1), a)" with
// all the attendant performance overhead and temp. handling issues.
s += ".postIncrement()";
returningRef = true;
}
@ -512,11 +522,14 @@ namespace MetaData {
case ExprNode::identifier:
{
IdentifierExprNode *i = checked_cast<IdentifierExprNode *>(p);
s += "new LexicalReference(" + (i->cxt->strict) ? "true, " : "false, ";
s += "new LexicalReference(";
s += (i->cxt->strict) ? "true, " : "false, ";
s += "new Multiname(\"" + i->name + "\"";
for (NamespaceListIterator nli = i->cxt->openNamespaces.begin(), end = i->cxt->openNamespaces.end();
(nli != end); nli++) {
s += ", " + (*nli)->name;
s += ", new Namespace(\""
s += (*nli)->name;
s += "\")";
}
s += "))";
returningRef = true;
@ -584,32 +597,27 @@ namespace MetaData {
return JSVAL_VOID;
}
// Slightly varies from spec. - the multiname is actually the list of
// qualifiers to apply to the name
jsval Environment::lexicalRead(ExecutionState *eState, Multiname *multiname, Phase phase)
// Read the value of a lexical reference - it's an error if that reference
// doesn't have a binding somewhere
jsval Environment::lexicalRead(JS2Metadata *meta, Multiname *multiname, Phase phase)
{
LookupKind lookup(true, findThis(false));
Frame *pf = firstFrame;
while (pf) {
jsval rval;
if (readProperty(eState, pf, multiname, &lookup, phase, &rval))
// have to wrap the frame in a Monkey object in order
// to have readProperty handle it...
if (meta->readProperty(pf, multiname, &lookup, phase, &rval))
return rval;
pf = pf->nextFrame;
}
eState->meta->reportError(Exception::referenceError, "{0} is undefined", eState->pos, multiname->name);
meta->reportError(Exception::referenceError, "{0} is undefined", meta->errorPos, multiname->name);
return JSVAL_VOID;
}
bool Environment::readProperty(ExecutionState *eState, jsval container, Multiname *multinameVal, LookupKind *lookupKind, Phase phase, jsval *rval)
{
}
/************************************************************************************
*
* Context
@ -620,6 +628,21 @@ namespace MetaData {
{
}
/************************************************************************************
*
* Multiname
*
************************************************************************************/
// return true if the given namespace is on the namespace list
bool Multiname::onList(Namespace *nameSpace)
{
for (NamespaceListIterator n = nsList.begin(), end = nsList.end(); (n != end); n++) {
if (*n == nameSpace)
return true;
}
return false;
}
/************************************************************************************
*
@ -679,7 +702,10 @@ namespace MetaData {
}
JS2Metadata::JS2Metadata(World &world) :
publicNamespace(new Namespace(world.identifiers["public"]))
world(world),
publicNamespace(new Namespace(world.identifiers["public"])),
glob(world),
env(new MetaData::SystemFrame(), &glob)
{
initializeMonkey();
}
@ -701,6 +727,8 @@ namespace MetaData {
else
return stringClass;
}
ASSERT(JSVAL_IS_OBJECT(obj));
return NULL;
/*
NAMESPACE do return namespaceClass;
COMPOUNDATTRIBUTE do return attributeClass;
@ -712,6 +740,68 @@ namespace MetaData {
*/
}
bool JS2Metadata::readDynamicProperty(Frame *container, Multiname *multiname, LookupKind *lookupKind, Phase phase)
{
return true;
}
bool JS2Metadata::readStaticMember(StaticMember *m, Phase phase)
{
return true;
}
// Read the value of a property in the container. Return true/false if that container has
// the property or not. If it does, return it's value
bool JS2Metadata::readProperty(jsval container, Multiname *multiname, LookupKind *lookupKind, Phase phase, jsval *rval)
{
return true;
}
// Read the value of a property in the frame. Return true/false if that frame has
// the property or not. If it does, return it's value
bool JS2Metadata::readProperty(Frame *container, Multiname *multiname, LookupKind *lookupKind, Phase phase, jsval *rval)
{
StaticMember *m = findFlatMember(container, multiname, ReadAccess, phase);
if (!m && (container->kind == Frame::GlobalObject))
return readDynamicProperty(container, multiname, lookupKind, phase);
else
return readStaticMember(m, phase);
}
// Find a binding in the frame that matches the multiname and access
// It's an error if more than one such binding exists.
StaticMember *JS2Metadata::findFlatMember(Frame *container, Multiname *multiname, Access access, Phase phase)
{
StaticMember *found = NULL;
StaticBindingIterator b, end;
if ((access == ReadAccess) || (access == ReadWriteAccess)) {
b = container->staticReadBindings.lower_bound(multiname->name);
end = container->staticReadBindings.upper_bound(multiname->name);
}
else {
b = container->staticWriteBindings.lower_bound(multiname->name);
end = container->staticWriteBindings.upper_bound(multiname->name);
}
while (true) {
if (b == end) {
if (access == ReadWriteAccess) {
access = WriteAccess;
b = container->staticWriteBindings.lower_bound(multiname->name);
end = container->staticWriteBindings.upper_bound(multiname->name);
}
else
break;
}
if (multiname->matches(b->second->qname)) {
if (found)
reportError(Exception::propertyAccessError, "Ambiguous reference to {0}", errorPos, multiname->name);
else
found = b->second->content;
}
b++;
}
return found;
}
/*
* Throw an exception of the specified kind, indicating the position 'pos' and

View File

@ -46,7 +46,6 @@ namespace MetaData {
// forward definitions:
class ExecutionState;
class JS2Metadata;
class JS2Class;
class StaticBinding;
@ -59,7 +58,8 @@ typedef Invokable Callor;
typedef Invokable Constructor;
enum Phase { CompilePhase, RunPhase };
enum Phase { CompilePhase, RunPhase };
enum Access { ReadAccess, WriteAccess, ReadWriteAccess };
class JS2Object {
// Every object is either undefined, null, a Boolean,
@ -105,11 +105,19 @@ public:
};
// MULTINAME is the semantic domain of sets of qualified names. Multinames are used internally in property lookup.
typedef std::vector<QualifiedName *> QualifierList;
typedef QualifierList::iterator QualifierListIterator;
// We keep Multinames as a basename and a list of namespace qualifiers
typedef std::vector<Namespace *> NamespaceList;
typedef NamespaceList::iterator NamespaceListIterator;
class Multiname {
public:
QualifierList qList;
Multiname(StringAtom &name) : name(name) { }
void addNamespace(Namespace *ns) { nsList.push_back(ns); }
bool matches(QualifiedName &q) { return (name == q.id) && onList(q.nameSpace); }
bool onList(Namespace *nameSpace);
NamespaceList nsList;
StringAtom &name;
};
@ -237,7 +245,9 @@ public:
class Frame {
public:
enum Plurality { Singular, Plural };
enum FrameKind { GlobalObject, Package, Function, Class, Block };
enum FrameKind { System, GlobalObject, Package, Function, Class, Block };
Frame(FrameKind kind) : kind(kind), nextFrame(NULL) { }
StaticBindingMap staticReadBindings; // Map of qualified names to readable static members defined in this frame
StaticBindingMap staticWriteBindings; // Map of qualified names to writable static members defined in this frame
@ -252,6 +262,7 @@ public:
class JS2Class : public Frame {
public:
JS2Class() : Frame(Class) { }
InstanceBindingMap instanceReadBindings; // Map of qualified names to readable instance members defined in this class
InstanceBindingMap instanceWriteBindings; // Map of qualified names to writable instance members defined in this class
@ -276,7 +287,7 @@ public:
class GlobalObject : public Frame {
public:
GlobalObject(World &world) : internalNamespace(new Namespace(world.identifiers["internal"])) { }
GlobalObject(World &world) : Frame(Frame::GlobalObject), internalNamespace(new Namespace(world.identifiers["internal"])) { }
Namespace *internalNamespace; // This global object's internal namespace
DynamicPropertyMap dynamicProperties; // A set of this global object's dynamic properties
@ -369,11 +380,14 @@ public:
// The top-level frame containing predefined constants, functions, and classes.
class SystemFrame : public Frame {
public:
SystemFrame() : Frame(System) { }
};
// Frames holding bindings for invoked functions
class FunctionFrame : public Frame {
public:
FunctionFrame() : Frame(Function) { }
Plurality plurality;
jsval thisObject; // The value of this; none if this function doesn't define this;
// inaccessible if this function defines this but the value is not
@ -386,6 +400,8 @@ public:
class BlockFrame : public Frame {
public:
BlockFrame() : Frame(Block) { }
Plurality plurality;
};
@ -410,9 +426,7 @@ public:
Frame *getTopFrame() { return firstFrame; }
jsval findThis(bool allowPrototypeThis);
jsval lexicalRead(ExecutionState *eState, Multiname *multiname, Phase phase);
bool readProperty(ExecutionState *eState, jsval container, Multiname *multinameVal, LookupKind *lookupKind, Phase phase, jsval *rval);
jsval lexicalRead(JS2Metadata *meta, Multiname *multiname, Phase phase);
private:
@ -468,32 +482,47 @@ public:
void setCurrentParser(Parser *parser) { mParser = parser; }
void ValidateTypeExpression(ExprNode *e);
void ValidateStmtList(StmtNode *p);
jsval EvalStmtList(Phase phase, StmtNode *p);
void ValidateStmtList(Context *cxt, Environment *env, StmtNode *p);
void ValidateTypeExpression(ExprNode *e);
void ValidateStmt(Context *cxt, Environment *env, StmtNode *p);
void defineHoistedVar(Environment *env, const StringAtom &id, StmtNode *p);
void ValidateExpression(Context *cxt, Environment *env, ExprNode *p);
void ValidateAttributeExpression(Context *cxt, Environment *env, ExprNode *p);
jsval EvalStmtList(Environment *env, Phase phase, StmtNode *p);
jsval EvalExpression(Environment *env, Phase phase, ExprNode *p);
bool EvalExprNode(Environment *env, Phase phase, ExprNode *p, String &s);
Attribute *EvalAttributeExpression(Environment *env, Phase phase, ExprNode *p);
jsval EvalStmtList(Environment *env, Phase phase, StmtNode *p);
jsval EvalStmt(Environment *env, Phase phase, StmtNode *p);
JS2Class *objectType(jsval obj);
bool readProperty(jsval container, Multiname *multiname, LookupKind *lookupKind, Phase phase, jsval *rval);
bool readProperty(Frame *pf, Multiname *multiname, LookupKind *lookupKind, Phase phase, jsval *rval);
StaticMember *findFlatMember(Frame *container, Multiname *multiname, Access access, Phase phase);
bool readDynamicProperty(Frame *container, Multiname *multiname, LookupKind *lookupKind, Phase phase);
bool readStaticMember(StaticMember *m, Phase phase);
void reportError(Exception::Kind kind, const char *message, size_t pos, const char *arg = NULL);
void reportError(Exception::Kind kind, const char *message, size_t pos, const String& name);
void initializeMonkey();
jsval execute(String *str, Environment *env, JS2Metadata *meta, size_t pos);
jsval execute(String *str, size_t pos);
// Used for interning strings
World &world;
// The one and only 'public' namespace
Namespace *publicNamespace; // XXX is this the right place for this ???
Namespace *publicNamespace;
// The base classes:
JS2Class *undefinedClass;
@ -505,21 +534,18 @@ public:
Parser *mParser; // used for error reporting
size_t errorPos;
};
// Captures some metadata-related info. that gets passed back into
// js2metadata routines from executing JS code
// - it's hidden in the Monkey context private
class ExecutionState {
public:
ExecutionState(JSContext *cx, Environment *env, JS2Metadata *meta, size_t pos) : cx(cx), env(env), meta(meta), pos(pos) { }
virtual ~ExecutionState() { }
GlobalObject glob;
Environment env;
Context cxt;
// SpiderMonkey execution data:
JSRuntime *monkeyRuntime;
JSContext *monkeyContext;
JSObject *monkeyGlobalObject;
JSContext *cx; // the SpiderMonkey context
Environment *env; // the frame array, used for lookups
JS2Metadata *meta; // base class for error reporting
size_t pos; // position from node being executed (vaguely)
};