New implementation of read/write handling, fixed gc bugs etc.

This commit is contained in:
rogerl%netscape.com 2003-05-09 23:05:01 +00:00
Родитель 08874ced8a
Коммит dfc97970bc
12 изменённых файлов: 244 добавлений и 262 удалений

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

@ -84,8 +84,7 @@ js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 newLength)
}
Multiname *mn = new Multiname(meta->engine->length_StringAtom, meta->publicNamespace);
DEFINE_ROOTKEEPER(rk, mn);
LookupKind lookup(false, JS2VAL_NULL);
defaultWriteProperty(meta, OBJECT_TO_JS2VAL(obj), meta->arrayClass, mn, &lookup, true, result, false);
defaultWriteProperty(meta, OBJECT_TO_JS2VAL(obj), meta->arrayClass, mn, meta->env, true, result, false);
}
else {
JS2Class *c = meta->objectType(obj);
@ -227,6 +226,7 @@ js2val Array_concat(JS2Metadata *meta, const js2val thisValue, js2val *argv, uin
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
DEFINE_ROOTKEEPER(rk, A);
uint32 n = 0;
uint32 i = 0;
@ -383,6 +383,7 @@ static js2val Array_slice(JS2Metadata *meta, const js2val thisValue, js2val *arg
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
DEFINE_ROOTKEEPER(rk, A);
uint32 length = getLength(meta, thisObj);
@ -583,25 +584,22 @@ static js2val Array_sort(JS2Metadata *meta, const js2val thisValue, js2val *argv
JS2Object *thisObj = JS2VAL_TO_OBJECT(thatValue);
uint32 length = getLength(meta, thisObj);
if (length > 0) {
uint32 i;
js2val *vec = new js2val[length];
uint32 i;
// XXX bogus! new[] was supposed to behave itself, not just assert fail or crash
if (length > 0x1000000)
meta->reportError(Exception::internalError, "out of memory", meta->engine->errorPos());
JS2Class *c = meta->objectType(thisObj);
// XXX Need to root the Strings somewhere, this'll do for now..
Multiname *mn1 = new Multiname(meta->publicNamespace);
DEFINE_ROOTKEEPER(rk1, mn1);
for (i = 0; i < length; i++) {
mn1->name = meta->engine->numberToString(i);
c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &vec[i]);
}
js2val *vec = new js2val[length];
js_qsort(vec, length, &ca);
JS2Class *c = meta->objectType(thisObj);
for (i = 0; i < length; i++) {
c->readPublic(meta, &thatValue, c, meta->engine->numberToString(i), RunPhase, &vec[i]);
}
for (i = 0; i < length; i++) {
mn1->name = meta->engine->numberToString(i);
c->writePublic(meta, thatValue, c, mn1->name, true, vec[i]);
}
js_qsort(vec, length, &ca);
for (i = 0; i < length; i++) {
c->writePublic(meta, thatValue, c, meta->engine->numberToString(i), true, vec[i]);
}
return thatValue;
}
@ -618,6 +616,7 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
DEFINE_ROOTKEEPER(rk, A);
int32 arg0 = meta->toInteger(argv[0]);
uint32 start;

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

@ -97,6 +97,11 @@ namespace MetaData {
DEFINE_ROOTKEEPER(rk2, astr);
DEFINE_ROOTKEEPER(rk3, bstr);
DEFINE_ROOTKEEPER(rk4, a);
DEFINE_ROOTKEEPER(rk5, b);
DEFINE_ROOTKEEPER(rk6, baseVal);
DEFINE_ROOTKEEPER(rk7, indexVal);
retval = JS2VAL_VOID;
while (true) {
try {
@ -125,6 +130,7 @@ namespace MetaData {
// one that matches the handler's. The bytecode container, pc and
// sp are all reset appropriately, and execution continues.
HandlerData *hndlr = (HandlerData *)mTryStack.top();
// mTryStack.pop();
ActivationFrame *curAct = (activationStackEmpty()) ? NULL : (activationStackTop - 1);
js2val x = JS2VAL_UNDEFINED;
@ -247,6 +253,13 @@ namespace MetaData {
return result;
}
String *JS2Engine::allocStringPtr(const char16 *s, uint32 length)
{
String *p = (String *)(JS2Object::alloc(sizeof(String), PondScum::StringFlag));
String *result = new (p) String(s, length);
return result;
}
String *JS2Engine::allocStringPtr(const String *s)
{
String *p = (String *)(JS2Object::alloc(sizeof(String), PondScum::StringFlag));
@ -977,7 +990,8 @@ namespace MetaData {
// jump to start of new bytecodeContainer
void JS2Engine::jsr(Phase execPhase, BytecodeContainer *new_bCon, uint32 stackBase, js2val returnVal, Environment *env)
{
ASSERT(activationStackTop < (activationStack + MAX_ACTIVATION_STACK));
if (activationStackTop >= (activationStack + MAX_ACTIVATION_STACK))
meta->reportError(Exception::internalError, "out of activation stack", meta->engine->errorPos());
activationStackTop->bCon = bCon;
activationStackTop->pc = pc;
activationStackTop->phase = phase;

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

@ -238,12 +238,14 @@ public:
js2val posInfValue;
js2val negInfValue;
js2val allocString(const String *s) { return STRING_TO_JS2VAL(allocStringPtr(s)); }
js2val allocString(const String &s) { return allocString(&s); }
js2val allocString(const char *s) { return STRING_TO_JS2VAL(allocStringPtr(s)); }
js2val allocString(const String *s, uint32 index, uint32 length) { return STRING_TO_JS2VAL(allocStringPtr(s, index, length)); }
js2val allocString(const String *s) { return STRING_TO_JS2VAL(allocStringPtr(s)); }
js2val allocString(const String &s) { return allocString(&s); }
js2val allocString(const char *s) { return STRING_TO_JS2VAL(allocStringPtr(s)); }
js2val allocString(const char16 *s, uint32 length) { return STRING_TO_JS2VAL(allocStringPtr(s, length)); }
js2val allocString(const String *s, uint32 index, uint32 length) { return STRING_TO_JS2VAL(allocStringPtr(s, index, length)); }
String *allocStringPtr(const String *s);
String *allocStringPtr(const char *s);
String *allocStringPtr(const char16 *s, uint32 length);
String *allocStringPtr(const String *s, uint32 index, uint32 length);
String *concatStrings(const String *s1, const String *s2);

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

@ -108,7 +108,6 @@ js2val Error_toString(JS2Metadata *meta, const js2val thisValue, js2val *argv, u
{
js2val thatValue = thisValue;
js2val result;
LookupKind lookup(false, JS2VAL_NULL);
Multiname mn(&meta->world.identifiers["message"], meta->publicNamespace);
JS2Class *c = meta->objectType(thatValue);

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

@ -625,7 +625,7 @@ namespace MetaData {
}
bool defaultReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval)
bool defaultReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Environment *env, Phase phase, js2val *rval)
{
InstanceMember *mBase = meta->findBaseInstanceMember(limit, multiname, ReadAccess);
if (mBase)
@ -635,9 +635,10 @@ namespace MetaData {
Member *m = meta->findCommonMember(base, multiname, ReadAccess, false);
if (m == NULL) {
if (lookupKind->isPropertyLookup() && JS2VAL_IS_OBJECT(*base)
&& ( (JS2VAL_TO_OBJECT(*base)->kind == SimpleInstanceKind) && !checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(*base))->sealed)
|| ( (JS2VAL_TO_OBJECT(*base)->kind == PackageKind) && !checked_cast<Package *>(JS2VAL_TO_OBJECT(*base))->sealed) ) {
if ((env == NULL)
&& JS2VAL_IS_OBJECT(*base)
&& (( (JS2VAL_TO_OBJECT(*base)->kind == SimpleInstanceKind) && !checked_cast<SimpleInstance *>(JS2VAL_TO_OBJECT(*base))->sealed)
|| ( (JS2VAL_TO_OBJECT(*base)->kind == PackageKind) && !checked_cast<Package *>(JS2VAL_TO_OBJECT(*base))->sealed) ) ) {
if (phase == CompilePhase)
meta->reportError(Exception::compileExpressionError, "Inappropriate compile time expression", meta->engine->errorPos());
else {
@ -661,14 +662,12 @@ namespace MetaData {
case Member::InstanceMethodMember:
case Member::InstanceGetterMember:
case Member::InstanceSetterMember:
if ( (JS2VAL_IS_OBJECT(*base) && (JS2VAL_TO_OBJECT(*base)->kind != ClassKind))
|| lookupKind->isPropertyLookup())
meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos());
if (JS2VAL_IS_VOID(lookupKind->thisObject))
meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos());
if (JS2VAL_IS_UNINITIALIZED(lookupKind->thisObject))
meta->reportError(Exception::compileExpressionError, "Inappropriate compile time expression", meta->engine->errorPos());
return meta->readInstanceMember(lookupKind->thisObject, meta->objectType(lookupKind->thisObject), checked_cast<InstanceMember *>(m), phase, rval);
{
if (!JS2VAL_IS_OBJECT(*base) || (JS2VAL_TO_OBJECT(*base)->kind != ClassKind) || (env == NULL))
meta->reportError(Exception::referenceError, "Can't read an instance member without supplying an instance", meta->engine->errorPos());
js2val thisVal = env->readImplicitThis(meta);
return meta->readInstanceMember(thisVal, meta->objectType(thisVal), checked_cast<InstanceMember *>(m), phase, rval);
}
default:
NOT_REACHED("bad member kind");
return false;
@ -679,44 +678,44 @@ namespace MetaData {
{
// XXX could speed up by pushing knowledge of single namespace?
DEFINE_ROOTKEEPER(rk1, name);
LookupKind lookup(false, JS2VAL_NULL);
Multiname *mn = new Multiname(name, meta->publicNamespace);
DEFINE_ROOTKEEPER(rk, mn);
return defaultReadProperty(meta, base, limit, mn, &lookup, phase, rval);
return defaultReadProperty(meta, base, limit, mn, NULL, phase, rval);
}
bool defaultDeletePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result)
{
DEFINE_ROOTKEEPER(rk1, name);
// XXX could speed up by pushing knowledge of single namespace & lookup?
LookupKind lookup(false, JS2VAL_NULL);
// XXX could speed up by pushing knowledge of single namespace?
Multiname *mn = new Multiname(name, meta->publicNamespace);
DEFINE_ROOTKEEPER(rk, mn);
return defaultDeleteProperty(meta, base, limit, mn, &lookup, result);
return defaultDeleteProperty(meta, base, limit, mn, NULL, result);
}
bool defaultWritePublicProperty(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue)
{
DEFINE_ROOTKEEPER(rk1, name);
// XXX could speed up by pushing knowledge of single namespace?
LookupKind lookup(false, JS2VAL_NULL);
Multiname *mn = new Multiname(name, meta->publicNamespace);
DEFINE_ROOTKEEPER(rk, mn);
return defaultWriteProperty(meta, base, limit, mn, &lookup, createIfMissing, newValue, false);
return defaultWriteProperty(meta, base, limit, mn, NULL, createIfMissing, newValue, false);
}
bool defaultBracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Phase phase, js2val *rval)
bool defaultBracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval)
{
LookupKind lookup(false, JS2VAL_NULL);
return limit->read(meta, base, limit, multiname, &lookup, phase, rval);
const String *indexStr = meta->toString(indexVal);
DEFINE_ROOTKEEPER(rk, indexStr);
Multiname *mn = new Multiname(indexStr, meta->publicNamespace);
DEFINE_ROOTKEEPER(rk1, mn);
return limit->read(meta, base, limit, mn, NULL, phase, rval);
}
bool arrayWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag)
bool arrayClass_WriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag)
{
ASSERT(JS2VAL_IS_OBJECT(base));
JS2Object *obj = JS2VAL_TO_OBJECT(base);
bool result = defaultWriteProperty(meta, base, limit, multiname, lookupKind, createIfMissing, newValue, false);
bool result = defaultWriteProperty(meta, base, limit, multiname, env, createIfMissing, newValue, false);
if (result && (multiname->nsList->size() == 1) && (multiname->nsList->back() == meta->publicNamespace)) {
const char16 *numEnd;
float64 f = stringToDouble(multiname->name->data(), multiname->name->data() + multiname->name->length(), numEnd);
@ -735,17 +734,16 @@ namespace MetaData {
return result;
}
bool arrayWritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue)
bool arrayClass_WritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue)
{
DEFINE_ROOTKEEPER(rk1, name);
// XXX could speed up by pushing knowledge of single namespace?
LookupKind lookup(false, JS2VAL_NULL);
Multiname *mn = new Multiname(name, meta->publicNamespace);
DEFINE_ROOTKEEPER(rk, mn);
return arrayWriteProperty(meta, base, limit, mn, &lookup, createIfMissing, newValue, false);
return arrayClass_WriteProperty(meta, base, limit, mn, meta->env, createIfMissing, newValue, false);
}
bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag)
bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag)
{
InstanceMember *mBase = meta->findBaseInstanceMember(limit, multiname, WriteAccess);
if (mBase) {
@ -794,26 +792,29 @@ namespace MetaData {
case Member::InstanceMethodMember:
case Member::InstanceGetterMember:
case Member::InstanceSetterMember:
if ( (JS2VAL_IS_OBJECT(base) && (JS2VAL_TO_OBJECT(base)->kind != ClassKind))
|| lookupKind->isPropertyLookup())
meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos());
if (JS2VAL_IS_VOID(lookupKind->thisObject))
meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos());
meta->writeInstanceMember(lookupKind->thisObject, meta->objectType(lookupKind->thisObject), checked_cast<InstanceMember *>(m), newValue);
return true;
{
if ( !JS2VAL_IS_OBJECT(base) || (JS2VAL_TO_OBJECT(base)->kind != ClassKind) || (env == NULL))
meta->reportError(Exception::referenceError, "Can't write an instance member withoutsupplying an instance", meta->engine->errorPos());
js2val thisVal = env->readImplicitThis(meta);
meta->writeInstanceMember(thisVal, meta->objectType(thisVal), checked_cast<InstanceMember *>(m), newValue);
return true;
}
default:
NOT_REACHED("bad member kind");
return false;
}
}
bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, js2val newValue)
bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, js2val newValue)
{
LookupKind lookup(false, JS2VAL_NULL);
return limit->write(meta, base, limit, multiname, &lookup, true, newValue, false);
const String *indexStr = meta->toString(indexVal);
DEFINE_ROOTKEEPER(rk, indexStr);
Multiname *mn = new Multiname(indexStr, meta->publicNamespace);
DEFINE_ROOTKEEPER(rk1, mn);
return limit->write(meta, base, limit, mn, NULL, true, newValue, false);
}
bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool *result)
bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool *result)
{
InstanceMember *mBase = meta->findBaseInstanceMember(limit, multiname, WriteAccess);
if (mBase) {
@ -882,12 +883,11 @@ VariableMemberCommon:
case Member::InstanceMethodMember:
case Member::InstanceGetterMember:
case Member::InstanceSetterMember:
if ( (JS2VAL_IS_OBJECT(base) && (JS2VAL_TO_OBJECT(base)->kind != ClassKind)) || lookupKind->isPropertyLookup()) {
if ( (!JS2VAL_IS_OBJECT(base) || (JS2VAL_TO_OBJECT(base)->kind != ClassKind)) || (env == NULL)) {
*result = false;
return true;
}
if (JS2VAL_IS_VOID(lookupKind->thisObject))
meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos());
env->readImplicitThis(meta);
*result = false;
return true;
default:
@ -896,10 +896,13 @@ VariableMemberCommon:
}
}
bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, bool *result)
bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, bool *result)
{
LookupKind lookup(false, JS2VAL_NULL);
return limit->deleteProperty(meta, base, limit, multiname, &lookup, result);
const String *indexStr = meta->toString(indexVal);
DEFINE_ROOTKEEPER(rk, indexStr);
Multiname *mn = new Multiname(indexStr, meta->publicNamespace);
DEFINE_ROOTKEEPER(rk1, mn);
return limit->deleteProperty(meta, base, limit, mn, NULL, result);
}
js2val defaultImplicitCoerce(JS2Metadata *meta, js2val newValue, JS2Class *isClass)
@ -943,6 +946,32 @@ VariableMemberCommon:
return BOOLEAN_TO_JS2VAL(result);
}
bool stringClass_BracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval)
{
if (JS2VAL_IS_INT(indexVal)) {
const String *str = NULL;
if (JS2VAL_IS_STRING(*base)) {
str = JS2VAL_TO_STRING(*base);
}
else {
ASSERT(JS2VAL_IS_OBJECT(*base));
JS2Object *obj = JS2VAL_TO_OBJECT(*base);
ASSERT((obj->kind == SimpleInstanceKind) && (checked_cast<SimpleInstance *>(obj)->type == meta->stringClass));
StringInstance *a = checked_cast<StringInstance *>(obj);
str = a->mValue;
}
int32 i = JS2VAL_TO_INT(indexVal);
if ((i >= 0) && (i < str->length()))
*rval = meta->engine->allocString(&(*str)[i], 1);
else
*rval = JS2VAL_UNDEFINED;
return true;
}
else
return defaultBracketRead(meta, base, limit, indexVal, phase, rval);
}
}; // namespace MetaData
}; // namespace Javascript

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

@ -2813,6 +2813,20 @@ doUnary:
return false;
}
js2val Environment::readImplicitThis(JS2Metadata *meta)
{
ParameterFrame *pFrame = getEnclosingParameterFrame();
if (pFrame == NULL)
meta->reportError(Exception::referenceError, "Can't access instance members outside an instance method without supplying an instance object", meta->engine->errorPos());
js2val thisVal = pFrame->thisObject;
if ((!JS2VAL_IS_OBJECT(thisVal) || JS2VAL_IS_NULL(thisVal)) || !pFrame->isInstance || !pFrame->isConstructor)
meta->reportError(Exception::referenceError, "Can't access instance members inside a non-instance method without supplying an instance object", meta->engine->errorPos());
if (!pFrame->superConstructorCalled)
meta->reportError(Exception::uninitializedError, "Can't access instance members from within a constructor before the superconstructor has been called", meta->engine->errorPos());
return thisVal;
}
// Read the value of a lexical reference - it's an error if that reference
// doesn't have a binding somewhere.
// Attempt the read in each frame in the current environment, stopping at the
@ -2822,7 +2836,6 @@ doUnary:
{
js2val a = JS2VAL_VOID;
findThis(meta, false, &a);
LookupKind lookup(true, a);
FrameListIterator fi = getBegin();
bool result = false;
while (fi != getEnd()) {
@ -2832,7 +2845,7 @@ doUnary:
{
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi));
js2val frame = OBJECT_TO_JS2VAL(*fi);
result = limit->read(meta, &frame, limit, multiname, &lookup, phase, rval);
result = limit->read(meta, &frame, limit, multiname, this, phase, rval);
}
break;
case SystemKind:
@ -2850,7 +2863,7 @@ doUnary:
// XXX uninitialized 'with' object?
js2val withVal = OBJECT_TO_JS2VAL(wf->obj);
JS2Class *limit = meta->objectType(withVal);
result = limit->read(meta, &withVal, limit, multiname, &lookup, phase, rval);
result = limit->read(meta, &withVal, limit, multiname, this, phase, rval);
if (result && base)
*base = withVal;
}
@ -2869,7 +2882,6 @@ doUnary:
{
js2val a = JS2VAL_VOID;
findThis(meta, false, &a);
LookupKind lookup(true, a);
FrameListIterator fi = getBegin();
bool result = false;
while (fi != getEnd()) {
@ -2878,7 +2890,7 @@ doUnary:
case PackageKind:
{
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi));
result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, &lookup, false, newValue, false);
result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, this, false, newValue, false);
}
break;
case SystemKind:
@ -2897,7 +2909,7 @@ doUnary:
WithFrame *wf = checked_cast<WithFrame *>(*fi);
// XXX uninitialized 'with' object?
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(wf->obj));
result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, &lookup, false, newValue, false);
result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, this, false, newValue, false);
}
break;
}
@ -2908,7 +2920,7 @@ doUnary:
if (createIfMissing) {
Package *pkg = getPackageFrame();
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(pkg));
result = limit->write(meta, OBJECT_TO_JS2VAL(pkg), limit, multiname, &lookup, true, newValue, false);
result = limit->write(meta, OBJECT_TO_JS2VAL(pkg), limit, multiname, this, true, newValue, false);
if (result)
return;
}
@ -2923,7 +2935,6 @@ doUnary:
{
js2val a = JS2VAL_VOID;
findThis(meta, false, &a);
LookupKind lookup(true, a);
FrameListIterator fi = getBegin();
bool result = false;
while (fi != getEnd()) {
@ -2932,7 +2943,7 @@ doUnary:
case PackageKind:
{
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi));
result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, &lookup, false, newValue, true);
result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, this, false, newValue, true);
}
break;
case SystemKind:
@ -2951,7 +2962,7 @@ doUnary:
WithFrame *wf = checked_cast<WithFrame *>(*fi);
// XXX uninitialized 'with' object?
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(wf->obj));
result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, &lookup, false, newValue, true);
result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, this, false, newValue, true);
}
break;
}
@ -2963,7 +2974,7 @@ doUnary:
ASSERT(false);
Package *pkg = getPackageFrame();
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(pkg));
result = limit->write(meta, OBJECT_TO_JS2VAL(pkg), limit, multiname, &lookup, true, newValue, true);
result = limit->write(meta, OBJECT_TO_JS2VAL(pkg), limit, multiname, this, true, newValue, true);
if (result)
return;
}
@ -2974,7 +2985,6 @@ doUnary:
{
js2val a = JS2VAL_VOID;
findThis(meta, false, &a);
LookupKind lookup(true, a);
FrameListIterator fi = getBegin();
bool result = false;
while (fi != getEnd()) {
@ -2983,7 +2993,7 @@ doUnary:
case PackageKind:
{
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi));
if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, &lookup, &result))
if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, this, &result))
return result;
}
break;
@ -3001,7 +3011,7 @@ doUnary:
WithFrame *wf = checked_cast<WithFrame *>(*fi);
// XXX uninitialized 'with' object?
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(wf->obj));
if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, &lookup, &result))
if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, this, &result))
return result;
}
break;
@ -3773,16 +3783,16 @@ static const uint8 urlCharType[256] =
return thisValue;
}
bool nullClass_ReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval) { return false; }
bool nullClass_ReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Environment *env, Phase phase, js2val *rval) { return false; }
bool nullClass_ReadPublicProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, const String *name, Phase phase, js2val *rval) { return false; }
bool nullClass_BracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Phase phase, js2val *rval) { return false; }
bool nullClass_arrayWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue) { return false; }
bool nullClass_WriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag) { return false; }
bool nullClass_BracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval) { return false; }
bool nullClass_arrayWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue) { return false; }
bool nullClass_WriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag) { return false; }
bool nullClass_WritePublicProperty(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue) { return false; }
bool nullClass_BracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, js2val newValue) { return false; }
bool nullClass_DeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool *result) { return false; }
bool nullClass_BracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, js2val newValue) { return false; }
bool nullClass_DeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool *result) { return false; }
bool nullClass_DeletePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result) { return false; }
bool nullClass_BracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, bool *result) { return false; }
bool nullClass_BracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, bool *result) { return false; }
#define MAKEBUILTINCLASS(c, super, dynamic, final, name, defaultVal) c = new JS2Class(super, NULL, new Namespace(engine->private_StringAtom), dynamic, final, name); c->complete = true; c->defaultValue = defaultVal;
@ -3823,6 +3833,8 @@ bool nullClass_BracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, Mu
integerClass->is = integerIs;
MAKEBUILTINCLASS(characterClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["Character"]), JS2VAL_ZERO);
MAKEBUILTINCLASS(stringClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["String"]), JS2VAL_NULL);
stringClass->bracketRead = stringClass_BracketRead;
MAKEBUILTINCLASS(namespaceClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["namespace"]), JS2VAL_NULL);
MAKEBUILTINCLASS(attributeClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["attribute"]), JS2VAL_NULL);
MAKEBUILTINCLASS(classClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["Class"]), JS2VAL_NULL);
@ -3955,8 +3967,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
/*** ECMA 3 Array Class ***/
MAKEBUILTINCLASS(arrayClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["Array"]), JS2VAL_NULL);
arrayClass->write = arrayWriteProperty;
arrayClass->writePublic = arrayWritePublic;
arrayClass->write = arrayClass_WriteProperty;
arrayClass->writePublic = arrayClass_WritePublic;
v = new Variable(classClass, OBJECT_TO_JS2VAL(arrayClass), true);
defineLocalMember(env, &world.identifiers["Array"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
initArrayObject(this);
@ -4852,10 +4864,11 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
JS2Object *result = this;
DEFINE_ROOTKEEPER(rk1, result);
JS2Object *obj = new SimpleInstance(meta, meta->objectClass->prototype, meta->objectClass);
DEFINE_ROOTKEEPER(rk2, obj);
JS2Object *protoObj = new SimpleInstance(meta, meta->objectClass->prototype, meta->objectClass);
DEFINE_ROOTKEEPER(rk2, protoObj);
meta->createDynamicProperty(this, meta->engine->prototype_StringAtom, OBJECT_TO_JS2VAL(obj), ReadWriteAccess, true, false);
meta->createDynamicProperty(this, meta->engine->prototype_StringAtom, OBJECT_TO_JS2VAL(protoObj), ReadWriteAccess, true, false);
meta->createDynamicProperty(protoObj, &meta->world.identifiers["constructor"], OBJECT_TO_JS2VAL(this), ReadWriteAccess, true, false);
}
@ -5106,28 +5119,15 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
************************************************************************************/
Pond JS2Object::pond(POND_SIZE, NULL);
#ifdef DEBUG
std::list<RootKeeper *> JS2Object::rootList;
#else
std::list<PondScum **> JS2Object::rootList;
#endif
// Add a pointer to the (address of a) gc-allocated object to the root list
// (Note - we hand out an iterator, so it's essential to
// use something like std::list that doesn't mess with locations)
#ifdef DEBUG
JS2Object::RootIterator JS2Object::addRoot(RootKeeper *t)
{
return rootList.insert(rootList.end(), t);
}
#else
JS2Object::RootIterator JS2Object::addRoot(void *t)
{
PondScum **p = (PondScum **)t;
ASSERT(p);
return rootList.insert(rootList.end(), p);
}
#endif
// Remove a root pointer
void JS2Object::removeRoot(RootIterator ri)
@ -5152,22 +5152,20 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
PondScum *scum = NULL;
if (r->is_js2val) {
js2val *valp = (js2val *)(r->p);
if (JS2VAL_IS_OBJECT(*valp))
scum = ((PondScum *)(JS2VAL_TO_OBJECT(*valp))) - 1;
markJS2Value(*valp);
}
else {
JS2Object *objp = (JS2Object *)(r->p);
if (objp)
scum = ((PondScum *)objp - 1);
}
if (scum) {
ASSERT(scum->owner && (scum->getSize() >= sizeof(PondScum)) && (scum->owner->sanity == POND_SANITY));
if (scum->isJS2Object()) {
JS2Object *obj = (JS2Object *)(scum + 1);
GCMARKOBJECT(obj)
JS2Object **objp = (JS2Object **)(r->p);
if (*objp) {
scum = ((PondScum *)(*objp) - 1);
ASSERT(scum->owner && (scum->getSize() >= sizeof(PondScum)) && (scum->owner->sanity == POND_SANITY));
if (scum->isJS2Object()) {
JS2Object *obj = (JS2Object *)(scum + 1);
GCMARKOBJECT(obj)
}
else
mark(scum + 1);
}
else
mark(scum + 1);
}
}
return pond.moveUnmarkedToFreeList();

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

@ -56,7 +56,6 @@ class StringInstance;
class FunctionInstance;
class ArrayInstance;
class RegExpInstance;
class LookupKind;
class Package;
typedef void (Invokable)();
@ -64,35 +63,37 @@ 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 (Read)(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Environment *env, Phase phase, js2val *rval);
typedef bool (ReadPublic)(JS2Metadata *meta, js2val *base, JS2Class *limit, const String *name, Phase phase, js2val *rval);
typedef bool (Write)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag);
typedef bool (Write)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag);
typedef bool (WritePublic)(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue);
typedef bool (DeleteProperty)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool *result);
typedef bool (DeleteProperty)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool *result);
typedef bool (DeletePublic)(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result);
typedef bool (BracketRead)(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Phase phase, js2val *rval);
typedef bool (BracketWrite)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, js2val newValue);
typedef bool (BracketDelete)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, bool *result);
typedef bool (BracketRead)(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval);
typedef bool (BracketWrite)(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, js2val newValue);
typedef bool (BracketDelete)(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, bool *result);
typedef js2val (ImplicitCoerce)(JS2Metadata *meta, js2val newValue, JS2Class *toClass);
typedef js2val (Is)(JS2Metadata *meta, js2val newValue, JS2Class *isClass);
bool defaultReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
bool defaultReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Environment *env, Phase phase, js2val *rval);
bool defaultReadPublicProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, const String *name, Phase phase, js2val *rval);
bool defaultBracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Phase phase, js2val *rval);
bool arrayWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag);
bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag);
bool defaultBracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval);
bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag);
bool defaultWritePublicProperty(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue);
bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, js2val newValue);
bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool *result);
bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, js2val newValue);
bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool *result);
bool defaultDeletePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result);
bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, bool *result);
bool arrayWritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue);
bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, bool *result);
bool arrayClass_WriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag);
bool arrayClass_WritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue);
js2val defaultImplicitCoerce(JS2Metadata *meta, js2val newValue, JS2Class *isClass);
js2val defaultIs(JS2Metadata *meta, js2val newValue, JS2Class *isClass);
js2val integerImplicitCoerce(JS2Metadata *meta, js2val newValue, JS2Class *isClass);
js2val integerIs(JS2Metadata *meta, js2val newValue, JS2Class *isClass);
bool stringClass_BracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval);
extern void initDateObject(JS2Metadata *meta);
extern void initStringObject(JS2Metadata *meta);
@ -253,10 +254,16 @@ public:
static void markJS2Value(js2val v);
};
#ifdef DEBUG
#define ROOTKEEPER_CONSTRUCTOR(type) RootKeeper(type **p, int line, char *pfile) : is_js2val(false), p(p) { init(line, pfile); }
#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj, __LINE__, __FILE__);
#else
#define ROOTKEEPER_CONSTRUCTOR(type) RootKeeper(type **p) : is_js2val(false), p(p) { ri = JS2Object::addRoot(this); }
#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj);
#endif
class RootKeeper {
public:
#ifdef DEBUG
ROOTKEEPER_CONSTRUCTOR(JS2Object)
ROOTKEEPER_CONSTRUCTOR(RegExpInstance)
@ -274,22 +281,18 @@ public:
ROOTKEEPER_CONSTRUCTOR(FunctionInstance)
ROOTKEEPER_CONSTRUCTOR(DateInstance)
RootKeeper(js2val *p, int line, char *pfile) : is_js2val(true), p(p)
{
init(line, pfile);
}
#ifdef DEBUG
RootKeeper(js2val *p, int line, char *pfile) : is_js2val(true), p(p) { init(line, pfile); }
~RootKeeper() { JS2Object::removeRoot(ri); delete file; }
void RootKeeper::init(int line, char *pfile)
void RootKeeper::init(int ln, char *pfile)
{
line = line;
line = ln;
file = new char[strlen(pfile) + 1];
strcpy(file, pfile);
ri = JS2Object::addRoot(this);
}
#else
RootKeeper(JS2Object **p) : is_js2val(false), p(p), { ri = JS2Object::addRoot(p); }
RootKeeper(js2val *p) : is_js2val(true), p(p) { ri = JS2Object::addRoot(p); }
RootKeeper(js2val *p) : is_js2val(true), p(p) { ri = JS2Object::addRoot(this); }
~RootKeeper() { JS2Object::removeRoot(ri); }
#endif
@ -303,11 +306,6 @@ public:
#endif
};
#ifdef DEBUG
#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj, __LINE__, __FILE__);
#else
#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj);
#endif
class Attribute : public JS2Object {
public:
@ -740,6 +738,7 @@ public:
void removeTopFrame() { frameList.pop_front(); }
bool findThis(JS2Metadata *meta, bool allowPrototypeThis, js2val *result);
js2val readImplicitThis(JS2Metadata *meta);
void lexicalRead(JS2Metadata *meta, Multiname *multiname, Phase phase, js2val *rval, js2val *base);
void lexicalWrite(JS2Metadata *meta, Multiname *multiname, js2val newValue, bool createIfMissing);
void lexicalInit(JS2Metadata *meta, Multiname *multiname, js2val newValue);
@ -1240,6 +1239,7 @@ public:
prototype(prototype),
buildArguments(false),
isConstructor(false),
isInstance(false),
callsSuperConstructor(false),
superConstructorCalled(true)
{ }
@ -1249,6 +1249,7 @@ public:
prototype(pluralFrame->prototype),
buildArguments(pluralFrame->buildArguments),
isConstructor(pluralFrame->isConstructor),
isInstance(pluralFrame->isInstance),
callsSuperConstructor(pluralFrame->callsSuperConstructor),
superConstructorCalled(false) // initialized to false for each construction of a singular frame
// and then set true when/if the call occurs
@ -1262,6 +1263,7 @@ public:
bool prototype; // true if this function is not an instance method but defines this anyway
bool buildArguments;
bool isConstructor;
bool isInstance;
bool callsSuperConstructor;
bool superConstructorCalled;
@ -1286,17 +1288,6 @@ public:
};
class LookupKind {
public:
LookupKind(bool isLexical, js2val thisObject) : isLexical(isLexical), thisObject(thisObject) { }
bool isPropertyLookup() { return !isLexical; }
bool isLexical; // if isLexical, use the 'this' below. Otherwise it's a propertyLookup
js2val thisObject;
};
typedef std::vector<Namespace *> NamespaceList;
typedef NamespaceList::iterator NamespaceListIterator;

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

@ -34,7 +34,6 @@
// Read a multiname property from a base object, push the value onto the stack
case eDotRead:
{
LookupKind lookup(false, JS2VAL_NULL);
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
b = pop();
@ -43,12 +42,12 @@
if (JS2VAL_IS_OBJECT(b) && (JS2VAL_TO_OBJECT(b)->kind == LimitedInstanceKind)) {
LimitedInstance *li = checked_cast<LimitedInstance *>(JS2VAL_TO_OBJECT(b));
b = OBJECT_TO_JS2VAL(li->instance);
if (!li->limit->read(meta, &b, li->limit, mn, &lookup, RunPhase, &a))
if (!li->limit->read(meta, &b, li->limit, mn, NULL, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
}
else {
JS2Class *limit = meta->objectType(b);
if (!limit->read(meta, &b, limit, mn, &lookup, RunPhase, &a))
if (!limit->read(meta, &b, limit, mn, NULL, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
}
push(a);
@ -57,13 +56,12 @@
case eDotDelete:
{
LookupKind lookup(false, JS2VAL_NULL);
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
b = pop();
bool result;
JS2Class *limit = meta->objectType(b);
if (!limit->deleteProperty(meta, b, limit, mn, &lookup, &result))
if (!limit->deleteProperty(meta, b, limit, mn, NULL, &result))
push(JS2VAL_FALSE);
else
push(BOOLEAN_TO_JS2VAL(result));
@ -75,7 +73,6 @@
case eDotWrite:
{
a = pop();
LookupKind lookup(false, JS2VAL_NULL);
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
b = pop();
@ -84,14 +81,14 @@
if (JS2VAL_IS_OBJECT(b) && (JS2VAL_TO_OBJECT(b)->kind == LimitedInstanceKind)) {
LimitedInstance *li = checked_cast<LimitedInstance *>(JS2VAL_TO_OBJECT(b));
b = OBJECT_TO_JS2VAL(li->instance);
if (!li->limit->write(meta, b, li->limit, mn, &lookup, true, a, false)) {
if (!li->limit->write(meta, b, li->limit, mn, NULL, true, a, false)) {
if (!meta->cxt.E3compatibility)
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
}
}
else {
JS2Class *limit = meta->objectType(b);
if (!limit->write(meta, b, limit, mn, &lookup, true, a, false)) {
if (!limit->write(meta, b, limit, mn, NULL, true, a, false)) {
if (!meta->cxt.E3compatibility)
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
}
@ -103,12 +100,11 @@
// Read the multiname property, but leave the base and the value on the stack
case eDotRef:
{
LookupKind lookup(false, JS2VAL_NULL);
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
b = pop();
JS2Class *limit = meta->objectType(b);
if (!limit->read(meta, &b, limit, mn, &lookup, RunPhase, &a))
if (!limit->read(meta, &b, limit, mn, NULL, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
push(b);
push(a);
@ -175,32 +171,25 @@
{
indexVal = pop();
b = pop();
astr = meta->toString(indexVal);
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
JS2Class *limit = meta->objectType(b);
if (!limit->bracketRead(meta, &b, limit, &mn, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
if (!limit->bracketRead(meta, &b, limit, indexVal, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
push(a);
indexVal = JS2VAL_VOID;
astr = NULL;
}
break;
case eBracketDelete:
{
LookupKind lookup(false, JS2VAL_NULL);
indexVal = pop();
b = pop();
astr = meta->toString(indexVal);
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
bool result;
JS2Class *limit = meta->objectType(b);
if (!limit->bracketDelete(meta, b, limit, &mn, &result))
if (!limit->bracketDelete(meta, b, limit, indexVal, &result))
push(JS2VAL_FALSE);
else
push(BOOLEAN_TO_JS2VAL(result));
indexVal = JS2VAL_VOID;
astr = NULL;
}
break;
@ -211,48 +200,40 @@
a = pop();
indexVal = pop();
b = pop();
astr = meta->toString(indexVal);
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
JS2Class *limit = meta->objectType(b);
if (!limit->bracketWrite(meta, b, limit, &mn, a)) {
if (!limit->bracketWrite(meta, b, limit, indexVal, a)) {
if (!meta->cxt.E3compatibility)
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
}
push(a);
indexVal = JS2VAL_VOID;
astr = NULL;
}
break;
// Leave the base object on the stack and push the property value
case eBracketRef:
{
LookupKind lookup(false, JS2VAL_NULL);
indexVal = pop();
b = top();
astr = meta->toString(indexVal);
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
JS2Class *limit = meta->objectType(b);
if (!limit->bracketRead(meta, &b, limit, &mn, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
if (!limit->bracketRead(meta, &b, limit, indexVal, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
push(a);
indexVal = JS2VAL_VOID;
astr = NULL;
}
break;
// Leave the base object and index value, push the value
case eBracketReadForRef:
{
LookupKind lookup(false, JS2VAL_NULL);
indexVal = pop();
b = top();
astr = meta->toString(indexVal);
push(STRING_TO_JS2VAL(astr));
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
indexVal = STRING_TO_JS2VAL(astr);
push(indexVal);
JS2Class *limit = meta->objectType(b);
if (!limit->bracketRead(meta, &b, limit, &mn, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
if (!limit->bracketRead(meta, &b, limit, indexVal, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), astr);
push(a);
indexVal = JS2VAL_VOID;
astr = NULL;
@ -262,16 +243,14 @@
// Beneath the value is a reference pair (base and index), write to that location but leave just the value
case eBracketWriteRef:
{
LookupKind lookup(false, JS2VAL_NULL);
a = pop();
indexVal = pop();
ASSERT(JS2VAL_IS_STRING(indexVal));
ASSERT(JS2VAL_IS_STRING(indexVal)); // because the readForRef above will have executed first
b = pop();
Multiname mn(&meta->world.identifiers[*JS2VAL_TO_STRING(indexVal)], meta->publicNamespace);
JS2Class *limit = meta->objectType(b);
if (!limit->bracketWrite(meta, b, limit, &mn, a)) {
if (!limit->bracketWrite(meta, b, limit, indexVal, a)) {
if (!meta->cxt.E3compatibility)
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), JS2VAL_TO_STRING(indexVal));
}
push(a);
indexVal = JS2VAL_VOID;

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

@ -964,15 +964,14 @@
case eDotPostInc:
{
LookupKind lookup(false, JS2VAL_NULL);
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
baseVal = pop();
JS2Class *limit = meta->objectType(baseVal);
if (!limit->read(meta, &baseVal, limit, mn, &lookup, RunPhase, &a))
if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
float64 num = meta->toFloat64(a);
if (!limit->write(meta, baseVal, limit, mn, &lookup, true, allocNumber(num + 1.0), false))
if (!limit->write(meta, baseVal, limit, mn, NULL, true, allocNumber(num + 1.0), false))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
pushNumber(num);
baseVal = JS2VAL_VOID;
@ -980,15 +979,14 @@
break;
case eDotPostDec:
{
LookupKind lookup(false, JS2VAL_NULL);
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
baseVal = pop();
JS2Class *limit = meta->objectType(baseVal);
if (!limit->read(meta, &baseVal, limit, mn, &lookup, RunPhase, &a))
if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
float64 num = meta->toFloat64(a);
if (!limit->write(meta, baseVal, limit, mn, &lookup, true, allocNumber(num - 1.0), false))
if (!limit->write(meta, baseVal, limit, mn, NULL, true, allocNumber(num - 1.0), false))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
pushNumber(num);
baseVal = JS2VAL_VOID;
@ -996,32 +994,30 @@
break;
case eDotPreInc:
{
LookupKind lookup(false, JS2VAL_NULL);
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
baseVal = pop();
JS2Class *limit = meta->objectType(baseVal);
if (!limit->read(meta, &baseVal, limit, mn, &lookup, RunPhase, &a))
if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
float64 num = meta->toFloat64(a);
a = pushNumber(num + 1.0);
if (!limit->write(meta, baseVal, limit, mn, &lookup, true, a, false))
if (!limit->write(meta, baseVal, limit, mn, NULL, true, a, false))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
baseVal = JS2VAL_VOID;
}
break;
case eDotPreDec:
{
LookupKind lookup(false, JS2VAL_NULL);
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
baseVal = pop();
JS2Class *limit = meta->objectType(baseVal);
if (!limit->read(meta, &baseVal, limit, mn, &lookup, RunPhase, &a))
if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
float64 num = meta->toFloat64(a);
a = pushNumber(num - 1.0);
if (!limit->write(meta, baseVal, limit, mn, &lookup, true, a, false))
if (!limit->write(meta, baseVal, limit, mn, NULL, true, a, false))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
baseVal = JS2VAL_VOID;
}
@ -1029,36 +1025,29 @@
case eBracketPostInc:
{
LookupKind lookup(false, JS2VAL_NULL);
indexVal = pop();
baseVal = pop();
astr = meta->toString(indexVal);
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
JS2Class *limit = meta->objectType(baseVal);
if (!limit->bracketRead(meta, &baseVal, limit, &mn, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
float64 num = meta->toFloat64(a);
if (!limit->bracketWrite(meta, baseVal, limit, &mn, allocNumber(num + 1.0)))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
if (!limit->bracketWrite(meta, baseVal, limit, indexVal, allocNumber(num + 1.0)))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
pushNumber(num);
baseVal = JS2VAL_VOID;
indexVal = JS2VAL_VOID;
astr = NULL;
}
break;
case eBracketPostDec:
{
LookupKind lookup(false, JS2VAL_NULL);
indexVal = pop();
baseVal = pop();
astr = meta->toString(indexVal);
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
JS2Class *limit = meta->objectType(baseVal);
if (!limit->bracketRead(meta, &baseVal, limit, &mn, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
float64 num = meta->toFloat64(a);
if (!limit->bracketWrite(meta, baseVal, limit, &mn, allocNumber(num - 1.0)))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
if (!limit->bracketWrite(meta, baseVal, limit, indexVal, allocNumber(num - 1.0)))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
pushNumber(num);
baseVal = JS2VAL_VOID;
indexVal = JS2VAL_VOID;
@ -1067,18 +1056,15 @@
break;
case eBracketPreInc:
{
LookupKind lookup(false, JS2VAL_NULL);
indexVal = pop();
baseVal = pop();
astr = meta->toString(indexVal);
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
JS2Class *limit = meta->objectType(baseVal);
if (!limit->bracketRead(meta, &baseVal, limit, &mn, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
float64 num = meta->toFloat64(a);
a = pushNumber(num + 1.0);
if (!limit->bracketWrite(meta, baseVal, limit, &mn, a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
if (!limit->bracketWrite(meta, baseVal, limit, indexVal, a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
baseVal = JS2VAL_VOID;
indexVal = JS2VAL_VOID;
astr = NULL;
@ -1086,18 +1072,15 @@
break;
case eBracketPreDec:
{
LookupKind lookup(false, JS2VAL_NULL);
indexVal = pop();
baseVal = pop();
astr = meta->toString(indexVal);
Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace);
JS2Class *limit = meta->objectType(baseVal);
if (!limit->bracketRead(meta, &baseVal, limit, &mn, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
float64 num = meta->toFloat64(a);
a = pushNumber(num - 1.0);
if (!limit->bracketWrite(meta, baseVal, limit, &mn, a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name);
if (!limit->bracketWrite(meta, baseVal, limit, indexVal, a))
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
baseVal = JS2VAL_VOID;
indexVal = JS2VAL_VOID;
astr = NULL;

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

@ -65,11 +65,8 @@
// stack is out of balance anyway...
js2val protoVal = OBJECT_TO_JS2VAL(meta->objectClass->prototype);
Multiname mn(prototype_StringAtom); // gc safe because the content is rooted elsewhere
LookupKind lookup(true, JS2VAL_NULL); // make it a lexical lookup since we want it to
// fail if 'prototype' hasn't been defined
// XXX (prototype should always exist for functions)
JS2Class *limit = meta->objectType(a);
if (limit->read(meta, &a, limit, &mn, &lookup, RunPhase, &protoVal)) {
if (limit->read(meta, &a, limit, &mn, meta->env, RunPhase, &protoVal)) {
if (!JS2VAL_IS_OBJECT(protoVal))
meta->reportError(Exception::badValueError, "Non-object prototype value", errorPos());
}
@ -291,11 +288,8 @@
js2val b_protoVal;
Multiname mn(prototype_StringAtom); // gc safe because the content is rooted elsewhere
LookupKind lookup(true, JS2VAL_NULL); // make it a lexical lookup since we want it to
// fail if 'prototype' hasn't been defined
// XXX (prototype should always exist for functions)
JS2Class *limit = meta->objectType(b);
if (limit->read(meta, &b, limit, &mn, &lookup, RunPhase, &b_protoVal)) {
if (limit->read(meta, &b, limit, &mn, meta->env, RunPhase, &b_protoVal)) {
if (!JS2VAL_IS_OBJECT(b_protoVal))
meta->reportError(Exception::typeError, "Non-object prototype value in instanceOf", errorPos());
}

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

@ -41,14 +41,8 @@
*/
typedef uint32 jsint;
typedef char16 jschar;
typedef bool JSBool;
typedef uint32 uintN;
typedef int32 intN;
typedef uint8 jsbytecode;
typedef char16 JSString;
typedef char16 JSSubString;
typedef struct RECharSet {

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

@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\js\src" /I "../../RegExp" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "XP_PC" /D "EPIMETHEUS" /D "IS_LITTLE_ENDIAN" /FR /YX /FD /c
# ADD CPP /nologo /W3 /GX /Zi /O2 /I "..\..\..\js\src" /I "../../RegExp" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "XP_PC" /D "EPIMETHEUS" /D "IS_LITTLE_ENDIAN" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@ -50,7 +50,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\..\js\src\release"
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /libpath:"..\..\..\..\js\src\release"
!ELSEIF "$(CFG)" == "Epimetheus - Win32 Debug"