!!! BROKEN !!! Major bustage, halfway through swicth to current spec. low
level implementation git-svn-id: svn://10.0.0.236/trunk@140155 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
65773f5b59
commit
642d71fcc3
@ -264,7 +264,7 @@ namespace JavaScript {
|
||||
#ifndef _WIN32
|
||||
template<class Value> Data &insert(Key key, Value value);
|
||||
template<class Value> Data &insert(Reference &r, Key key, Value value);
|
||||
template<class Value> Data &insert(Data data);
|
||||
template<class Value> Data &insert(Data data);
|
||||
#else
|
||||
// Microsoft VC6 bug: VC6 doesn't allow this to be defined outside the
|
||||
// class
|
||||
@ -291,15 +291,13 @@ namespace JavaScript {
|
||||
return insert(r, key, value);
|
||||
}
|
||||
|
||||
template<class Value>
|
||||
Data &HashTable<Data, Key, H>::insert(Data data)
|
||||
{
|
||||
Key key = data.key();
|
||||
Value value = data.value();
|
||||
return insert(key, value);
|
||||
}
|
||||
|
||||
|
||||
template<class Value>
|
||||
Data &HashTable<Data, Key, H>::insert(Data data)
|
||||
{
|
||||
Key key = data.key();
|
||||
Value value = data.value();
|
||||
return insert(key, value);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -364,46 +362,48 @@ namespace JavaScript {
|
||||
#endif
|
||||
return e->data;
|
||||
}
|
||||
|
||||
// Insert the given key/value pair into the hash table. If an entry with a
|
||||
// matching key already exists, replace that entry's value.
|
||||
// Return a reference to the new entry's value.
|
||||
|
||||
// Microsoft VC6 bug: VC6 doesn't allow this to be defined outside the class
|
||||
template<class Data, class Key, class H> template<class Value>
|
||||
Data &HashTable<Data, Key, H>::insert(Key key, Value value)
|
||||
{
|
||||
Reference r(*this, key);
|
||||
if (r)
|
||||
return *r = value;
|
||||
else
|
||||
return insert(r, key, value);
|
||||
}
|
||||
|
||||
template<class Data, class Key, class H> template<class Value>
|
||||
Data &HashTable<Data, Key, H>::insert(Data data)
|
||||
{
|
||||
Key key = data.key();
|
||||
Value value = data.value();
|
||||
return insert(key, value);
|
||||
}
|
||||
|
||||
|
||||
// Insert the given key/value pair into the hash table. If an entry with a
|
||||
// matching key already exists, replace that entry's value.
|
||||
// Return a reference to the new entry's value.
|
||||
|
||||
// Microsoft VC6 bug: VC6 doesn't allow this to be defined outside the class
|
||||
template<class Data, class Key, class H> template<class Value>
|
||||
Data &HashTable<Data, Key, H>::insert(Key key, Value value)
|
||||
{
|
||||
Reference r(*this, key);
|
||||
if (r)
|
||||
return *r = value;
|
||||
else
|
||||
return insert(r, key, value);
|
||||
}
|
||||
|
||||
template<class Data, class Key, class H> template<class Value>
|
||||
Data &HashTable<Data, Key, H>::insert(Data data)
|
||||
{
|
||||
Key key = data.key();
|
||||
Value value = data.value();
|
||||
return insert(key, value);
|
||||
}
|
||||
|
||||
#endif // !_WIN32
|
||||
|
||||
template<class Data, class Key, class H>
|
||||
inline Data &HashTable<Data, Key, H>::insert(Reference &r, Key key)
|
||||
{
|
||||
ASSERT(r.ht == this && !r.entry);
|
||||
Entry *e = new Entry(r.keyHash, key);
|
||||
*r.backpointer = e;
|
||||
++nEntries;
|
||||
maybeGrow();
|
||||
#ifdef DEBUG
|
||||
--r.ht->nReferences;
|
||||
r.ht = 0;
|
||||
#endif
|
||||
return e->data;
|
||||
}
|
||||
|
||||
template<class Data, class Key, class H>
|
||||
inline Data &HashTable<Data, Key, H>::insert(Reference &r, Key key)
|
||||
{
|
||||
ASSERT(r.ht == this && !r.entry);
|
||||
Entry *e = new Entry(r.keyHash, key);
|
||||
*r.backpointer = e;
|
||||
++nEntries;
|
||||
maybeGrow();
|
||||
#ifdef DEBUG
|
||||
--r.ht->nReferences;
|
||||
r.ht = 0;
|
||||
#endif
|
||||
return e->data;
|
||||
}
|
||||
|
||||
template<class Data, class Key, class H>
|
||||
Data &HashTable<Data, Key, H>::insert(Key key)
|
||||
{
|
||||
@ -415,7 +415,6 @@ namespace JavaScript {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Reference r must point to an existing entry. Delete that entry.
|
||||
// The reference is not valid after this method is called.
|
||||
template<class Data, class Key, class H>
|
||||
|
||||
@ -70,8 +70,8 @@ js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 newLength)
|
||||
{
|
||||
js2val result = meta->engine->allocNumber(newLength);
|
||||
|
||||
if ((obj->kind == PrototypeInstanceKind)
|
||||
|| (checked_cast<PrototypeInstance *>(obj)->type == meta->arrayClass)) {
|
||||
if ((obj->kind == SimpleInstanceKind)
|
||||
|| (checked_cast<SimpleInstance *>(obj)->type == meta->arrayClass)) {
|
||||
uint32 length = getLength(meta, obj);
|
||||
if (newLength < length) {
|
||||
// need to delete all the elements above the new length
|
||||
@ -85,17 +85,17 @@ js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 newLength)
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->kind == PrototypeInstanceKind) {
|
||||
if (obj->kind == SimpleInstanceKind) {
|
||||
// Can't call 'writeDynamicProperty' as that'll just cycle back here for
|
||||
// ArrayInstances.
|
||||
DynamicPropertyMap *dMap = &checked_cast<PrototypeInstance *>(obj)->dynamicProperties;
|
||||
DynamicPropertyMap *dMap = &checked_cast<SimpleInstance *>(obj)->dynamicProperties;
|
||||
DynamicPropertyBinding **dpbP = (*dMap)[*meta->engine->length_StringAtom];
|
||||
if (dpbP) {
|
||||
(*dpbP)->v.value = result;
|
||||
return result;
|
||||
}
|
||||
DynamicPropertyBinding *dpb = new DynamicPropertyBinding(*meta->engine->length_StringAtom, DynamicPropertyValue(result, DynamicPropertyValue::PERMANENT));
|
||||
checked_cast<PrototypeInstance *>(obj)->dynamicProperties.insert(dpb->name, dpb);
|
||||
checked_cast<SimpleInstance *>(obj)->dynamicProperties.insert(dpb->name, dpb);
|
||||
}
|
||||
else {
|
||||
meta->writeDynamicProperty(obj, meta->engine->length_StringAtom, true, result, RunPhase);
|
||||
@ -138,8 +138,8 @@ js2val Array_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val *
|
||||
static js2val Array_toString(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
|
||||
{
|
||||
if (!JS2VAL_IS_OBJECT(thisValue)
|
||||
|| (JS2VAL_TO_OBJECT(thisValue)->kind != PrototypeInstanceKind)
|
||||
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->arrayClass))
|
||||
|| (JS2VAL_TO_OBJECT(thisValue)->kind != SimpleInstanceKind)
|
||||
|| ((checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->arrayClass))
|
||||
meta->reportError(Exception::typeError, "Array.prototype.toString called on a non Array", meta->engine->errorPos());
|
||||
|
||||
ArrayInstance *arrInst = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(thisValue));
|
||||
@ -170,8 +170,8 @@ static js2val Array_toString(JS2Metadata *meta, const js2val thisValue, js2val *
|
||||
static js2val Array_toSource(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
|
||||
{
|
||||
if (!JS2VAL_IS_OBJECT(thisValue)
|
||||
|| (JS2VAL_TO_OBJECT(thisValue)->kind != PrototypeInstanceKind)
|
||||
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->arrayClass))
|
||||
|| (JS2VAL_TO_OBJECT(thisValue)->kind != SimpleInstanceKind)
|
||||
|| ((checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->arrayClass))
|
||||
meta->reportError(Exception::typeError, "Array.prototype.toString called on a non Array", meta->engine->errorPos());
|
||||
|
||||
ArrayInstance *arrInst = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(thisValue));
|
||||
@ -566,8 +566,8 @@ static js2val Array_sort(JS2Metadata *meta, const js2val thisValue, js2val *argv
|
||||
|
||||
if (argc > 0) {
|
||||
if (!JS2VAL_IS_UNDEFINED(argv[0])) {
|
||||
if ((JS2VAL_TO_OBJECT(argv[0])->kind != PrototypeInstanceKind)
|
||||
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(argv[0])))->type != meta->functionClass))
|
||||
if ((JS2VAL_TO_OBJECT(argv[0])->kind != SimpleInstanceKind)
|
||||
|| ((checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(argv[0])))->type != meta->functionClass))
|
||||
meta->reportError(Exception::typeError, "sort needs a compare function", meta->engine->errorPos());
|
||||
ca.target = JS2VAL_TO_OBJECT(argv[0]);
|
||||
}
|
||||
|
||||
@ -79,8 +79,8 @@ namespace MetaData {
|
||||
static js2val Boolean_toString(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
|
||||
{
|
||||
if (!JS2VAL_IS_OBJECT(thisValue)
|
||||
|| (JS2VAL_TO_OBJECT(thisValue)->kind != PrototypeInstanceKind)
|
||||
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->booleanClass))
|
||||
|| (JS2VAL_TO_OBJECT(thisValue)->kind != SimpleInstanceKind)
|
||||
|| ((checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->booleanClass))
|
||||
meta->reportError(Exception::typeError, "Boolean.toString called on something other than a boolean thing", meta->engine->errorPos());
|
||||
BooleanInstance *boolInst = checked_cast<BooleanInstance *>(JS2VAL_TO_OBJECT(thisValue));
|
||||
return (boolInst->mValue) ? meta->engine->allocString(meta->engine->true_StringAtom) : meta->engine->allocString(meta->engine->false_StringAtom);
|
||||
@ -89,8 +89,8 @@ namespace MetaData {
|
||||
static js2val Boolean_valueOf(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
|
||||
{
|
||||
if (!JS2VAL_IS_OBJECT(thisValue)
|
||||
|| (JS2VAL_TO_OBJECT(thisValue)->kind != PrototypeInstanceKind)
|
||||
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->booleanClass))
|
||||
|| (JS2VAL_TO_OBJECT(thisValue)->kind != SimpleInstanceKind)
|
||||
|| ((checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->booleanClass))
|
||||
meta->reportError(Exception::typeError, "Boolean.valueOf called on something other than a boolean thing", meta->engine->errorPos());
|
||||
BooleanInstance *boolInst = checked_cast<BooleanInstance *>(JS2VAL_TO_OBJECT(thisValue));
|
||||
return (boolInst->mValue) ? JS2VAL_TRUE : JS2VAL_FALSE;
|
||||
|
||||
@ -296,8 +296,8 @@ static int32 WeekDay(float64 t)
|
||||
static float64 *Date_getProlog(JS2Metadata *meta, const js2val thisValue)
|
||||
{
|
||||
if (!JS2VAL_IS_OBJECT(thisValue)
|
||||
|| (JS2VAL_TO_OBJECT(thisValue)->kind != PrototypeInstanceKind)
|
||||
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->dateClass))
|
||||
|| (JS2VAL_TO_OBJECT(thisValue)->kind != SimpleInstanceKind)
|
||||
|| ((checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->dateClass))
|
||||
meta->reportError(Exception::typeError, "You really need a date", meta->engine->errorPos());
|
||||
DateInstance *dateInst = checked_cast<DateInstance *>(JS2VAL_TO_OBJECT(thisValue));
|
||||
return &dateInst->ms;
|
||||
|
||||
@ -847,10 +847,7 @@ namespace MetaData {
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(thisValue);
|
||||
ASSERT(obj->kind == ClassKind);
|
||||
JS2Class *c = checked_cast<JS2Class *>(obj);
|
||||
if (c->prototype)
|
||||
return OBJECT_TO_JS2VAL(new PrototypeInstance(meta, c->prototype, c));
|
||||
else
|
||||
return OBJECT_TO_JS2VAL(new SimpleInstance(c));
|
||||
return OBJECT_TO_JS2VAL(new SimpleInstance(meta, c->prototype, c));
|
||||
}
|
||||
|
||||
// Save current engine state (pc, environment top) and
|
||||
@ -991,18 +988,16 @@ namespace MetaData {
|
||||
case MethodClosureKind:
|
||||
a = STRING_TO_JS2VAL(Function_StringAtom);
|
||||
break;
|
||||
case PrototypeInstanceKind:
|
||||
if (checked_cast<PrototypeInstance *>(obj)->type == meta->functionClass)
|
||||
case SimpleInstanceKind:
|
||||
if (checked_cast<SimpleInstance *>(obj)->type == meta->functionClass)
|
||||
a = STRING_TO_JS2VAL(Function_StringAtom);
|
||||
else
|
||||
a = STRING_TO_JS2VAL(object_StringAtom);
|
||||
// a = STRING_TO_JS2VAL(checked_cast<SimpleInstance *>(obj)->type->getName());
|
||||
break;
|
||||
case PackageKind:
|
||||
a = STRING_TO_JS2VAL(object_StringAtom);
|
||||
break;
|
||||
case SimpleInstanceKind:
|
||||
a = STRING_TO_JS2VAL(checked_cast<SimpleInstance *>(obj)->type->getName());
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
break;
|
||||
@ -1025,9 +1020,7 @@ namespace MetaData {
|
||||
return buildNameList();
|
||||
}
|
||||
|
||||
// XXX need help from spec. Here we iterate over dynamic properties only
|
||||
// unless the object is a Class, in which case we iterate the static
|
||||
// members.
|
||||
// Iterate over LocalBindings
|
||||
bool ForIteratorObject::buildNameList()
|
||||
{
|
||||
if (obj->kind == ClassKind) {
|
||||
@ -1040,23 +1033,22 @@ namespace MetaData {
|
||||
}
|
||||
}
|
||||
else {
|
||||
DynamicPropertyMap *dMap = NULL;
|
||||
LocalBindingMap *lMap = NULL;
|
||||
if (obj->kind == SimpleInstanceKind)
|
||||
dMap = (checked_cast<SimpleInstance *>(obj))->dynamicProperties;
|
||||
lMap = &(checked_cast<SimpleInstance *>(obj))->localBindings;
|
||||
else
|
||||
if (obj->kind == PackageKind)
|
||||
dMap = &(checked_cast<Package *>(obj))->dynamicProperties;
|
||||
lMap = &(checked_cast<Package *>(obj))->localBindings;
|
||||
else
|
||||
if (obj->kind == PrototypeInstanceKind)
|
||||
dMap = &(checked_cast<PrototypeInstance *>(obj))->dynamicProperties;
|
||||
if (obj->kind == ClassKind)
|
||||
lMap = &(checked_cast<JS2Class *>(obj))->localBindings;
|
||||
|
||||
if (dMap) {
|
||||
nameList = new const String *[dMap->size()];
|
||||
if (lMap) {
|
||||
nameList = new const String *[lMap->size()];
|
||||
length = 0;
|
||||
for (DynamicPropertyIterator dpi = dMap->begin(), dpend = dMap->end(); (dpi != dpend); dpi++) {
|
||||
DynamicPropertyBinding *dpb = *dpi;
|
||||
if (dpb->v.flags & DynamicPropertyValue::ENUMERATE)
|
||||
nameList[length++] = &dpb->name;
|
||||
for (LocalBindingIterator bi = lMap->begin(), bend = lMap->end(); (bi != bend); bi++) {
|
||||
LocalBindingEntry *lbe = *bi;
|
||||
nameList[length++] = &lbe->name;
|
||||
}
|
||||
it = 0;
|
||||
return (length != 0);
|
||||
@ -1087,8 +1079,8 @@ namespace MetaData {
|
||||
break;
|
||||
}
|
||||
if (it == length) {
|
||||
if (obj->kind == PrototypeInstanceKind) {
|
||||
obj = (checked_cast<PrototypeInstance *>(obj))->parent;
|
||||
if (obj->kind == SimpleInstanceKind) {
|
||||
obj = (checked_cast<SimpleInstance *>(obj))->super;
|
||||
if (obj)
|
||||
return buildNameList();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -58,6 +58,8 @@ typedef js2val (Callor)(JS2Metadata *meta, const js2val thisValue, js2val *argv,
|
||||
typedef js2val (Constructor)(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc);
|
||||
typedef js2val (NativeCode)(JS2Metadata *meta, const js2val thisValue, js2val argv[], uint32 argc);
|
||||
|
||||
typedef bool (Read)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
|
||||
typedef bool (Write)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, js2val rval);
|
||||
|
||||
extern void initDateObject(JS2Metadata *meta);
|
||||
extern void initStringObject(JS2Metadata *meta);
|
||||
@ -94,7 +96,7 @@ extern js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 length);
|
||||
|
||||
// OBJECT is the semantic domain of all possible objects and is defined as:
|
||||
// OBJECT = UNDEFINED | NULL | BOOLEAN | FLOAT64 | LONG | ULONG | CHARACTER | STRING | NAMESPACE |
|
||||
// COMPOUNDATTRIBUTE | CLASS | METHODCLOSURE | PROTOTYPE | INSTANCE | PACKAGE
|
||||
// COMPOUNDATTRIBUTE | CLASS | METHODCLOSURE | INSTANCE | PACKAGE
|
||||
//
|
||||
// In this implementation, the primitive types are distinguished by the tag value
|
||||
// of a JS2Value (see js2value.h). Non-primitive types are distinguished by calling
|
||||
@ -107,7 +109,6 @@ enum ObjectKind {
|
||||
ParameterKind,
|
||||
ClassKind,
|
||||
BlockFrameKind,
|
||||
PrototypeInstanceKind,
|
||||
SimpleInstanceKind,
|
||||
MultinameKind,
|
||||
MethodClosureKind,
|
||||
@ -168,7 +169,7 @@ public:
|
||||
class JS2Object {
|
||||
// Every object is either undefined, null, a Boolean,
|
||||
// a number, a string, a namespace, a compound attribute, a class, a method closure,
|
||||
// a prototype instance, a class instance, a package object, or the global object.
|
||||
// a class instance, a package object, or the global object.
|
||||
public:
|
||||
|
||||
JS2Object(ObjectKind kind) : kind(kind) { }
|
||||
@ -384,30 +385,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
// A DYNAMICPROPERTY record describes one dynamic property of one (prototype or class) instance.
|
||||
class DynamicPropertyValue {
|
||||
public:
|
||||
enum Flags { ENUMERATE = 0x1, READONLY = 0x2, PERMANENT = 0x4 };
|
||||
|
||||
DynamicPropertyValue(js2val v) : value(v), flags(ENUMERATE) { }
|
||||
DynamicPropertyValue(js2val v, uint32 f) : value(v), flags(f) { }
|
||||
|
||||
js2val value;
|
||||
uint32 flags;
|
||||
};
|
||||
|
||||
class DynamicPropertyBinding {
|
||||
public:
|
||||
DynamicPropertyBinding(const String name) : name(name), v(JS2VAL_VOID) { }
|
||||
DynamicPropertyBinding(const String name, DynamicPropertyValue v) : name(name), v(v) { }
|
||||
|
||||
const String name;
|
||||
DynamicPropertyValue v;
|
||||
};
|
||||
|
||||
typedef HashTable<DynamicPropertyBinding *, const String> DynamicPropertyMap;
|
||||
typedef TableIterator<DynamicPropertyBinding *, const String> DynamicPropertyIterator;
|
||||
|
||||
|
||||
// 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
|
||||
@ -599,7 +576,7 @@ public:
|
||||
void removeTopFrame() { frameList.pop_front(); }
|
||||
|
||||
js2val findThis(bool allowPrototypeThis);
|
||||
js2val lexicalRead(JS2Metadata *meta, Multiname *multiname, Phase phase);
|
||||
void lexicalRead(JS2Metadata *meta, Multiname *multiname, Phase phase, js2val *rval);
|
||||
void lexicalWrite(JS2Metadata *meta, Multiname *multiname, js2val newValue, bool createIfMissing, Phase phase);
|
||||
void lexicalInit(JS2Metadata *meta, Multiname *multiname, js2val newValue);
|
||||
bool lexicalDelete(JS2Metadata *meta, Multiname *multiname, Phase phase);
|
||||
@ -619,36 +596,36 @@ class JS2Class : public NonWithFrame {
|
||||
public:
|
||||
JS2Class(JS2Class *super, JS2Object *proto, Namespace *privateNamespace, bool dynamic, bool allowNull, bool final, const String *name);
|
||||
|
||||
const String *getName() { return name; }
|
||||
const String *getName() { return typeofString; }
|
||||
|
||||
InstanceBindingMap instanceBindings; // Map of qualified names to instance members defined in this class
|
||||
|
||||
InstanceVariable **instanceInitOrder; // List of instance variables defined in this class in the order in which they are initialised
|
||||
|
||||
bool complete; // true after all members of this class have been added to this CLASS record
|
||||
|
||||
JS2Class *super; // This class's immediate superclass or null if none
|
||||
InstanceBindingMap instanceBindings; // Map of qualified names to instance members defined in this class
|
||||
InstanceVariable **instanceInitOrder; // List of instance variables defined in this class in the order in which they are initialised
|
||||
bool complete; // true after all members of this class have been added to this CLASS record
|
||||
JS2Object *prototype; // An object that serves as this class's prototype for compatibility with ECMAScript 3; may be null
|
||||
|
||||
const String *typeofString;
|
||||
Namespace *privateNamespace; // This class's private namespace
|
||||
|
||||
bool dynamic; // true if this class or any of its ancestors was defined with the dynamic attribute
|
||||
bool allowNull; // true if null is considered to be an instance of this class
|
||||
bool final; // true if this class cannot be subclassed
|
||||
js2val defaultValue; // An instance of this class assigned when a variable is not explicitly initialized
|
||||
|
||||
Callor *call; // A procedure to call when this class is used in a call expression
|
||||
Constructor *construct; // A procedure to call when this class is used in a new expression
|
||||
js2val implicitCoerce(JS2Metadata *meta, js2val newValue);
|
||||
// A procedure to call when a value is assigned whose type is this class
|
||||
|
||||
void emitDefaultValue(BytecodeContainer *bCon, size_t pos);
|
||||
|
||||
|
||||
Read *read;
|
||||
Write *write;
|
||||
|
||||
|
||||
bool isAncestor(JS2Class *heir);
|
||||
|
||||
js2val defaultValue; // An instance of this class assigned when a variable is not explicitly initialized
|
||||
|
||||
uint32 slotCount;
|
||||
|
||||
const String *name;
|
||||
|
||||
virtual void instantiate(Environment * /* env */) { } // nothing to do
|
||||
virtual void markChildren();
|
||||
@ -658,10 +635,9 @@ public:
|
||||
|
||||
class Package : public NonWithFrame {
|
||||
public:
|
||||
Package(Namespace *internal) : NonWithFrame(PackageKind), internalNamespace(internal) { }
|
||||
|
||||
Package(Namespace *internal) : NonWithFrame(PackageKind), super(JS2VAL_VOID), internalNamespace(internal) { }
|
||||
js2val super;
|
||||
Namespace *internalNamespace; // This Package's internal namespace
|
||||
DynamicPropertyMap dynamicProperties; // A set of this Package's dynamic properties
|
||||
virtual void markChildren();
|
||||
virtual ~Package() { }
|
||||
};
|
||||
@ -693,16 +669,16 @@ public:
|
||||
|
||||
|
||||
// Instances which do not respond to the function call or new operators are represented as SIMPLEINSTANCE records
|
||||
// XXX SimpleInstance dynamic properties don't need the ECMA3 property attributes
|
||||
class SimpleInstance : public JS2Object {
|
||||
public:
|
||||
SimpleInstance(JS2Class *type);
|
||||
SimpleInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type);
|
||||
|
||||
LocalBindingMap localBindings;
|
||||
js2val super;
|
||||
bool sealed;
|
||||
JS2Class *type; // This instance's type
|
||||
Slot *slots; // A set of slots that hold this instance's fixed property values
|
||||
|
||||
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 markChildren();
|
||||
@ -712,69 +688,50 @@ public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Prototype instances are represented as PROTOTYPE records. Prototype instances
|
||||
// contain no fixed properties.
|
||||
class PrototypeInstance : public JS2Object {
|
||||
public:
|
||||
PrototypeInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type);
|
||||
|
||||
JS2Object *parent; // If this instance was created by calling new on a prototype function,
|
||||
// the value of the function’s prototype property at the time of the call;
|
||||
// none otherwise. (aka [[prototype]], aka __prototype__)
|
||||
JS2Class *type; // XXX used to determine [[class]] value
|
||||
DynamicPropertyMap dynamicProperties; // A set of this instance's dynamic properties
|
||||
virtual void markChildren();
|
||||
virtual ~PrototypeInstance() { }
|
||||
|
||||
virtual void writeProperty(JS2Metadata *meta, const String *name, js2val newValue, uint32 flags);
|
||||
|
||||
};
|
||||
|
||||
// Date instances are simple instances created by the Date class, they have an extra field
|
||||
// that contains the millisecond count
|
||||
class DateInstance : public PrototypeInstance {
|
||||
class DateInstance : public SimpleInstance {
|
||||
public:
|
||||
DateInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type) : PrototypeInstance(meta, parent, type) { }
|
||||
DateInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type) : SimpleInstance(meta, parent, type) { }
|
||||
|
||||
float64 ms;
|
||||
};
|
||||
|
||||
// String instances are simple instances created by the String class, they have an extra field
|
||||
// that contains the string data
|
||||
class StringInstance : public PrototypeInstance {
|
||||
class StringInstance : public SimpleInstance {
|
||||
public:
|
||||
StringInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type) : PrototypeInstance(meta, parent, type), mValue(NULL) { }
|
||||
StringInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type) : SimpleInstance(meta, parent, type), mValue(NULL) { }
|
||||
|
||||
String *mValue; // has been allocated by engine in the GC'able Pond
|
||||
|
||||
virtual void markChildren() { PrototypeInstance::markChildren(); if (mValue) JS2Object::mark(mValue); }
|
||||
virtual void markChildren() { SimpleInstance::markChildren(); if (mValue) JS2Object::mark(mValue); }
|
||||
virtual ~StringInstance() { }
|
||||
};
|
||||
|
||||
// Number instances are simple instances created by the Number class, they have an extra field
|
||||
// that contains the float64 data
|
||||
class NumberInstance : public PrototypeInstance {
|
||||
class NumberInstance : public SimpleInstance {
|
||||
public:
|
||||
NumberInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type) : PrototypeInstance(meta, parent, type), mValue(0.0) { }
|
||||
NumberInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type) : SimpleInstance(meta, parent, type), mValue(0.0) { }
|
||||
|
||||
float64 mValue;
|
||||
virtual ~NumberInstance() { }
|
||||
};
|
||||
|
||||
// Boolean instances are PrototypeInstances created by the Boolean class, they have an extra field
|
||||
// Boolean instances are simple instances created by the Boolean class, they have an extra field
|
||||
// that contains the bool data
|
||||
class BooleanInstance : public PrototypeInstance {
|
||||
class BooleanInstance : public SimpleInstance {
|
||||
public:
|
||||
BooleanInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type) : PrototypeInstance(meta, parent, type), mValue(false) { }
|
||||
BooleanInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type) : SimpleInstance(meta, parent, type), mValue(false) { }
|
||||
|
||||
bool mValue;
|
||||
virtual ~BooleanInstance() { }
|
||||
};
|
||||
|
||||
// Function instances are PrototypeInstances created by the Function class, they have an extra field
|
||||
// Function instances are SimpleInstances created by the Function class, they have an extra field
|
||||
// that contains a pointer to the function implementation
|
||||
class FunctionInstance : public PrototypeInstance {
|
||||
class FunctionInstance : public SimpleInstance {
|
||||
public:
|
||||
FunctionInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type);
|
||||
|
||||
@ -784,12 +741,12 @@ public:
|
||||
virtual ~FunctionInstance() { }
|
||||
};
|
||||
|
||||
// Array instances are PrototypeInstances created by the Array class, they
|
||||
// Array instances are SimpleInstances created by the Array class, they
|
||||
// maintain the value of the 'length' property when 'indexable' elements
|
||||
// are added.
|
||||
class ArrayInstance : public PrototypeInstance {
|
||||
class ArrayInstance : public SimpleInstance {
|
||||
public:
|
||||
ArrayInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type) : PrototypeInstance(meta, parent, type) { setLength(meta, this, 0); }
|
||||
ArrayInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type) : SimpleInstance(meta, parent, type) { setLength(meta, this, 0); }
|
||||
|
||||
virtual void writeProperty(JS2Metadata *meta, const String *name, js2val newValue, uint32 flags);
|
||||
virtual ~ArrayInstance() { }
|
||||
@ -799,7 +756,7 @@ public:
|
||||
// that contains the RegExp object
|
||||
class RegExpInstance : public SimpleInstance {
|
||||
public:
|
||||
RegExpInstance(JS2Class *type) : SimpleInstance(type) { }
|
||||
RegExpInstance(JS2Metadata *meta, JS2Object *parent, JS2Class *type) : SimpleInstance(meta, parent, type) { }
|
||||
|
||||
void setLastIndex(JS2Metadata *meta, js2val a);
|
||||
void setGlobal(JS2Metadata *meta, js2val a);
|
||||
@ -1261,7 +1218,6 @@ public:
|
||||
JS2Class *attributeClass;
|
||||
JS2Class *classClass;
|
||||
JS2Class *functionClass;
|
||||
JS2Class *prototypeClass;
|
||||
JS2Class *packageClass;
|
||||
JS2Class *dateClass;
|
||||
JS2Class *regexpClass;
|
||||
@ -1306,9 +1262,6 @@ inline bool operator!=(MetaData::LocalBindingEntry *s1, const String &s2) { retu
|
||||
inline bool operator==(MetaData::InstanceBindingEntry *s1, const String &s2) { return s1->name == s2;}
|
||||
inline bool operator!=(MetaData::InstanceBindingEntry *s1, const String &s2) { return s1->name != s2;}
|
||||
|
||||
inline bool operator==(MetaData::DynamicPropertyBinding *s1, const String &s2) { return s1->name == s2;}
|
||||
inline bool operator!=(MetaData::DynamicPropertyBinding *s1, const String &s2) { return s1->name != s2;}
|
||||
|
||||
|
||||
}; // namespace Javascript
|
||||
|
||||
|
||||
@ -38,7 +38,9 @@
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
b = pop();
|
||||
if (!meta->readProperty(&b, mn, &lookup, RunPhase, &a))
|
||||
|
||||
JS2Class *limit = objectType(b);
|
||||
if (!limit->read(meta, b, limit, mn, lookup, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
push(a);
|
||||
}
|
||||
@ -91,7 +93,8 @@
|
||||
{
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
push(meta->env->lexicalRead(meta, mn, phase));
|
||||
meta->env->lexicalRead(meta, mn, phase, &a);
|
||||
push(a);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user