Changes throughout to match new Object layout - merged CallableInstance to

SimpleInstance, switched StaticBinding to LocalBinding etc.
This commit is contained in:
rogerl%netscape.com 2003-01-30 21:41:25 +00:00
parent 3d736f006c
commit 7de5f3cf85
15 changed files with 362 additions and 431 deletions

View File

@ -235,11 +235,11 @@ js2val trace(JS2Metadata *meta, const js2val /* thisValue */, js2val /* argv */
void printFrameBindings(Frame *f)
{
stdOut << " Static Bindings:\n";
for (StaticBindingIterator rsb = f->staticReadBindings.begin(), rsend = f->staticReadBindings.end(); (rsb != rsend); rsb++) {
stdOut << " Local Bindings:\n";
for (LocalBindingIterator rsb = f->localReadBindings.begin(), rsend = f->localReadBindings.end(); (rsb != rsend); rsb++) {
stdOut << "\t" << *rsb->second->qname.nameSpace->name << "::" << *rsb->second->qname.id;
bool found = false;
for (StaticBindingIterator wsb = f->staticWriteBindings.begin(), wsend = f->staticWriteBindings.end(); (wsb != wsend); wsb++) {
for (LocalBindingIterator wsb = f->localWriteBindings.begin(), wsend = f->localWriteBindings.end(); (wsb != wsend); wsb++) {
if (rsb->second->qname == wsb->second->qname) {
found = true;
break;
@ -247,9 +247,9 @@ void printFrameBindings(Frame *f)
}
stdOut << ((found) ? " [read/write]" : " [read-only]") << "\n";
}
for (StaticBindingIterator wsb = f->staticWriteBindings.begin(), wsend = f->staticWriteBindings.end(); (wsb != wsend); wsb++) {
for (LocalBindingIterator wsb = f->localWriteBindings.begin(), wsend = f->localWriteBindings.end(); (wsb != wsend); wsb++) {
bool found = false;
for (StaticBindingIterator rsb = f->staticReadBindings.begin(), rsend = f->staticReadBindings.end(); (rsb != rsend); rsb++) {
for (LocalBindingIterator rsb = f->localReadBindings.begin(), rsend = f->localReadBindings.end(); (rsb != rsend); rsb++) {
if (rsb->second->qname == wsb->second->qname) {
found = true;
break;
@ -266,10 +266,10 @@ js2val dump(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint
if (argc) {
if (JS2VAL_IS_OBJECT(argv[0])) {
JS2Object *fObj = JS2VAL_TO_OBJECT(argv[0]);
if (((fObj->kind == CallableInstanceKind)
if (((fObj->kind == SimpleInstanceKind)
&& (meta->objectType(argv[0]) == meta->functionClass))) {
FunctionWrapper *fWrap;
fWrap = (checked_cast<CallableInstance *>(fObj))->fWrap;
fWrap = (checked_cast<SimpleInstance *>(fObj))->fWrap;
if (fWrap->code)
stdOut << "<native code>\n";
else

View File

@ -806,7 +806,7 @@ void initArrayObject(JS2Metadata *meta)
PrototypeFunction *pf = &arrayProtos[0];
while (pf->name) {
CallableInstance *fInst = new CallableInstance(meta->functionClass);
SimpleInstance *fInst = new SimpleInstance(meta->functionClass);
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
InstanceMember *m = new InstanceMethod(fInst);

View File

@ -123,9 +123,9 @@ namespace MetaData {
// Adding "prototype" & "length" as static members of the class - not dynamic properties; XXX
meta->env->addFrame(meta->booleanClass);
Variable *v = new Variable(meta->booleanClass, OBJECT_TO_JS2VAL(meta->booleanClass->prototype), true);
meta->defineStaticMember(meta->env, meta->engine->prototype_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->defineLocalMember(meta->env, meta->engine->prototype_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
v = new Variable(meta->numberClass, INT_TO_JS2VAL(1), true);
meta->defineStaticMember(meta->env, meta->engine->length_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->defineLocalMember(meta->env, meta->engine->length_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->env->removeTopFrame();
// Add "constructor" as a dynamic property of the prototype
@ -137,12 +137,12 @@ namespace MetaData {
PrototypeFunction *pf = &prototypeFunctions[0];
while (pf->name) {
CallableInstance *callInst = new CallableInstance(meta->functionClass);
SimpleInstance *callInst = new SimpleInstance(meta->functionClass);
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
/*
XXX not static members, since those can't be accessed from the instance
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(callInst), true);
meta->defineStaticMember(&meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->defineLocalMember(&meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
*/
InstanceMember *m = new InstanceMethod(callInst);
meta->defineInstanceMember(meta->booleanClass, &meta->cxt, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, m, 0);

View File

@ -1469,7 +1469,7 @@ void initDateObject(JS2Metadata *meta)
PrototypeFunction *pf = &prototypeFunctions[0];
while (pf->name) {
CallableInstance *fInst = new CallableInstance(meta->functionClass);
SimpleInstance *fInst = new SimpleInstance(meta->functionClass);
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
/*
XXX not prototype object function properties, like ECMA3
@ -1478,7 +1478,7 @@ XXX not prototype object function properties, like ECMA3
/*
XXX not static members, since those can't be accessed from the instance
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(fInst), true);
meta->defineStaticMember(&meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->defineLocalMember(&meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
*/
InstanceMember *m = new InstanceMethod(fInst);
meta->defineInstanceMember(meta->dateClass, &meta->cxt, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, m, 0);

View File

@ -771,7 +771,7 @@ namespace MetaData {
if (c->prototype)
return OBJECT_TO_JS2VAL(new PrototypeInstance(c->prototype, c));
else
return OBJECT_TO_JS2VAL(new CallableInstance(c));
return OBJECT_TO_JS2VAL(new SimpleInstance(c));
}
// Save current engine state (pc, environment top) and
@ -885,17 +885,17 @@ namespace MetaData {
{
if (obj->kind == ClassKind) {
JS2Class *c = checked_cast<JS2Class *>(obj);
StaticBindingIterator sbi, end;
nameList = new const String *[c->staticReadBindings.size()];
LocalBindingIterator sbi, end;
nameList = new const String *[c->localReadBindings.size()];
length = 0;
for (sbi = c->staticReadBindings.begin(), end = c->staticReadBindings.end(); (sbi != end); sbi++) {
for (sbi = c->localReadBindings.begin(), end = c->localReadBindings.end(); (sbi != end); sbi++) {
nameList[length++] = &sbi->first;
}
}
else {
DynamicPropertyMap *dMap = NULL;
if (obj->kind == CallableInstanceKind)
dMap = (checked_cast<CallableInstance *>(obj))->dynamicProperties;
if (obj->kind == SimpleInstanceKind)
dMap = (checked_cast<SimpleInstance *>(obj))->dynamicProperties;
else
if (obj->kind == GlobalObjectKind)
dMap = &(checked_cast<GlobalObject *>(obj))->dynamicProperties;

View File

@ -151,7 +151,7 @@ void initErrorObject(JS2Metadata *meta)
PrototypeFunction *pf = &errorProtos[0];
while (pf->name) {
CallableInstance *fInst = new CallableInstance(meta->functionClass);
SimpleInstance *fInst = new SimpleInstance(meta->functionClass);
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
InstanceMember *m = new InstanceMethod(fInst);

View File

@ -115,23 +115,23 @@ namespace MetaData {
// Adding "prototype" as a static member of the class - not a dynamic property
meta->env->addFrame(meta->functionClass);
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(meta->functionClass->prototype), true);
meta->defineStaticMember(meta->env, meta->engine->prototype_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->defineLocalMember(meta->env, meta->engine->prototype_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->env->removeTopFrame();
// Add "constructor" as a dynamic property of the prototype
CallableInstance *fInst = new CallableInstance(meta->functionClass);
SimpleInstance *fInst = new SimpleInstance(meta->functionClass);
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), Function_Constructor);
meta->writeDynamicProperty(meta->functionClass->prototype, new Multiname(&meta->world.identifiers["constructor"], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
PrototypeFunction *pf = &prototypeFunctions[0];
while (pf->name) {
fInst = new CallableInstance(meta->functionClass);
fInst = new SimpleInstance(meta->functionClass);
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
/*
XXX not static members, since those can't be accessed from the instance
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(fInst), true);
meta->defineStaticMember(&meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->defineLocalMember(&meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
*/
InstanceMember *m = new InstanceMethod(fInst);
meta->defineInstanceMember(meta->functionClass, &meta->cxt, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, m, 0);

View File

@ -310,7 +310,7 @@ void initMathObject(JS2Metadata *meta)
for (i = 0; i < M_CONSTANTS_COUNT; i++)
{
Variable *v = new Variable(meta->numberClass, meta->engine->allocNumber(MathObjectConstants[i].value), true);
meta->defineStaticMember(meta->env, &meta->world.identifiers[MathObjectConstants[i].name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->defineLocalMember(meta->env, &meta->world.identifiers[MathObjectConstants[i].name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
}
meta->env->removeTopFrame();
@ -346,10 +346,10 @@ void initMathObject(JS2Metadata *meta)
meta->env->addFrame(meta->mathClass);
PrototypeFunction *pf = &prototypeFunctions[0];
while (pf->name) {
CallableInstance *fInst = new CallableInstance(meta->functionClass);
SimpleInstance *fInst = new SimpleInstance(meta->functionClass);
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(fInst), true);
meta->defineStaticMember(meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->defineLocalMember(meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
pf++;
}
meta->env->removeTopFrame();

File diff suppressed because it is too large Load Diff

View File

@ -44,14 +44,13 @@ namespace MetaData {
class JS2Object;
class JS2Metadata;
class JS2Class;
class StaticBinding;
class LocalBinding;
class Environment;
class Context;
class CompoundAttribute;
class BytecodeContainer;
class Pond;
class SimpleInstance;
class CallableInstance;
typedef void (Invokable)();
@ -102,7 +101,6 @@ enum ObjectKind {
BlockKind,
PrototypeInstanceKind,
SimpleInstanceKind,
CallableInstanceKind,
MultinameKind,
MethodClosureKind,
AlienInstanceKind,
@ -271,10 +269,10 @@ class Signature {
bool returnType; // The type of this function's result
};
// A base class for Instance and Static members for convenience.
// A base class for Instance and Local members for convenience.
class Member {
public:
enum MemberKind { Forbidden, Variable, HoistedVariable, ConstructorMethod, Accessor, InstanceVariableKind, InstanceMethodKind, InstanceAccessorKind };
enum MemberKind { Forbidden, DynamicVariableKind, Variable, ConstructorMethod, Setter, Getter, InstanceVariableKind, InstanceMethodKind, InstanceAccessorKind };
Member(MemberKind kind) : kind(kind) { }
@ -283,67 +281,82 @@ public:
virtual void mark() { }
};
// A static member is either forbidden, a variable, a hoisted variable, a constructor method, or an accessor:
class StaticMember : public Member {
// A local member is either forbidden, a dynamic variable, a variable, a constructor method, a getter or a setter:
class LocalMember : public Member {
public:
StaticMember(MemberKind kind) : Member(kind), forbidden(false) { }
StaticMember(MemberKind kind, bool forbidden) : Member(kind), forbidden(forbidden) { }
LocalMember(MemberKind kind) : Member(kind), forbidden(false) { }
LocalMember(MemberKind kind, bool forbidden) : Member(kind), forbidden(forbidden) { }
StaticMember *cloneContent; // Used during cloning operation to prevent cloning of duplicates (i.e. once
LocalMember *cloneContent; // Used during cloning operation to prevent cloning of duplicates (i.e. once
// a clone exists for this member it's recorded here and used for any other
// bindings that refer to this member.)
// Also used thereafter by 'assignArguments' to initialize the singular
// variable instantations in a parameter frame.
virtual StaticMember *clone() { if (forbidden) return this; ASSERT(false); return NULL; }
virtual LocalMember *clone() { if (forbidden) return this; ASSERT(false); return NULL; }
bool forbidden;
};
#define FUTURE_TYPE ((JS2Class *)(-1))
class Variable : public StaticMember {
class Variable : public LocalMember {
public:
Variable() : StaticMember(Member::Variable), type(NULL), vb(NULL), value(JS2VAL_VOID), immutable(false) { }
Variable(JS2Class *type, js2val value, bool immutable) : StaticMember(StaticMember::Variable), type(type), vb(NULL), value(value), immutable(immutable) { }
Variable() : LocalMember(Member::Variable), type(NULL), value(JS2VAL_VOID), immutable(false), vb(NULL) { }
Variable(JS2Class *type, js2val value, bool immutable) : LocalMember(LocalMember::Variable), type(type), value(value), immutable(immutable), vb(NULL) { }
virtual StaticMember *clone() { return new Variable(type, value, immutable); }
virtual LocalMember *clone() { return new Variable(type, value, immutable); }
JS2Class *type; // Type of values that may be stored in this variable, NULL if INACCESSIBLE, FUTURE_TYPE if pending
VariableBinding *vb; // The variable definition node, to resolve future types
js2val value; // This variable's current value; future if the variable has not been declared yet;
// uninitialised if the variable must be written before it can be read
bool immutable; // true if this variable's value may not be changed once set
// XXX union this with the type field later?
VariableBinding *vb; // The variable definition node, to resolve future types
virtual void mark() { GCMARKVALUE(value); }
};
class HoistedVar : public StaticMember {
class DynamicVariable : public LocalMember {
public:
HoistedVar() : StaticMember(Member::HoistedVariable), value(JS2VAL_UNDEFINED), hasFunctionInitializer(false) { }
DynamicVariable() : LocalMember(Member::DynamicVariableKind), value(JS2VAL_UNDEFINED), sealed(false) { }
js2val value; // This variable's current value
bool hasFunctionInitializer; // true if this variable was created by a function statement
// XXX may be an uninstantiated function at compile time
bool sealed; // true if this variable cannot be deleted using the delete operator
virtual StaticMember *clone() { return new HoistedVar(); }
virtual void mark() { GCMARKVALUE(value); }
virtual LocalMember *clone() { return new DynamicVariable(); }
virtual void mark() { GCMARKVALUE(value); }
};
class ConstructorMethod : public StaticMember {
class ConstructorMethod : public LocalMember {
public:
ConstructorMethod() : StaticMember(Member::ConstructorMethod), value(JS2VAL_VOID) { }
ConstructorMethod(js2val value) : StaticMember(Member::ConstructorMethod), value(value) { }
ConstructorMethod() : LocalMember(Member::ConstructorMethod), value(JS2VAL_VOID) { }
ConstructorMethod(js2val value) : LocalMember(Member::ConstructorMethod), value(value) { }
js2val value; // This function itself (a callable object)
js2val value; // This constructor itself (a callable object)
virtual void mark() { GCMARKVALUE(value); }
};
class Accessor : public StaticMember {
class Getter : public LocalMember {
public:
Accessor() : StaticMember(Member::Accessor), type(NULL), code(NULL) { }
Getter() : LocalMember(Member::Getter), type(NULL), code(NULL) { }
JS2Class *type; // The type of the value read from the getter or written into the setter
Invokable *code; // calling this object does the read or write
JS2Class *type; // The type of the value read from this getter
Invokable *code; // calling this object does the read
virtual void mark();
};
class Setter : public LocalMember {
public:
Setter() : LocalMember(Member::Setter), type(NULL), code(NULL) { }
JS2Class *type; // The type of the value written into the setter
Invokable *code; // calling this object does the write
virtual void mark();
};
@ -352,17 +365,19 @@ typedef std::map<String, js2val> DynamicPropertyMap;
typedef DynamicPropertyMap::iterator DynamicPropertyIterator;
// A STATICBINDING describes the member to which one qualified name is bound in a frame. Multiple
// A LOCALBINDING describes the member to which one qualified name is bound in a frame. Multiple
// qualified names may be bound to the same member in a frame, but a qualified name may not be
// bound to multiple members in a frame (except when one binding is for reading only and
// the other binding is for writing only).
class StaticBinding {
class LocalBinding {
public:
StaticBinding(QualifiedName &qname, StaticMember *content) : qname(qname), xplicit(false), content(content) { }
LocalBinding(QualifiedName &qname, LocalMember *content) : qname(qname), content(content), xplicit(false) { }
QualifiedName qname; // The qualified name bound by this binding
// implemented by having separate read & write binding sets
// AccessSet Accesses;
LocalMember *content; // The member to which this qualified name was bound
bool xplicit; // true if this binding should not be imported into the global scope by an import statement
StaticMember *content; // The member to which this qualified name was bound
};
class InstanceMember : public Member {
@ -387,10 +402,10 @@ public:
class InstanceMethod : public InstanceMember {
public:
InstanceMethod(CallableInstance *fInst) : InstanceMember(InstanceMethodKind, NULL, false), fInst(fInst) { }
InstanceMethod(SimpleInstance *fInst) : InstanceMember(InstanceMethodKind, NULL, false), fInst(fInst) { }
Signature type; // This method's signature
// Invokable *code; // This method itself (a callable object); null if this method is abstract
CallableInstance *fInst;
SimpleInstance *fInst;
virtual void mark();
};
@ -424,10 +439,10 @@ typedef std::pair<OverrideStatus *, OverrideStatus *> OverrideStatusPair;
// A StaticBindingMap maps names to a list of StaticBindings. Each StaticBinding in the list
// A LocalBindingMap maps names to a list of LocalBindings. Each LocalBinding in the list
// will have the same QualifiedName.name, but (potentially) different QualifiedName.namespace values
typedef std::multimap<String, StaticBinding *> StaticBindingMap;
typedef StaticBindingMap::iterator StaticBindingIterator;
typedef std::multimap<String, LocalBinding *> LocalBindingMap;
typedef LocalBindingMap::iterator LocalBindingIterator;
typedef std::multimap<String, InstanceBinding *> InstanceBindingMap;
typedef InstanceBindingMap::iterator InstanceBindingIterator;
@ -441,8 +456,8 @@ public:
Frame(ObjectKind kind) : JS2Object(kind), temps(NULL), pluralFrame(NULL) { }
Frame(ObjectKind kind, Frame *pluralFrame) : JS2Object(kind), temps(NULL), pluralFrame(pluralFrame) { }
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
LocalBindingMap localReadBindings; // Map of qualified names to readable members defined in this frame
LocalBindingMap localWriteBindings; // Map of qualified names to writable members defined in this frame
std::vector<js2val> *temps; // temporaries allocted in this frame
uint16 allocateTemp();
@ -542,39 +557,21 @@ public:
SimpleInstance(JS2Class *type);
JS2Class *type; // This instance's type
// Implemented as type->getName()
// const String *typeofString; // A string to return if typeof is invoked on this instance
Slot *slots; // A set of slots that hold this instance's fixed property values
DynamicPropertyMap *dynamicProperties; // A set of this instance's dynamic properties, or NULL if this is a fixed instance
FunctionWrapper *fWrap;
virtual void writeProperty(JS2Metadata *meta, const String *name, js2val newValue);
virtual void markChildren();
virtual ~SimpleInstance() { }
};
// If the instance reposnds to the function call or new operators, then that
// instance is a CallableInstance
class CallableInstance : public JS2Object {
public:
CallableInstance(JS2Class *type);
JS2Class *type; // This instance's type
// Invokable *call; // A procedure to call when this instance is used in a call expression
// Invokable *construct; // A procedure to call when this instance is used in a new expression
// Environment *env; // The environment to pass to the call or construct procedure
FunctionWrapper *fWrap;
// Implemented as type->getName()
// const String *typeofString; // A string to return if typeof is invoked on this instance
Slot *slots; // A set of slots that hold this instance's fixed property values
DynamicPropertyMap *dynamicProperties; // A set of this instance's dynamic properties, or NULL if this is a fixed instance
virtual void markChildren();
virtual void writeProperty(JS2Metadata *meta, const String *name, js2val newValue);
virtual ~CallableInstance() { }
};
// Prototype instances are represented as PROTOTYPE records. Prototype instances
// contain no fixed properties.
class PrototypeInstance : public JS2Object {
public:
PrototypeInstance(JS2Object *parent, JS2Class *type) : JS2Object(PrototypeInstanceKind), parent(parent), type(type) { }
@ -589,20 +586,20 @@ public:
virtual ~PrototypeInstance() { }
};
// Date instances are Callable instances created by the Date class, they have an extra field
// Date instances are simple instances created by the Date class, they have an extra field
// that contains the millisecond count
class DateInstance : public CallableInstance {
class DateInstance : public SimpleInstance {
public:
DateInstance(JS2Class *type) : CallableInstance(type) { }
DateInstance(JS2Class *type) : SimpleInstance(type) { }
float64 ms;
};
// String instances are Callable instances created by the String class, they have an extra field
// String instances are simple instances created by the String class, they have an extra field
// that contains the string data
class StringInstance : public CallableInstance {
class StringInstance : public SimpleInstance {
public:
StringInstance(JS2Class *type) : CallableInstance(type), mValue(NULL) { }
StringInstance(JS2Class *type) : SimpleInstance(type), mValue(NULL) { }
String *mValue; // has been allocated by engine in the GC'able Pond
@ -610,11 +607,11 @@ public:
virtual ~StringInstance() { }
};
// Number instances are Callable instances created by the Number class, they have an extra field
// Number instances are simple instances created by the Number class, they have an extra field
// that contains the float64 data
class NumberInstance : public CallableInstance {
class NumberInstance : public SimpleInstance {
public:
NumberInstance(JS2Class *type) : CallableInstance(type), mValue(0.0) { }
NumberInstance(JS2Class *type) : SimpleInstance(type), mValue(0.0) { }
float64 mValue;
virtual ~NumberInstance() { }
@ -642,22 +639,22 @@ public:
virtual ~FunctionInstance() { }
};
// Array instances are Callable instances created by the Array class, they
// Array instances are simple instances created by the Array class, they
// maintain the value of the 'length' property when 'indexable' elements
// are added.
class ArrayInstance : public CallableInstance {
class ArrayInstance : public SimpleInstance {
public:
ArrayInstance(JS2Class *type) : CallableInstance(type) { }
ArrayInstance(JS2Class *type) : SimpleInstance(type) { }
virtual void writeProperty(JS2Metadata *meta, const String *name, js2val newValue);
virtual ~ArrayInstance() { }
};
// RegExp instances are Callable instances created by the RegExp class, they have an extra field
// RegExp instances are simple instances created by the RegExp class, they have an extra field
// that contains the RegExp object
class RegExpInstance : public CallableInstance {
class RegExpInstance : public SimpleInstance {
public:
RegExpInstance(JS2Class *type) : CallableInstance(type) { }
RegExpInstance(JS2Class *type) : SimpleInstance(type) { }
void setLastIndex(JS2Metadata *meta, js2val a);
void setGlobal(JS2Metadata *meta, js2val a);
@ -1006,7 +1003,7 @@ typedef std::vector<StmtNode *>::iterator TargetListIterator;
typedef std::vector<StmtNode *>::reverse_iterator TargetListReverseIterator;
struct MemberDescriptor {
StaticMember *staticMember;
LocalMember *localMember;
QualifiedName *qname;
};
@ -1053,17 +1050,17 @@ public:
bool hasType(js2val objVal, JS2Class *c);
bool relaxedHasType(js2val objVal, JS2Class *c);
StaticMember *findFlatMember(Frame *container, Multiname *multiname, Access access, Phase phase);
LocalMember *findFlatMember(Frame *container, Multiname *multiname, Access access, Phase phase);
InstanceBinding *resolveInstanceMemberName(JS2Class *js2class, Multiname *multiname, Access access, Phase phase);
HoistedVar *defineHoistedVar(Environment *env, const String *id, StmtNode *p);
Multiname *defineStaticMember(Environment *env, const String *id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, StaticMember *m, size_t pos);
DynamicVariable *defineHoistedVar(Environment *env, const String *id, StmtNode *p);
Multiname *defineLocalMember(Environment *env, const String *id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, LocalMember *m, size_t pos);
OverrideStatusPair *defineInstanceMember(JS2Class *c, Context *cxt, const String *id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, InstanceMember *m, size_t pos);
OverrideStatus *resolveOverrides(JS2Class *c, Context *cxt, const String *id, NamespaceList *namespaces, Access access, bool expectMethod, size_t pos);
OverrideStatus *searchForOverrides(JS2Class *c, const String *id, NamespaceList *namespaces, Access access, size_t pos);
InstanceMember *findInstanceMember(JS2Class *c, QualifiedName *qname, Access access);
Slot *findSlot(js2val thisObjVal, InstanceVariable *id);
bool findStaticMember(JS2Class *c, Multiname *multiname, Access access, Phase phase, MemberDescriptor *result);
bool findLocalMember(JS2Class *c, Multiname *multiname, Access access, Phase phase, MemberDescriptor *result);
JS2Class *getVariableType(Variable *v, Phase phase, size_t pos);
js2val invokeFunction(const char *fname);
@ -1072,7 +1069,7 @@ public:
bool readProperty(js2val container, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
bool readProperty(Frame *pf, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
bool readDynamicProperty(JS2Object *container, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
bool readStaticMember(StaticMember *m, Phase phase, js2val *rval);
bool readLocalMember(LocalMember *m, Phase phase, js2val *rval);
bool readInstanceMember(js2val containerVal, JS2Class *c, QualifiedName *qname, Phase phase, js2val *rval);
JS2Object *lookupDynamicProperty(JS2Object *obj, const String *name);
bool JS2Metadata::hasOwnProperty(JS2Object *obj, const String *name);
@ -1080,13 +1077,13 @@ public:
bool writeProperty(js2val container, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, Phase phase);
bool writeProperty(Frame *container, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, Phase phase);
bool writeDynamicProperty(JS2Object *container, Multiname *multiname, bool createIfMissing, js2val newValue, Phase phase);
bool writeStaticMember(StaticMember *m, js2val newValue, Phase phase);
bool writeLocalMember(LocalMember *m, js2val newValue, Phase phase);
bool writeInstanceMember(js2val containerVal, JS2Class *c, QualifiedName *qname, js2val newValue, Phase phase);
bool deleteProperty(Frame *container, Multiname *multiname, LookupKind *lookupKind, Phase phase, bool *result);
bool deleteProperty(js2val container, Multiname *multiname, LookupKind *lookupKind, Phase phase, bool *result);
bool deleteDynamicProperty(JS2Object *container, Multiname *multiname, LookupKind *lookupKind, bool *result);
bool deleteStaticMember(StaticMember *m, bool *result);
bool deleteLocalMember(LocalMember *m, bool *result);
bool deleteInstanceMember(JS2Class *c, QualifiedName *qname, bool *result);
void addGlobalObjectFunction(char *name, NativeCode *code);
@ -1129,7 +1126,7 @@ public:
// The one and only 'public' namespace
Namespace *publicNamespace;
StaticMember *forbiddenMember; // just need one of these hanging around
LocalMember *forbiddenMember; // just need one of these hanging around
// The base classes:
JS2Class *objectClass;

View File

@ -104,7 +104,7 @@ namespace MetaData {
for (i = 0; i < N_CONSTANTS_COUNT; i++)
{
Variable *v = new Variable(meta->numberClass, meta->engine->allocNumber(NumberObjectConstants[i].value), true);
meta->defineStaticMember(meta->env, &meta->world.identifiers[NumberObjectConstants[i].name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->defineLocalMember(meta->env, &meta->world.identifiers[NumberObjectConstants[i].name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
}
meta->env->removeTopFrame();

View File

@ -244,11 +244,8 @@
b = pop();
ASSERT(JS2VAL_IS_OBJECT(b));
JS2Object *obj = JS2VAL_TO_OBJECT(b);
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
if (obj->kind == SimpleInstanceKind)
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = a;
else
checked_cast<CallableInstance *>(obj)->slots[slotIndex].value = a;
ASSERT(obj->kind == SimpleInstanceKind);
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = a;
push(a);
}
break;
@ -260,11 +257,8 @@
b = pop();
ASSERT(JS2VAL_IS_OBJECT(b));
JS2Object *obj = JS2VAL_TO_OBJECT(b);
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
if (obj->kind == SimpleInstanceKind)
push(checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value);
else
push(checked_cast<CallableInstance *>(obj)->slots[slotIndex].value);
ASSERT(obj->kind == SimpleInstanceKind);
push(checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value);
}
break;
@ -275,11 +269,8 @@
b = top();
ASSERT(JS2VAL_IS_OBJECT(b));
JS2Object *obj = JS2VAL_TO_OBJECT(b);
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
if (obj->kind == SimpleInstanceKind)
push(checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value);
else
push(checked_cast<CallableInstance *>(obj)->slots[slotIndex].value);
ASSERT(obj->kind == SimpleInstanceKind);
push(checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value);
}
break;

View File

@ -1016,16 +1016,10 @@
baseVal = pop();
ASSERT(JS2VAL_IS_OBJECT(baseVal));
JS2Object *obj = JS2VAL_TO_OBJECT(baseVal);
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
if (obj->kind == SimpleInstanceKind)
a = checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value;
else
a = checked_cast<CallableInstance *>(obj)->slots[slotIndex].value;
ASSERT(obj->kind == SimpleInstanceKind);
a = checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value;
float64 num = meta->toFloat64(a);
if (obj->kind == SimpleInstanceKind)
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = allocNumber(num + 1.0);
else
checked_cast<CallableInstance *>(obj)->slots[slotIndex].value = allocNumber(num + 1.0);
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = allocNumber(num + 1.0);
pushNumber(num);
baseVal = JS2VAL_VOID;
}
@ -1037,16 +1031,10 @@
baseVal = pop();
ASSERT(JS2VAL_IS_OBJECT(baseVal));
JS2Object *obj = JS2VAL_TO_OBJECT(baseVal);
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
if (obj->kind == SimpleInstanceKind)
a = checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value;
else
a = checked_cast<CallableInstance *>(obj)->slots[slotIndex].value;
ASSERT(obj->kind == SimpleInstanceKind);
a = checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value;
float64 num = meta->toFloat64(a);
if (obj->kind == SimpleInstanceKind)
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = allocNumber(num - 1.0);
else
checked_cast<CallableInstance *>(obj)->slots[slotIndex].value = allocNumber(num - 1.0);
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = allocNumber(num - 1.0);
pushNumber(num);
baseVal = JS2VAL_VOID;
}
@ -1058,17 +1046,11 @@
baseVal = pop();
ASSERT(JS2VAL_IS_OBJECT(baseVal));
JS2Object *obj = JS2VAL_TO_OBJECT(baseVal);
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
if (obj->kind == SimpleInstanceKind)
a = checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value;
else
a = checked_cast<CallableInstance *>(obj)->slots[slotIndex].value;
ASSERT(obj->kind == SimpleInstanceKind);
a = checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value;
float64 num = meta->toFloat64(a);
a = pushNumber(num + 1.0);
if (obj->kind == SimpleInstanceKind)
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = a;
else
checked_cast<CallableInstance *>(obj)->slots[slotIndex].value = a;
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = a;
baseVal = JS2VAL_VOID;
}
break;
@ -1079,17 +1061,11 @@
baseVal = pop();
ASSERT(JS2VAL_IS_OBJECT(baseVal));
JS2Object *obj = JS2VAL_TO_OBJECT(baseVal);
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
if (obj->kind == SimpleInstanceKind)
a = checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value;
else
a = checked_cast<CallableInstance *>(obj)->slots[slotIndex].value;
ASSERT(obj->kind == SimpleInstanceKind);
a = checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value;
float64 num = meta->toFloat64(a);
a = pushNumber(num - 1.0);
if (obj->kind == SimpleInstanceKind)
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = a;
else
checked_cast<CallableInstance *>(obj)->slots[slotIndex].value = a;
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = a;
baseVal = JS2VAL_VOID;
}
break;

View File

@ -48,22 +48,15 @@
}
else {
FunctionWrapper *fWrap = NULL;
if ((obj->kind == CallableInstanceKind)
if ((obj->kind == SimpleInstanceKind)
&& (meta->objectType(a) == meta->functionClass)) {
fWrap = (checked_cast<CallableInstance *>(obj))->fWrap;
fWrap = (checked_cast<SimpleInstance *>(obj))->fWrap;
}
else
if ((obj->kind == PrototypeInstanceKind)
&& ((checked_cast<PrototypeInstance *>(obj))->type == meta->functionClass)) {
fWrap = (checked_cast<FunctionInstance *>(obj))->fWrap;
}
/*
if (obj->kind == CallableInstanceKind) {
FunctionWrapper *fWrap = NULL;
CallableInstance *dInst = (checked_cast<CallableInstance *>(obj));
if (dInst->type == meta->functionClass)
fWrap = dInst->fWrap;
*/
if (fWrap) {
// XXX - I made this stuff up - extract the 'prototype' property from
// the function being invoked (defaulting to Object.prototype). Then
@ -122,9 +115,9 @@
meta->reportError(Exception::badValueError, "Can't call on primitive value", errorPos());
JS2Object *fObj = JS2VAL_TO_OBJECT(b);
FunctionWrapper *fWrap = NULL;
if ((fObj->kind == CallableInstanceKind)
if ((fObj->kind == SimpleInstanceKind)
&& (meta->objectType(b) == meta->functionClass)) {
fWrap = (checked_cast<CallableInstance *>(fObj))->fWrap;
fWrap = (checked_cast<SimpleInstance *>(fObj))->fWrap;
}
else
if ((fObj->kind == PrototypeInstanceKind)
@ -160,7 +153,7 @@
else
if (fObj->kind == MethodClosureKind) { // XXX I made this up (particularly the frame push of the objectType)
MethodClosure *mc = checked_cast<MethodClosure *>(fObj);
CallableInstance *fInst = mc->method->fInst;
SimpleInstance *fInst = mc->method->fInst;
FunctionWrapper *fWrap = fInst->fWrap;
ParameterFrame *runtimeFrame = new ParameterFrame(fWrap->compileFrame);
runtimeFrame->instantiate(meta->env);
@ -293,9 +286,6 @@
case SimpleInstanceKind:
a = STRING_TO_JS2VAL(checked_cast<SimpleInstance *>(obj)->type->getName());
break;
case CallableInstanceKind:
a = STRING_TO_JS2VAL(checked_cast<CallableInstance *>(obj)->type->getName());
break;
}
}
push(a);

View File

@ -784,7 +784,7 @@ void initStringObject(JS2Metadata *meta)
PrototypeFunction *pf = &prototypeFunctions[0];
while (pf->name) {
CallableInstance *fInst = new CallableInstance(meta->functionClass);
SimpleInstance *fInst = new SimpleInstance(meta->functionClass);
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
/*
XXX not prototype object function properties, like ECMA3, but members of the String class