mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-19 09:30:44 +00:00
Moevd access dispatch to classes, fixed E3 bugs
This commit is contained in:
parent
5cee333241
commit
3134aa4bd3
@ -62,7 +62,7 @@ uint32 getLength(JS2Metadata *meta, JS2Object *obj)
|
||||
js2val result;
|
||||
JS2Class *c = meta->objectType(obj);
|
||||
js2val val = OBJECT_TO_JS2VAL(obj);
|
||||
if (c->readPublic(meta, &val, c, meta->engine->length_StringAtom, RunPhase, &result))
|
||||
if (c->ReadPublic(meta, &val, meta->engine->length_StringAtom, RunPhase, &result))
|
||||
length = toUInt32(meta->toInteger(result));
|
||||
return length;
|
||||
}
|
||||
@ -79,16 +79,16 @@ js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 newLength)
|
||||
bool deleteResult;
|
||||
JS2Class *c = meta->objectType(obj);
|
||||
for (uint32 i = newLength; i < length; i++) {
|
||||
c->deletePublic(meta, OBJECT_TO_JS2VAL(obj), c, meta->engine->numberToString(i), &deleteResult);
|
||||
c->DeletePublic(meta, OBJECT_TO_JS2VAL(obj), meta->engine->numberToString(i), &deleteResult);
|
||||
}
|
||||
}
|
||||
Multiname *mn = new Multiname(meta->engine->length_StringAtom, meta->publicNamespace);
|
||||
DEFINE_ROOTKEEPER(rk, mn);
|
||||
defaultWriteProperty(meta, OBJECT_TO_JS2VAL(obj), meta->arrayClass, mn, meta->env, true, result, false);
|
||||
meta->arrayClass->Write(meta, OBJECT_TO_JS2VAL(obj), mn, meta->env, true, result, false);
|
||||
}
|
||||
else {
|
||||
JS2Class *c = meta->objectType(obj);
|
||||
c->writePublic(meta, OBJECT_TO_JS2VAL(obj), c, meta->engine->length_StringAtom, true, result);
|
||||
c->WritePublic(meta, OBJECT_TO_JS2VAL(obj), meta->engine->length_StringAtom, true, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -142,7 +142,7 @@ static js2val Array_toString(JS2Metadata *meta, const js2val thisValue, js2val *
|
||||
js2val result;
|
||||
String *s = new String();
|
||||
for (uint32 i = 0; i < length; i++) {
|
||||
if (meta->arrayClass->readPublic(meta, &thatValue, meta->arrayClass, meta->engine->numberToString(i), RunPhase, &result)
|
||||
if (meta->arrayClass->ReadPublic(meta, &thatValue, meta->engine->numberToString(i), RunPhase, &result)
|
||||
&& !JS2VAL_IS_UNDEFINED(result)
|
||||
&& !JS2VAL_IS_NULL(result) )
|
||||
s->append(*meta->toString(result));
|
||||
@ -173,7 +173,7 @@ static js2val Array_toSource(JS2Metadata *meta, const js2val thisValue, js2val *
|
||||
js2val result;
|
||||
String *s = new String(widenCString("["));
|
||||
for (uint32 i = 0; i < length; i++) {
|
||||
if (meta->arrayClass->readPublic(meta, &thatValue, meta->arrayClass, meta->engine->numberToString(i), RunPhase, &result)
|
||||
if (meta->arrayClass->ReadPublic(meta, &thatValue, meta->engine->numberToString(i), RunPhase, &result)
|
||||
&& !JS2VAL_IS_UNDEFINED(result))
|
||||
s->append(*meta->toString(result));
|
||||
if (i < (length - 1))
|
||||
@ -195,7 +195,7 @@ static js2val Array_push(JS2Metadata *meta, const js2val thisValue, js2val *argv
|
||||
|
||||
JS2Class *c = meta->objectType(thisObj);
|
||||
for (uint32 i = 0; i < argc; i++) {
|
||||
c->writePublic(meta, thisValue, c, meta->engine->numberToString(i + length), true, argv[i]);
|
||||
c->WritePublic(meta, thisValue, meta->engine->numberToString(i + length), true, argv[i]);
|
||||
}
|
||||
return setLength(meta, thisObj, length + argc);
|
||||
}
|
||||
@ -211,8 +211,8 @@ static js2val Array_pop(JS2Metadata *meta, const js2val thisValue, js2val * /*ar
|
||||
js2val result = JS2VAL_UNDEFINED;
|
||||
bool deleteResult;
|
||||
JS2Class *c = meta->objectType(thisObj);
|
||||
c->readPublic(meta, &thatValue, c, meta->engine->numberToString(length - 1), RunPhase, &result);
|
||||
c->deletePublic(meta, thatValue, c, meta->engine->numberToString(length - 1), &deleteResult);
|
||||
c->ReadPublic(meta, &thatValue, meta->engine->numberToString(length - 1), RunPhase, &result);
|
||||
c->DeletePublic(meta, thatValue, meta->engine->numberToString(length - 1), &deleteResult);
|
||||
setLength(meta, thisObj, length - 1);
|
||||
return result;
|
||||
}
|
||||
@ -232,7 +232,7 @@ js2val Array_concat(JS2Metadata *meta, const js2val thisValue, js2val *argv, uin
|
||||
|
||||
do {
|
||||
if (meta->objectType(E) != meta->arrayClass) {
|
||||
meta->arrayClass->writePublic(meta, result, meta->arrayClass, meta->engine->numberToString(n++), true, E);
|
||||
meta->arrayClass->WritePublic(meta, result, meta->engine->numberToString(n++), true, E);
|
||||
}
|
||||
else {
|
||||
ASSERT(JS2VAL_IS_OBJECT(thisValue));
|
||||
@ -241,8 +241,8 @@ js2val Array_concat(JS2Metadata *meta, const js2val thisValue, js2val *argv, uin
|
||||
JS2Class *c = meta->objectType(arrObj);
|
||||
for (uint32 k = 0; k < length; k++) {
|
||||
js2val rval = JS2VAL_UNDEFINED;
|
||||
c->readPublic(meta, &E, c, meta->engine->numberToString(k), RunPhase, &rval);
|
||||
meta->arrayClass->writePublic(meta, result, meta->arrayClass, meta->engine->numberToString(n++), true, rval);
|
||||
c->ReadPublic(meta, &E, meta->engine->numberToString(k), RunPhase, &rval);
|
||||
meta->arrayClass->WritePublic(meta, result, meta->engine->numberToString(n++), true, rval);
|
||||
}
|
||||
}
|
||||
E = argv[i++];
|
||||
@ -270,7 +270,7 @@ static js2val Array_join(JS2Metadata *meta, const js2val thisValue, js2val *argv
|
||||
|
||||
for (uint32 k = 0; k < length; k++) {
|
||||
js2val result = JS2VAL_UNDEFINED;
|
||||
c->readPublic(meta, &thatValue, c, meta->engine->numberToString(k), RunPhase, &result);
|
||||
c->ReadPublic(meta, &thatValue, meta->engine->numberToString(k), RunPhase, &result);
|
||||
if (!JS2VAL_IS_UNDEFINED(result) && !JS2VAL_IS_NULL(result))
|
||||
*S += *meta->toString(result);
|
||||
|
||||
@ -306,26 +306,26 @@ static js2val Array_reverse(JS2Metadata *meta, const js2val thisValue, js2val *
|
||||
|
||||
if (meta->hasOwnProperty(thisObj, mn1->name)) {
|
||||
if (meta->hasOwnProperty(thisObj, mn2->name)) {
|
||||
c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &result1);
|
||||
c->readPublic(meta, &thatValue, c, mn2->name, RunPhase, &result2);
|
||||
c->writePublic(meta, thatValue, c, mn1->name, true, result2);
|
||||
c->writePublic(meta, thatValue, c, mn2->name, true, result1);
|
||||
c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &result1);
|
||||
c->ReadPublic(meta, &thatValue, mn2->name, RunPhase, &result2);
|
||||
c->WritePublic(meta, thatValue, mn1->name, true, result2);
|
||||
c->WritePublic(meta, thatValue, mn2->name, true, result1);
|
||||
}
|
||||
else {
|
||||
c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &result1);
|
||||
c->writePublic(meta, thatValue, c, mn2->name, true, result1);
|
||||
c->deletePublic(meta, thatValue, c, mn1->name, &deleteResult);
|
||||
c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &result1);
|
||||
c->WritePublic(meta, thatValue, mn2->name, true, result1);
|
||||
c->DeletePublic(meta, thatValue, mn1->name, &deleteResult);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (meta->hasOwnProperty(thisObj, mn2->name)) {
|
||||
c->readPublic(meta, &thatValue, c, mn2->name, RunPhase, &result2);
|
||||
c->writePublic(meta, thatValue, c, mn1->name, true, result2);
|
||||
c->deletePublic(meta, thatValue, c, mn2->name, &deleteResult);
|
||||
c->ReadPublic(meta, &thatValue, mn2->name, RunPhase, &result2);
|
||||
c->WritePublic(meta, thatValue, mn1->name, true, result2);
|
||||
c->DeletePublic(meta, thatValue, mn2->name, &deleteResult);
|
||||
}
|
||||
else {
|
||||
c->deletePublic(meta, thatValue, c, mn1->name, &deleteResult);
|
||||
c->deletePublic(meta, thatValue, c, mn2->name, &deleteResult);
|
||||
c->DeletePublic(meta, thatValue, mn1->name, &deleteResult);
|
||||
c->DeletePublic(meta, thatValue, mn2->name, &deleteResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -355,22 +355,22 @@ static js2val Array_shift(JS2Metadata *meta, const js2val thisValue, js2val * /*
|
||||
js2val result;
|
||||
bool deleteResult;
|
||||
mn1->name = meta->engine->numberToString((int32)0);
|
||||
c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &result);
|
||||
c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &result);
|
||||
|
||||
for (uint32 k = 1; k < length; k++) {
|
||||
mn1->name = meta->engine->numberToString(k);
|
||||
mn2->name = meta->engine->numberToString(k - 1);
|
||||
|
||||
if (meta->hasOwnProperty(thisObj, mn1->name)) {
|
||||
c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &result);
|
||||
c->writePublic(meta, thatValue, c, mn2->name, true, result);
|
||||
c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &result);
|
||||
c->WritePublic(meta, thatValue, mn2->name, true, result);
|
||||
}
|
||||
else
|
||||
c->deletePublic(meta, thatValue, c, mn2->name, &deleteResult);
|
||||
c->DeletePublic(meta, thatValue, mn2->name, &deleteResult);
|
||||
}
|
||||
|
||||
mn2->name = meta->engine->numberToString(length - 1);
|
||||
c->deletePublic(meta, thatValue, c, mn2->name, &deleteResult);
|
||||
c->DeletePublic(meta, thatValue, mn2->name, &deleteResult);
|
||||
setLength(meta, thisObj, length - 1);
|
||||
return result;
|
||||
}
|
||||
@ -438,8 +438,8 @@ static js2val Array_slice(JS2Metadata *meta, const js2val thisValue, js2val *arg
|
||||
if (meta->hasOwnProperty(thisObj, mn1->name)) {
|
||||
js2val rval;
|
||||
mn2->name = meta->engine->numberToString(n);
|
||||
c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &rval);
|
||||
meta->arrayClass->writePublic(meta, result, meta->arrayClass, mn2->name, true, rval);
|
||||
c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &rval);
|
||||
meta->arrayClass->WritePublic(meta, result, mn2->name, true, rval);
|
||||
}
|
||||
n++;
|
||||
start++;
|
||||
@ -593,13 +593,13 @@ static js2val Array_sort(JS2Metadata *meta, const js2val thisValue, js2val *argv
|
||||
|
||||
JS2Class *c = meta->objectType(thisObj);
|
||||
for (i = 0; i < length; i++) {
|
||||
c->readPublic(meta, &thatValue, c, meta->engine->numberToString(i), RunPhase, &vec[i]);
|
||||
c->ReadPublic(meta, &thatValue, meta->engine->numberToString(i), RunPhase, &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]);
|
||||
c->WritePublic(meta, thatValue, meta->engine->numberToString(i), true, vec[i]);
|
||||
}
|
||||
return thatValue;
|
||||
}
|
||||
@ -656,8 +656,8 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar
|
||||
if (meta->hasOwnProperty(thisObj, mn1->name)) {
|
||||
js2val rval;
|
||||
mn2->name = meta->engine->numberToString(k);
|
||||
c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &rval);
|
||||
meta->arrayClass->writePublic(meta, result, meta->arrayClass, mn2->name, true, rval);
|
||||
c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &rval);
|
||||
meta->arrayClass->WritePublic(meta, result, mn2->name, true, rval);
|
||||
}
|
||||
}
|
||||
setLength(meta, A, deleteCount);
|
||||
@ -670,15 +670,15 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar
|
||||
mn2->name = meta->engine->numberToString(k + newItemCount);
|
||||
if (meta->hasOwnProperty(thisObj, mn1->name)) {
|
||||
js2val rval;
|
||||
c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &rval);
|
||||
meta->arrayClass->writePublic(meta, result, meta->arrayClass, mn2->name, true, rval);
|
||||
c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &rval);
|
||||
meta->arrayClass->WritePublic(meta, result, mn2->name, true, rval);
|
||||
}
|
||||
else
|
||||
c->deletePublic(meta, thatValue, c, mn2->name, &deleteResult);
|
||||
c->DeletePublic(meta, thatValue, mn2->name, &deleteResult);
|
||||
}
|
||||
for (k = length; k > (length - deleteCount + newItemCount); k--) {
|
||||
mn1->name = meta->engine->numberToString(k - 1);
|
||||
c->deletePublic(meta, thatValue, c, mn1->name, &deleteResult);
|
||||
c->DeletePublic(meta, thatValue, mn1->name, &deleteResult);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -689,18 +689,18 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar
|
||||
mn2->name = meta->engine->numberToString(k + newItemCount - 1);
|
||||
if (meta->hasOwnProperty(thisObj, mn1->name)) {
|
||||
js2val rval;
|
||||
c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &rval);
|
||||
meta->arrayClass->writePublic(meta, result, meta->arrayClass, mn2->name, true, rval);
|
||||
c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &rval);
|
||||
meta->arrayClass->WritePublic(meta, result, mn2->name, true, rval);
|
||||
}
|
||||
else
|
||||
c->deletePublic(meta, thatValue, c, mn2->name, &deleteResult);
|
||||
c->DeletePublic(meta, thatValue, mn2->name, &deleteResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
k = start;
|
||||
for (uint32 i = 2; i < argc; i++) {
|
||||
mn2->name = meta->engine->numberToString(k++);
|
||||
meta->arrayClass->writePublic(meta, result, meta->arrayClass, mn2->name, true, argv[i]);
|
||||
meta->arrayClass->WritePublic(meta, result, mn2->name, true, argv[i]);
|
||||
}
|
||||
setLength(meta, thisObj, (length - deleteCount + newItemCount));
|
||||
return result;
|
||||
@ -730,16 +730,16 @@ static js2val Array_unshift(JS2Metadata *meta, const js2val thisValue, js2val *a
|
||||
mn2->name = meta->engine->numberToString(k + argc - 1);
|
||||
if (meta->hasOwnProperty(thisObj, mn1->name)) {
|
||||
js2val rval;
|
||||
c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &rval);
|
||||
c->writePublic(meta, thatValue, c, mn2->name, true, rval);
|
||||
c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &rval);
|
||||
c->WritePublic(meta, thatValue, mn2->name, true, rval);
|
||||
}
|
||||
else
|
||||
c->deletePublic(meta, thatValue, c, mn2->name, &deleteResult);
|
||||
c->DeletePublic(meta, thatValue, mn2->name, &deleteResult);
|
||||
}
|
||||
|
||||
for (k = 0; k < argc; k++) {
|
||||
mn1->name = meta->engine->numberToString(k);
|
||||
c->writePublic(meta, thatValue, c, mn1->name, true, argv[k]);
|
||||
c->WritePublic(meta, thatValue, mn1->name, true, argv[k]);
|
||||
}
|
||||
setLength(meta, thisObj, (length + argc));
|
||||
|
||||
|
@ -61,7 +61,7 @@ js2val error_ConstructorCore(JS2Metadata *meta, JS2Class *errorClass, js2val arg
|
||||
js2val thatValue = OBJECT_TO_JS2VAL(obj);
|
||||
|
||||
if (!JS2VAL_IS_VOID(arg)) {
|
||||
errorClass->writePublic(meta, thatValue, errorClass, &meta->world.identifiers["message"], true, meta->engine->allocString(meta->toString(arg)));
|
||||
errorClass->WritePublic(meta, thatValue, &meta->world.identifiers["message"], true, meta->engine->allocString(meta->toString(arg)));
|
||||
}
|
||||
|
||||
return thatValue;
|
||||
@ -111,7 +111,7 @@ js2val Error_toString(JS2Metadata *meta, const js2val thisValue, js2val *argv, u
|
||||
Multiname mn(&meta->world.identifiers["message"], meta->publicNamespace);
|
||||
|
||||
JS2Class *c = meta->objectType(thatValue);
|
||||
if (c->readPublic(meta, &thatValue, c, &meta->world.identifiers["message"], RunPhase, &result)) {
|
||||
if (c->ReadPublic(meta, &thatValue, &meta->world.identifiers["message"], RunPhase, &result)) {
|
||||
if (JS2VAL_IS_STRING(result))
|
||||
return result;
|
||||
else
|
||||
|
@ -226,7 +226,7 @@ namespace MetaData {
|
||||
js2val fnVal;
|
||||
|
||||
JS2Class *limit = objectType(thisValue);
|
||||
if (limit->readPublic(this, &thisValue, limit, fnName, RunPhase, &fnVal)) {
|
||||
if (limit->ReadPublic(this, &thisValue, fnName, RunPhase, &fnVal)) {
|
||||
if (JS2VAL_IS_OBJECT(fnVal)) {
|
||||
JS2Object *fnObj = JS2VAL_TO_OBJECT(fnVal);
|
||||
if ((fnObj->kind == SimpleInstanceKind)
|
||||
@ -627,12 +627,12 @@ namespace MetaData {
|
||||
}
|
||||
|
||||
|
||||
bool defaultReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Environment *env, Phase phase, js2val *rval)
|
||||
bool JS2Class::Read(JS2Metadata *meta, js2val *base, Multiname *multiname, Environment *env, Phase phase, js2val *rval)
|
||||
{
|
||||
InstanceMember *mBase = meta->findBaseInstanceMember(limit, multiname, ReadAccess);
|
||||
InstanceMember *mBase = meta->findBaseInstanceMember(this, multiname, ReadAccess);
|
||||
if (mBase)
|
||||
return meta->readInstanceMember(*base, limit, mBase, phase, rval);
|
||||
if (limit != meta->objectType(*base))
|
||||
return meta->readInstanceMember(*base, this, mBase, phase, rval);
|
||||
if (this != meta->objectType(*base))
|
||||
return false;
|
||||
|
||||
Member *m = meta->findCommonMember(base, multiname, ReadAccess, false);
|
||||
@ -676,48 +676,48 @@ namespace MetaData {
|
||||
}
|
||||
}
|
||||
|
||||
bool defaultReadPublicProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, const String *name, Phase phase, js2val *rval)
|
||||
bool JS2Class::ReadPublic(JS2Metadata *meta, js2val *base, const String *name, Phase phase, js2val *rval)
|
||||
{
|
||||
// XXX could speed up by pushing knowledge of single namespace?
|
||||
DEFINE_ROOTKEEPER(rk1, name);
|
||||
Multiname *mn = new Multiname(name, meta->publicNamespace);
|
||||
DEFINE_ROOTKEEPER(rk, mn);
|
||||
return defaultReadProperty(meta, base, limit, mn, NULL, phase, rval);
|
||||
return Read(meta, base, mn, NULL, phase, rval);
|
||||
}
|
||||
|
||||
bool defaultDeletePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result)
|
||||
bool JS2Class::DeletePublic(JS2Metadata *meta, js2val base, const String *name, bool *result)
|
||||
{
|
||||
DEFINE_ROOTKEEPER(rk1, name);
|
||||
// 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, NULL, result);
|
||||
return Delete(meta, base, mn, NULL, result);
|
||||
}
|
||||
|
||||
bool defaultWritePublicProperty(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue)
|
||||
bool JS2Class::WritePublic(JS2Metadata *meta, js2val base, const String *name, bool createIfMissing, js2val newValue)
|
||||
{
|
||||
DEFINE_ROOTKEEPER(rk1, name);
|
||||
// XXX could speed up by pushing knowledge of single namespace?
|
||||
Multiname *mn = new Multiname(name, meta->publicNamespace);
|
||||
DEFINE_ROOTKEEPER(rk, mn);
|
||||
return defaultWriteProperty(meta, base, limit, mn, NULL, createIfMissing, newValue, false);
|
||||
return Write(meta, base, mn, NULL, createIfMissing, newValue, false);
|
||||
}
|
||||
|
||||
bool defaultBracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval)
|
||||
bool JS2Class::BracketRead(JS2Metadata *meta, js2val *base, js2val indexVal, Phase phase, js2val *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);
|
||||
return Read(meta, base, mn, NULL, phase, rval);
|
||||
}
|
||||
|
||||
bool arrayClass_WriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag)
|
||||
bool JS2ArrayClass::Write(JS2Metadata *meta, js2val base, 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, env, createIfMissing, newValue, false);
|
||||
bool result = JS2Class::Write(meta, base, 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);
|
||||
@ -736,23 +736,23 @@ namespace MetaData {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool arrayClass_WritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue)
|
||||
bool JS2ArrayClass::WritePublic(JS2Metadata *meta, js2val base, const String *name, bool createIfMissing, js2val newValue)
|
||||
{
|
||||
DEFINE_ROOTKEEPER(rk1, name);
|
||||
// XXX could speed up by pushing knowledge of single namespace?
|
||||
Multiname *mn = new Multiname(name, meta->publicNamespace);
|
||||
DEFINE_ROOTKEEPER(rk, mn);
|
||||
return arrayClass_WriteProperty(meta, base, limit, mn, meta->env, createIfMissing, newValue, false);
|
||||
return Write(meta, base, mn, meta->env, createIfMissing, newValue, false);
|
||||
}
|
||||
|
||||
bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag)
|
||||
bool JS2Class::Write(JS2Metadata *meta, js2val base, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag)
|
||||
{
|
||||
InstanceMember *mBase = meta->findBaseInstanceMember(limit, multiname, WriteAccess);
|
||||
InstanceMember *mBase = meta->findBaseInstanceMember(this, multiname, WriteAccess);
|
||||
if (mBase) {
|
||||
meta->writeInstanceMember(base, limit, mBase, newValue);
|
||||
meta->writeInstanceMember(base, this, mBase, newValue);
|
||||
return true;
|
||||
}
|
||||
if (limit != meta->objectType(base))
|
||||
if (this != meta->objectType(base))
|
||||
return false;
|
||||
|
||||
Member *m = meta->findCommonMember(&base, multiname, WriteAccess, true);
|
||||
@ -773,7 +773,7 @@ namespace MetaData {
|
||||
QualifiedName qName = multiname->selectPrimaryName(meta);
|
||||
Multiname *mn = new Multiname(qName);
|
||||
DEFINE_ROOTKEEPER(rk, mn);
|
||||
if ( (meta->findBaseInstanceMember(limit, mn, ReadAccess) == NULL)
|
||||
if ( (meta->findBaseInstanceMember(this, mn, ReadAccess) == NULL)
|
||||
&& (meta->findCommonMember(&base, mn, ReadAccess, true) == NULL) ) {
|
||||
meta->createDynamicProperty(baseObj, &qName, newValue, ReadWriteAccess, false, true);
|
||||
return true;
|
||||
@ -807,23 +807,23 @@ namespace MetaData {
|
||||
}
|
||||
}
|
||||
|
||||
bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, js2val newValue)
|
||||
bool JS2Class::BracketWrite(JS2Metadata *meta, js2val base, js2val indexVal, js2val newValue)
|
||||
{
|
||||
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);
|
||||
return Write(meta, base, mn, NULL, true, newValue, false);
|
||||
}
|
||||
|
||||
bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool *result)
|
||||
bool JS2Class::Delete(JS2Metadata *meta, js2val base, Multiname *multiname, Environment *env, bool *result)
|
||||
{
|
||||
InstanceMember *mBase = meta->findBaseInstanceMember(limit, multiname, WriteAccess);
|
||||
InstanceMember *mBase = meta->findBaseInstanceMember(this, multiname, WriteAccess);
|
||||
if (mBase) {
|
||||
*result = false;
|
||||
return true;
|
||||
}
|
||||
if (limit != meta->objectType(base))
|
||||
if (this != meta->objectType(base))
|
||||
return false;
|
||||
|
||||
Member *m = meta->findCommonMember(&base, multiname, WriteAccess, false);
|
||||
@ -898,24 +898,24 @@ VariableMemberCommon:
|
||||
}
|
||||
}
|
||||
|
||||
bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, bool *result)
|
||||
bool JS2Class::BracketDelete(JS2Metadata *meta, js2val base, js2val indexVal, bool *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);
|
||||
return Delete(meta, base, mn, NULL, result);
|
||||
}
|
||||
|
||||
js2val defaultImplicitCoerce(JS2Metadata *meta, js2val newValue, JS2Class *isClass)
|
||||
js2val JS2Class::ImplicitCoerce(JS2Metadata *meta, js2val newValue)
|
||||
{
|
||||
if (JS2VAL_IS_NULL(newValue) || meta->objectType(newValue)->isAncestor(isClass) )
|
||||
if (JS2VAL_IS_NULL(newValue) || meta->objectType(newValue)->isAncestor(this) )
|
||||
return newValue;
|
||||
meta->reportError(Exception::badValueError, "Illegal coercion", meta->engine->errorPos());
|
||||
return JS2VAL_VOID;
|
||||
}
|
||||
|
||||
js2val integerImplicitCoerce(JS2Metadata *meta, js2val newValue, JS2Class *isClass)
|
||||
js2val JS2IntegerClass::ImplicitCoerce(JS2Metadata *meta, js2val newValue)
|
||||
{
|
||||
if (JS2VAL_IS_UNDEFINED(newValue))
|
||||
return JS2VAL_ZERO;
|
||||
@ -931,12 +931,12 @@ VariableMemberCommon:
|
||||
return JS2VAL_VOID;
|
||||
}
|
||||
|
||||
js2val defaultIs(JS2Metadata *meta, js2val newValue, JS2Class *isClass)
|
||||
js2val JS2Class::Is(JS2Metadata *meta, js2val newValue)
|
||||
{
|
||||
return BOOLEAN_TO_JS2VAL(meta->objectType(newValue) == isClass);
|
||||
return BOOLEAN_TO_JS2VAL(meta->objectType(newValue) == this);
|
||||
}
|
||||
|
||||
js2val integerIs(JS2Metadata *meta, js2val newValue, JS2Class *isClass)
|
||||
js2val JS2IntegerClass::Is(JS2Metadata *meta, js2val newValue)
|
||||
{
|
||||
bool result = false;
|
||||
if (JS2VAL_IS_NUMBER(newValue)) {
|
||||
@ -948,7 +948,7 @@ VariableMemberCommon:
|
||||
return BOOLEAN_TO_JS2VAL(result);
|
||||
}
|
||||
|
||||
bool stringClass_BracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval)
|
||||
bool JS2StringClass::BracketRead(JS2Metadata *meta, js2val *base, js2val indexVal, Phase phase, js2val *rval)
|
||||
{
|
||||
if (JS2VAL_IS_INT(indexVal)) {
|
||||
const String *str = NULL;
|
||||
@ -970,7 +970,7 @@ VariableMemberCommon:
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return defaultBracketRead(meta, base, limit, indexVal, phase, rval);
|
||||
return BracketRead(meta, base, indexVal, phase, rval);
|
||||
}
|
||||
|
||||
|
||||
|
@ -481,7 +481,7 @@ namespace MetaData {
|
||||
ParameterFrame *pFrame = env->getEnclosingParameterFrame();
|
||||
// If there isn't a parameter frame, or the parameter frame is
|
||||
// only a runtime frame (for eval), then it's an orphan return
|
||||
if ((pFrame->kind != ParameterFrameKind) || pFrame->pluralFrame)
|
||||
if (!pFrame || pFrame->pluralFrame)
|
||||
reportError(Exception::syntaxError, "Return statement not in function", p->pos);
|
||||
ExprStmtNode *e = checked_cast<ExprStmtNode *>(p);
|
||||
if (e->expr) {
|
||||
@ -558,7 +558,7 @@ namespace MetaData {
|
||||
}
|
||||
|
||||
VariableBinding *vb = vs->bindings;
|
||||
Frame *regionalFrame = *(env->getRegionalFrame());
|
||||
Frame *regionalFrame = (env->getRegionalFrame())->first;
|
||||
while (vb) {
|
||||
const StringAtom *name = vb->name;
|
||||
if (vb->type)
|
||||
@ -1065,9 +1065,9 @@ namespace MetaData {
|
||||
{
|
||||
SwitchStmtNode *sw = checked_cast<SwitchStmtNode *>(p);
|
||||
FrameListIterator fi = env->getRegionalFrame();
|
||||
NonWithFrame *regionalFrame = checked_cast<NonWithFrame *>(*fi);
|
||||
NonWithFrame *regionalFrame = checked_cast<NonWithFrame *>(fi->first);
|
||||
if (regionalFrame->kind == ParameterFrameKind)
|
||||
regionalFrame = checked_cast<NonWithFrame *>(*--fi);
|
||||
regionalFrame = checked_cast<NonWithFrame *>((--fi)->first);
|
||||
FrameVariable *frV = makeFrameVariable(regionalFrame);
|
||||
ASSERT(frV->kind != FrameVariable::Parameter);
|
||||
Reference *switchTemp;
|
||||
@ -1349,7 +1349,7 @@ namespace MetaData {
|
||||
if (vb->initializer) {
|
||||
try {
|
||||
js2val newValue = EvalExpression(env, CompilePhase, vb->initializer);
|
||||
v->value = type->implicitCoerce(this, newValue, type);
|
||||
v->value = type->ImplicitCoerce(this, newValue);
|
||||
}
|
||||
catch (Exception x) {
|
||||
// If a compileExpressionError occurred, then the initialiser is
|
||||
@ -1420,7 +1420,7 @@ namespace MetaData {
|
||||
v->type = t;
|
||||
if (vb->initializer) {
|
||||
js2val newValue = EvalExpression(env, CompilePhase, vb->initializer);
|
||||
v->defaultValue = t->implicitCoerce(this, newValue, t);
|
||||
v->defaultValue = t->ImplicitCoerce(this, newValue);
|
||||
}
|
||||
else
|
||||
v->defaultValue = t->defaultValue;
|
||||
@ -1778,8 +1778,8 @@ namespace MetaData {
|
||||
break;
|
||||
case ExprNode::This:
|
||||
{
|
||||
js2val a;
|
||||
if (!env->findThis(this, true, &a) || (a == JS2VAL_VOID))
|
||||
ParameterFrame *pFrame = env->getEnclosingParameterFrame();
|
||||
if ((pFrame == NULL) || (pFrame->thisObject == JS2VAL_VOID))
|
||||
if (!cxt->E3compatibility)
|
||||
reportError(Exception::syntaxError, "No 'this' available", p->pos);
|
||||
}
|
||||
@ -1794,8 +1794,8 @@ namespace MetaData {
|
||||
ValidateExpression(cxt, env, s->op);
|
||||
}
|
||||
else {
|
||||
js2val a;
|
||||
if ((c == NULL) || !env->findThis(this, false, &a))
|
||||
ParameterFrame *pFrame = env->getEnclosingParameterFrame();
|
||||
if ((c == NULL) || (pFrame == NULL) || !(pFrame->isConstructor || pFrame->isInstance))
|
||||
reportError(Exception::syntaxError, "No 'super' available", p->pos);
|
||||
if (c->super == NULL)
|
||||
reportError(Exception::definitionError, "No 'super' for this class", p->pos);
|
||||
@ -2342,7 +2342,7 @@ doUnary:
|
||||
// that the arguments property will get built
|
||||
FrameListIterator fi = env->getBegin();
|
||||
while (fi != env->getEnd()) {
|
||||
Frame *fr = *fi;
|
||||
Frame *fr = fi->first;
|
||||
if ((fr->kind != WithFrameKind) && (fr->kind != BlockFrameKind)) {
|
||||
NonWithFrame *nwf = checked_cast<NonWithFrame *>(fr);
|
||||
if (nwf->kind == ParameterFrameKind) {
|
||||
@ -2369,7 +2369,7 @@ doUnary:
|
||||
FrameListIterator fi = env->getBegin();
|
||||
bool keepLooking = true;
|
||||
while (fi != env->getEnd() && keepLooking) {
|
||||
Frame *fr = *fi;
|
||||
Frame *fr = fi->first;
|
||||
if (fr->kind == WithFrameKind)
|
||||
// XXX unless it's provably not a dynamic object that been with'd??
|
||||
break;
|
||||
@ -2750,8 +2750,8 @@ doUnary:
|
||||
{
|
||||
FrameListIterator fi = getBegin();
|
||||
while (fi != getEnd()) {
|
||||
if ((*fi)->kind == ClassKind)
|
||||
return checked_cast<JS2Class *>(*fi);
|
||||
if ((fi->first)->kind == ClassKind)
|
||||
return checked_cast<JS2Class *>(fi->first);
|
||||
fi++;
|
||||
}
|
||||
return NULL;
|
||||
@ -2763,13 +2763,13 @@ doUnary:
|
||||
{
|
||||
FrameListIterator fi = getBegin();
|
||||
while (fi != getEnd()) {
|
||||
switch ((*fi)->kind) {
|
||||
switch ((fi->first)->kind) {
|
||||
case ClassKind:
|
||||
case PackageKind:
|
||||
case SystemKind:
|
||||
return NULL;
|
||||
case ParameterFrameKind:
|
||||
return checked_cast<ParameterFrame *>(*fi);
|
||||
return checked_cast<ParameterFrame *>(fi->first);
|
||||
case BlockFrameKind:
|
||||
case WithFrameKind:
|
||||
break;
|
||||
@ -2788,12 +2788,12 @@ doUnary:
|
||||
{
|
||||
FrameListIterator start = getBegin();
|
||||
FrameListIterator fi = start;
|
||||
while (((*fi)->kind == BlockFrameKind) || ((*fi)->kind == WithFrameKind)) {
|
||||
while (((fi->first)->kind == BlockFrameKind) || ((fi->first)->kind == WithFrameKind)) {
|
||||
fi++;
|
||||
ASSERT(fi != getEnd());
|
||||
}
|
||||
if ((*fi)->kind == ClassKind) {
|
||||
while ((fi != start) && ((*fi)->kind != BlockFrameKind))
|
||||
if ((fi->first)->kind == ClassKind) {
|
||||
while ((fi != start) && ((fi->first)->kind != BlockFrameKind))
|
||||
fi--;
|
||||
}
|
||||
return fi;
|
||||
@ -2811,30 +2811,11 @@ doUnary:
|
||||
// Returns the penultimate frame, always a Package
|
||||
Package *Environment::getPackageFrame()
|
||||
{
|
||||
Frame *result = *(getEnd() - 2);
|
||||
Frame *result = (getEnd() - 2)->first;
|
||||
ASSERT(result->kind == PackageKind);
|
||||
return checked_cast<Package *>(result);
|
||||
}
|
||||
|
||||
// findThis returns the value of this. If allowPrototypeThis is true, allow this to be defined
|
||||
// by either an instance member of a class or a prototype function. If allowPrototypeThis is
|
||||
// false, allow this to be defined only by an instance member of a class.
|
||||
bool Environment::findThis(JS2Metadata *meta, bool allowPrototypeThis, js2val *result)
|
||||
{
|
||||
FrameListIterator fi = getBegin();
|
||||
while (fi != getEnd()) {
|
||||
Frame *pf = *fi;
|
||||
if ((pf->kind == ParameterFrameKind)
|
||||
&& !JS2VAL_IS_NULL(checked_cast<ParameterFrame *>(pf)->thisObject))
|
||||
if (allowPrototypeThis || !checked_cast<ParameterFrame *>(pf)->prototype) {
|
||||
*result = checked_cast<ParameterFrame *>(pf)->thisObject;
|
||||
return true;
|
||||
}
|
||||
fi++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
js2val Environment::readImplicitThis(JS2Metadata *meta)
|
||||
{
|
||||
ParameterFrame *pFrame = getEnclosingParameterFrame();
|
||||
@ -2856,36 +2837,35 @@ doUnary:
|
||||
// an error.
|
||||
void Environment::lexicalRead(JS2Metadata *meta, Multiname *multiname, Phase phase, js2val *rval, js2val *base)
|
||||
{
|
||||
js2val a = JS2VAL_VOID;
|
||||
findThis(meta, false, &a);
|
||||
FrameListIterator fi = getBegin();
|
||||
bool result = false;
|
||||
while (fi != getEnd()) {
|
||||
switch ((*fi)->kind) {
|
||||
Frame *f = fi->first;
|
||||
switch (f->kind) {
|
||||
case ClassKind:
|
||||
case PackageKind:
|
||||
{
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi));
|
||||
js2val frame = OBJECT_TO_JS2VAL(*fi);
|
||||
result = limit->read(meta, &frame, limit, multiname, this, phase, rval);
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(f));
|
||||
js2val frame = OBJECT_TO_JS2VAL(f);
|
||||
result = limit->Read(meta, &frame, multiname, this, phase, rval);
|
||||
}
|
||||
break;
|
||||
case SystemKind:
|
||||
case ParameterFrameKind:
|
||||
case BlockFrameKind:
|
||||
{
|
||||
LocalMember *m = meta->findLocalMember(*fi, multiname, ReadAccess);
|
||||
LocalMember *m = meta->findLocalMember(f, multiname, ReadAccess);
|
||||
if (m)
|
||||
result = meta->readLocalMember(m, phase, rval);
|
||||
}
|
||||
break;
|
||||
case WithFrameKind:
|
||||
{
|
||||
WithFrame *wf = checked_cast<WithFrame *>(*fi);
|
||||
WithFrame *wf = checked_cast<WithFrame *>(f);
|
||||
// XXX uninitialized 'with' object?
|
||||
js2val withVal = OBJECT_TO_JS2VAL(wf->obj);
|
||||
JS2Class *limit = meta->objectType(withVal);
|
||||
result = limit->read(meta, &withVal, limit, multiname, this, phase, rval);
|
||||
result = limit->Read(meta, &withVal, multiname, this, phase, rval);
|
||||
if (result && base)
|
||||
*base = withVal;
|
||||
}
|
||||
@ -2902,24 +2882,23 @@ doUnary:
|
||||
// exists, then fine. Otherwise create the property there.
|
||||
void Environment::lexicalWrite(JS2Metadata *meta, Multiname *multiname, js2val newValue, bool createIfMissing)
|
||||
{
|
||||
js2val a = JS2VAL_VOID;
|
||||
findThis(meta, false, &a);
|
||||
FrameListIterator fi = getBegin();
|
||||
bool result = false;
|
||||
while (fi != getEnd()) {
|
||||
switch ((*fi)->kind) {
|
||||
Frame *f = fi->first;
|
||||
switch (f->kind) {
|
||||
case ClassKind:
|
||||
case PackageKind:
|
||||
{
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi));
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, this, false, newValue, false);
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(f));
|
||||
result = limit->Write(meta, OBJECT_TO_JS2VAL(f), multiname, this, false, newValue, false);
|
||||
}
|
||||
break;
|
||||
case SystemKind:
|
||||
case ParameterFrameKind:
|
||||
case BlockFrameKind:
|
||||
{
|
||||
LocalMember *m = meta->findLocalMember(*fi, multiname, WriteAccess);
|
||||
LocalMember *m = meta->findLocalMember(f, multiname, WriteAccess);
|
||||
if (m) {
|
||||
meta->writeLocalMember(m, newValue, false);
|
||||
result = true;
|
||||
@ -2928,10 +2907,10 @@ doUnary:
|
||||
break;
|
||||
case WithFrameKind:
|
||||
{
|
||||
WithFrame *wf = checked_cast<WithFrame *>(*fi);
|
||||
WithFrame *wf = checked_cast<WithFrame *>(f);
|
||||
// XXX uninitialized 'with' object?
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(wf->obj));
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, this, false, newValue, false);
|
||||
result = limit->Write(meta, OBJECT_TO_JS2VAL(wf->obj), multiname, this, false, newValue, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2942,7 +2921,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, this, true, newValue, false);
|
||||
result = limit->Write(meta, OBJECT_TO_JS2VAL(pkg), multiname, this, true, newValue, false);
|
||||
if (result)
|
||||
return;
|
||||
}
|
||||
@ -2955,24 +2934,23 @@ doUnary:
|
||||
// but it had darn well better be in the environment somewhere.
|
||||
void Environment::lexicalInit(JS2Metadata *meta, Multiname *multiname, js2val newValue)
|
||||
{
|
||||
js2val a = JS2VAL_VOID;
|
||||
findThis(meta, false, &a);
|
||||
FrameListIterator fi = getBegin();
|
||||
bool result = false;
|
||||
while (fi != getEnd()) {
|
||||
switch ((*fi)->kind) {
|
||||
Frame *f = fi->first;
|
||||
switch (f->kind) {
|
||||
case ClassKind:
|
||||
case PackageKind:
|
||||
{
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi));
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, this, false, newValue, true);
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(f));
|
||||
result = limit->Write(meta, OBJECT_TO_JS2VAL(f), multiname, this, false, newValue, true);
|
||||
}
|
||||
break;
|
||||
case SystemKind:
|
||||
case ParameterFrameKind:
|
||||
case BlockFrameKind:
|
||||
{
|
||||
LocalMember *m = meta->findLocalMember(*fi, multiname, WriteAccess);
|
||||
LocalMember *m = meta->findLocalMember(f, multiname, WriteAccess);
|
||||
if (m) {
|
||||
meta->writeLocalMember(m, newValue, true);
|
||||
result = true;
|
||||
@ -2981,10 +2959,10 @@ doUnary:
|
||||
break;
|
||||
case WithFrameKind:
|
||||
{
|
||||
WithFrame *wf = checked_cast<WithFrame *>(*fi);
|
||||
WithFrame *wf = checked_cast<WithFrame *>(f);
|
||||
// XXX uninitialized 'with' object?
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(wf->obj));
|
||||
result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, this, false, newValue, true);
|
||||
result = limit->Write(meta, OBJECT_TO_JS2VAL(wf->obj), multiname, this, false, newValue, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2996,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, this, true, newValue, true);
|
||||
result = limit->Write(meta, OBJECT_TO_JS2VAL(pkg), multiname, this, true, newValue, true);
|
||||
if (result)
|
||||
return;
|
||||
}
|
||||
@ -3005,17 +2983,16 @@ doUnary:
|
||||
// can't be found, or the result of the deleteProperty call if it was found.
|
||||
bool Environment::lexicalDelete(JS2Metadata *meta, Multiname *multiname, Phase phase)
|
||||
{
|
||||
js2val a = JS2VAL_VOID;
|
||||
findThis(meta, false, &a);
|
||||
FrameListIterator fi = getBegin();
|
||||
bool result = false;
|
||||
while (fi != getEnd()) {
|
||||
switch ((*fi)->kind) {
|
||||
Frame *f = fi->first;
|
||||
switch (f->kind) {
|
||||
case ClassKind:
|
||||
case PackageKind:
|
||||
{
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi));
|
||||
if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, this, &result))
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(f));
|
||||
if (limit->Delete(meta, OBJECT_TO_JS2VAL(f), multiname, this, &result))
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
@ -3023,17 +3000,17 @@ doUnary:
|
||||
case ParameterFrameKind:
|
||||
case BlockFrameKind:
|
||||
{
|
||||
LocalMember *m = meta->findLocalMember(*fi, multiname, WriteAccess);
|
||||
LocalMember *m = meta->findLocalMember(f, multiname, WriteAccess);
|
||||
if (m)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case WithFrameKind:
|
||||
{
|
||||
WithFrame *wf = checked_cast<WithFrame *>(*fi);
|
||||
WithFrame *wf = checked_cast<WithFrame *>(f);
|
||||
// XXX uninitialized 'with' object?
|
||||
JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(wf->obj));
|
||||
if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, this, &result))
|
||||
if (limit->Delete(meta, OBJECT_TO_JS2VAL(wf->obj), multiname, this, &result))
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
@ -3071,7 +3048,7 @@ doUnary:
|
||||
{
|
||||
FrameListIterator fi = getBegin();
|
||||
while (fi != getEnd()) {
|
||||
GCMARKOBJECT(*fi)
|
||||
GCMARKOBJECT(fi->first)
|
||||
fi++;
|
||||
}
|
||||
}
|
||||
@ -3172,7 +3149,7 @@ doUnary:
|
||||
Attribute::OverrideModifier overrideMod, bool xplicit, Access access,
|
||||
LocalMember *m, size_t pos, bool enumerable)
|
||||
{
|
||||
NonWithFrame *innerFrame = checked_cast<NonWithFrame *>(*(env->getBegin()));
|
||||
NonWithFrame *innerFrame = checked_cast<NonWithFrame *>((env->getBegin())->first);
|
||||
if ((overrideMod != Attribute::NoOverride) || (xplicit && innerFrame->kind != PackageKind))
|
||||
reportError(Exception::definitionError, "Illegal definition", pos);
|
||||
|
||||
@ -3194,12 +3171,12 @@ doUnary:
|
||||
|
||||
// Check all frames below the current - up to the RegionalFrame - for a non-forbidden definition
|
||||
FrameListIterator fi = env->getBegin();
|
||||
Frame *regionalFrame = *env->getRegionalFrame();
|
||||
Frame *regionalFrame = env->getRegionalFrame()->first;
|
||||
if (innerFrame != regionalFrame) {
|
||||
// The frame iterator is pointing at the top of the environment's
|
||||
// frame list, start at the one below that and continue to the frame
|
||||
// returned by 'getRegionalFrame()'.
|
||||
Frame *fr = *++fi;
|
||||
Frame *fr = (++fi)->first;
|
||||
while (true) {
|
||||
if (fr->kind != WithFrameKind) {
|
||||
NonWithFrame *nwfr = checked_cast<NonWithFrame *>(fr);
|
||||
@ -3216,7 +3193,7 @@ doUnary:
|
||||
}
|
||||
if (fr == regionalFrame)
|
||||
break;
|
||||
fr = *++fi;
|
||||
fr = (++fi)->first;
|
||||
ASSERT(fr);
|
||||
}
|
||||
}
|
||||
@ -3237,7 +3214,7 @@ doUnary:
|
||||
// region if they haven't been marked as such already.
|
||||
if (innerFrame != regionalFrame) {
|
||||
fi = env->getBegin();
|
||||
Frame *fr = *++fi;
|
||||
Frame *fr = ++fi->first;
|
||||
while (true) {
|
||||
if (fr->kind != WithFrameKind) {
|
||||
NonWithFrame *nwfr = checked_cast<NonWithFrame *>(fr);
|
||||
@ -3264,7 +3241,7 @@ doUnary:
|
||||
}
|
||||
if (fr == regionalFrame)
|
||||
break;
|
||||
fr = *++fi;
|
||||
fr = ++fi->first;
|
||||
}
|
||||
}
|
||||
return multiname;
|
||||
@ -3431,7 +3408,7 @@ doUnary:
|
||||
{
|
||||
LocalMember *result = NULL;
|
||||
FrameListIterator regionalFrameEnd = env->getRegionalEnvironment();
|
||||
NonWithFrame *regionalFrame = checked_cast<NonWithFrame *>(*regionalFrameEnd);
|
||||
NonWithFrame *regionalFrame = checked_cast<NonWithFrame *>(regionalFrameEnd->first);
|
||||
ASSERT((regionalFrame->kind == PackageKind) || (regionalFrame->kind == ParameterFrameKind));
|
||||
rescan:
|
||||
// run through all the existing bindings, to see if this variable already exists.
|
||||
@ -3455,7 +3432,7 @@ rescan:
|
||||
&& (regionalFrame->kind == ParameterFrameKind)
|
||||
&& (regionalFrameEnd != env->getBegin())) {
|
||||
// re-scan in the frame above the parameter frame
|
||||
regionalFrame = checked_cast<NonWithFrame *>(*(regionalFrameEnd - 1));
|
||||
regionalFrame = checked_cast<NonWithFrame *>((regionalFrameEnd - 1)->first);
|
||||
goto rescan;
|
||||
}
|
||||
|
||||
@ -3806,7 +3783,7 @@ static const uint8 urlCharType[256] =
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(thisValue);
|
||||
ASSERT(obj->kind == ClassKind);
|
||||
JS2Class *c = checked_cast<JS2Class *>(obj);
|
||||
return OBJECT_TO_JS2VAL(c->super);
|
||||
return OBJECT_TO_JS2VAL(meta->functionClass->prototype);
|
||||
}
|
||||
|
||||
static js2val Object_valueOf(JS2Metadata *meta, const js2val thisValue, js2val /* argv */ [], uint32 /* argc */)
|
||||
@ -3814,16 +3791,6 @@ static const uint8 urlCharType[256] =
|
||||
return thisValue;
|
||||
}
|
||||
|
||||
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, 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, 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, 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;
|
||||
|
||||
@ -3845,27 +3812,13 @@ bool nullClass_BracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, js
|
||||
|
||||
MAKEBUILTINCLASS(objectClass, NULL, false, false, engine->Object_StringAtom, JS2VAL_VOID);
|
||||
MAKEBUILTINCLASS(undefinedClass, objectClass, false, true, engine->undefined_StringAtom, JS2VAL_VOID);
|
||||
MAKEBUILTINCLASS(nullClass, objectClass, false, true, engine->null_StringAtom, JS2VAL_NULL);
|
||||
nullClass->read = nullClass_ReadProperty;
|
||||
nullClass->readPublic = nullClass_ReadPublicProperty;
|
||||
nullClass->write = nullClass_WriteProperty;
|
||||
nullClass->writePublic = nullClass_WritePublicProperty;
|
||||
nullClass->deleteProperty = nullClass_DeleteProperty;
|
||||
nullClass->deletePublic = nullClass_DeletePublic;
|
||||
nullClass->bracketRead = nullClass_BracketRead;
|
||||
nullClass->bracketWrite = nullClass_BracketWrite;
|
||||
nullClass->bracketDelete = nullClass_BracketDelete;
|
||||
|
||||
nullClass = new JS2NullClass(objectClass, NULL, new Namespace(engine->private_StringAtom), false, true, engine->null_StringAtom); nullClass->complete = true; nullClass->defaultValue = JS2VAL_NULL;
|
||||
MAKEBUILTINCLASS(booleanClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["Boolean"]), JS2VAL_FALSE);
|
||||
MAKEBUILTINCLASS(generalNumberClass, objectClass, false, false, engine->allocStringPtr(&world.identifiers["general number"]), engine->nanValue);
|
||||
MAKEBUILTINCLASS(numberClass, generalNumberClass, false, true, engine->allocStringPtr(&world.identifiers["Number"]), engine->nanValue);
|
||||
MAKEBUILTINCLASS(integerClass, numberClass, false, true, engine->allocStringPtr(&world.identifiers["Integer"]), JS2VAL_ZERO);
|
||||
integerClass->implicitCoerce = integerImplicitCoerce;
|
||||
integerClass->is = integerIs;
|
||||
integerClass = new JS2IntegerClass(numberClass, NULL, new Namespace(engine->private_StringAtom), false, true, engine->allocStringPtr(&world.identifiers["Integer"])); integerClass->complete = true; integerClass->defaultValue = JS2VAL_ZERO;
|
||||
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;
|
||||
|
||||
stringClass = new JS2StringClass(objectClass, NULL, new Namespace(engine->private_StringAtom), false, true, engine->allocStringPtr(&world.identifiers["String"])); stringClass->complete = true; stringClass->defaultValue = JS2VAL_NULL;
|
||||
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);
|
||||
@ -4018,9 +3971,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
||||
initMathObject(this, mathObject);
|
||||
|
||||
/*** ECMA 3 Array Class ***/
|
||||
MAKEBUILTINCLASS(arrayClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["Array"]), JS2VAL_NULL);
|
||||
arrayClass->write = arrayClass_WriteProperty;
|
||||
arrayClass->writePublic = arrayClass_WritePublic;
|
||||
|
||||
arrayClass = new JS2ArrayClass(objectClass, NULL, new Namespace(engine->private_StringAtom), true, true, engine->allocStringPtr(&world.identifiers["Array"])); arrayClass->complete = true; arrayClass->defaultValue = JS2VAL_NULL;
|
||||
v = new Variable(classClass, OBJECT_TO_JS2VAL(arrayClass), true);
|
||||
defineLocalMember(env, &world.identifiers["Array"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
|
||||
initArrayObject(this);
|
||||
@ -4289,7 +4241,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
||||
Slot *s = findSlot(containerVal, mv);
|
||||
if (mv->immutable && !JS2VAL_IS_UNINITIALIZED(s->value))
|
||||
reportError(Exception::compileExpressionError, "Reinitialization of constant", engine->errorPos());
|
||||
s->value = mv->type->implicitCoerce(this, newValue, mv->type);
|
||||
s->value = mv->type->ImplicitCoerce(this, newValue);
|
||||
return true;
|
||||
}
|
||||
case Member::InstanceSetterMember:
|
||||
@ -4330,15 +4282,15 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
||||
case FrameVariable::Local:
|
||||
{
|
||||
FrameListIterator fi = env->getRegionalFrame();
|
||||
ASSERT((*fi)->kind == ParameterFrameKind);
|
||||
*rval = (*checked_cast<NonWithFrame *>(*(fi - 1))->slots)[f->frameSlot];
|
||||
ASSERT((fi->first)->kind == ParameterFrameKind);
|
||||
*rval = (*checked_cast<NonWithFrame *>((fi - 1)->first)->slots)[f->frameSlot];
|
||||
}
|
||||
break;
|
||||
case FrameVariable::Parameter:
|
||||
{
|
||||
FrameListIterator fi = env->getRegionalFrame();
|
||||
ASSERT((*fi)->kind == ParameterFrameKind);
|
||||
*rval = (*checked_cast<NonWithFrame *>(*fi)->slots)[f->frameSlot];
|
||||
ASSERT((fi->first)->kind == ParameterFrameKind);
|
||||
*rval = (*checked_cast<NonWithFrame *>(fi->first)->slots)[f->frameSlot];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -4386,7 +4338,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
||||
reportError(Exception::propertyAccessError, "Forbidden access", engine->errorPos());
|
||||
else // quietly ignore the write for JS1 compatibility
|
||||
return true;
|
||||
v->value = v->type->implicitCoerce(this, newValue, v->type);
|
||||
v->value = v->type->ImplicitCoerce(this, newValue);
|
||||
}
|
||||
return true;
|
||||
case LocalMember::FrameVariableMember:
|
||||
@ -4399,15 +4351,15 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
||||
case FrameVariable::Local:
|
||||
{
|
||||
FrameListIterator fi = env->getRegionalFrame();
|
||||
ASSERT((*fi)->kind == ParameterFrameKind);
|
||||
(*checked_cast<NonWithFrame *>(*(fi - 1))->slots)[f->frameSlot] = newValue;
|
||||
ASSERT((fi->first)->kind == ParameterFrameKind);
|
||||
(*checked_cast<NonWithFrame *>((fi - 1)->first)->slots)[f->frameSlot] = newValue;
|
||||
}
|
||||
break;
|
||||
case FrameVariable::Parameter:
|
||||
{
|
||||
FrameListIterator fi = env->getRegionalFrame();
|
||||
ASSERT((*fi)->kind == ParameterFrameKind);
|
||||
(*checked_cast<NonWithFrame *>(*fi)->slots)[f->frameSlot] = newValue;
|
||||
ASSERT((fi->first)->kind == ParameterFrameKind);
|
||||
(*checked_cast<NonWithFrame *>(fi->first)->slots)[f->frameSlot] = newValue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -4660,17 +4612,6 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
||||
call(NULL),
|
||||
construct(JS2Engine::defaultConstructor),
|
||||
init(NULL),
|
||||
read(defaultReadProperty),
|
||||
readPublic(defaultReadPublicProperty),
|
||||
write(defaultWriteProperty),
|
||||
writePublic(defaultWritePublicProperty),
|
||||
deleteProperty(defaultDeleteProperty),
|
||||
deletePublic(defaultDeletePublic),
|
||||
bracketRead(defaultBracketRead),
|
||||
bracketWrite(defaultBracketWrite),
|
||||
bracketDelete(defaultBracketDelete),
|
||||
implicitCoerce(defaultImplicitCoerce),
|
||||
is(defaultIs),
|
||||
slotCount(super ? super->slotCount : 0)
|
||||
{
|
||||
}
|
||||
@ -5068,18 +5009,18 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
||||
(*slots)[i] = argBase[i];
|
||||
}
|
||||
if (plural->buildArguments)
|
||||
meta->objectClass->writePublic(meta, OBJECT_TO_JS2VAL(argsObj), meta->objectClass, meta->engine->numberToString(i), true, argBase[i]);
|
||||
meta->objectClass->WritePublic(meta, OBJECT_TO_JS2VAL(argsObj), meta->engine->numberToString(i), true, argBase[i]);
|
||||
}
|
||||
while (i++ < length) {
|
||||
if (i < slotCount) {
|
||||
(*slots)[i] = JS2VAL_UNDEFINED;
|
||||
}
|
||||
if (plural->buildArguments)
|
||||
meta->objectClass->writePublic(meta, OBJECT_TO_JS2VAL(argsObj), meta->objectClass, meta->engine->numberToString(i), true, JS2VAL_UNDEFINED);
|
||||
meta->objectClass->WritePublic(meta, OBJECT_TO_JS2VAL(argsObj), meta->engine->numberToString(i), true, JS2VAL_UNDEFINED);
|
||||
}
|
||||
if (plural->buildArguments) {
|
||||
setLength(meta, argsObj, argCount);
|
||||
meta->objectClass->writePublic(meta, OBJECT_TO_JS2VAL(argsObj), meta->objectClass, meta->engine->allocStringPtr("callee"), true, OBJECT_TO_JS2VAL(fnObj));
|
||||
meta->objectClass->WritePublic(meta, OBJECT_TO_JS2VAL(argsObj), meta->engine->allocStringPtr("callee"), true, OBJECT_TO_JS2VAL(fnObj));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@ 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, 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, Environment *env, bool createIfMissing, js2val newValue, bool initFlag);
|
||||
@ -94,7 +95,7 @@ js2val integerImplicitCoerce(JS2Metadata *meta, js2val newValue, JS2Class *isCla
|
||||
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);
|
||||
extern void initMathObject(JS2Metadata *meta, SimpleInstance *mathObject);
|
||||
@ -719,13 +720,17 @@ public:
|
||||
// a list of two or more frames. Each frame corresponds to a scope. More specific frames are listed first
|
||||
// -each frame's scope is directly contained in the following frame's scope. The last frame is always the
|
||||
// SYSTEMFRAME. The next-to-last frame is always a PACKAGE or GLOBAL frame.
|
||||
typedef std::deque<Frame *> FrameList;
|
||||
typedef std::deque<std::pair<Frame *, js2val> > FrameList;
|
||||
typedef FrameList::iterator FrameListIterator;
|
||||
|
||||
// Deriving from JS2Object for gc sake only
|
||||
class Environment : public JS2Object {
|
||||
public:
|
||||
Environment(SystemFrame *systemFrame, Frame *nextToLast) : JS2Object(EnvironmentKind) { frameList.push_back(nextToLast); frameList.push_back(systemFrame); }
|
||||
Environment(SystemFrame *systemFrame, Frame *nextToLast) : JS2Object(EnvironmentKind)
|
||||
{
|
||||
frameList.push_back(std::pair<Frame *, js2val>(nextToLast, JS2VAL_VOID));
|
||||
frameList.push_back(std::pair<Frame *, js2val>(systemFrame, JS2VAL_VOID));
|
||||
}
|
||||
virtual ~Environment() { }
|
||||
|
||||
Environment(Environment *e) : JS2Object(EnvironmentKind), frameList(e->frameList) { }
|
||||
@ -734,18 +739,18 @@ public:
|
||||
ParameterFrame *Environment::getEnclosingParameterFrame();
|
||||
FrameListIterator getRegionalFrame();
|
||||
FrameListIterator getRegionalEnvironment();
|
||||
Frame *getTopFrame() { return frameList.front(); }
|
||||
Frame *getTopFrame() { return frameList.front().first; }
|
||||
FrameListIterator getBegin() { return frameList.begin(); }
|
||||
FrameListIterator getEnd() { return frameList.end(); }
|
||||
Package *getPackageFrame();
|
||||
SystemFrame *getSystemFrame() { return checked_cast<SystemFrame *>(frameList.back()); }
|
||||
SystemFrame *getSystemFrame() { return checked_cast<SystemFrame *>(frameList.back().first); }
|
||||
|
||||
void setTopFrame(Frame *f) { while (frameList.front() != f) frameList.pop_front(); }
|
||||
void setTopFrame(Frame *f) { while (frameList.front().first != f) frameList.pop_front(); }
|
||||
|
||||
void addFrame(Frame *f) { frameList.push_front(f); }
|
||||
void addFrame(Frame *f) { frameList.push_front(std::pair<Frame *, js2val>(f, JS2VAL_VOID)); }
|
||||
void addFrame(Frame *f, js2val x) { frameList.push_front(std::pair<Frame *, js2val>(f, x)); }
|
||||
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);
|
||||
@ -790,29 +795,67 @@ public:
|
||||
|
||||
void emitDefaultValue(BytecodeContainer *bCon, size_t pos);
|
||||
|
||||
|
||||
Read *read;
|
||||
ReadPublic *readPublic;
|
||||
Write *write;
|
||||
WritePublic *writePublic;
|
||||
DeleteProperty *deleteProperty;
|
||||
DeletePublic *deletePublic;
|
||||
BracketRead *bracketRead;
|
||||
BracketWrite *bracketWrite;
|
||||
BracketDelete *bracketDelete;
|
||||
ImplicitCoerce *implicitCoerce;
|
||||
Is *is;
|
||||
virtual bool Read(JS2Metadata *meta, js2val *base, Multiname *multiname, Environment *env, Phase phase, js2val *rval);
|
||||
virtual bool ReadPublic(JS2Metadata *meta, js2val *base, const String *name, Phase phase, js2val *rval);
|
||||
virtual bool Write(JS2Metadata *meta, js2val base, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag);
|
||||
virtual bool WritePublic(JS2Metadata *meta, js2val base, const String *name, bool createIfMissing, js2val newValue);
|
||||
virtual bool Delete(JS2Metadata *meta, js2val base, Multiname *multiname, Environment *env, bool *result);
|
||||
virtual bool DeletePublic(JS2Metadata *meta, js2val base, const String *name, bool *result);
|
||||
virtual bool BracketRead(JS2Metadata *meta, js2val *base, js2val indexVal, Phase phase, js2val *rval);
|
||||
virtual bool BracketWrite(JS2Metadata *meta, js2val base, js2val indexVal, js2val newValue);
|
||||
virtual bool BracketDelete(JS2Metadata *meta, js2val base, js2val indexVal, bool *result);
|
||||
virtual js2val ImplicitCoerce(JS2Metadata *meta, js2val newValue);
|
||||
virtual js2val Is(JS2Metadata *meta, js2val newValue);
|
||||
|
||||
bool isAncestor(JS2Class *heir);
|
||||
|
||||
|
||||
uint32 slotCount;
|
||||
|
||||
|
||||
virtual void instantiate(Environment * /* env */) { } // nothing to do
|
||||
virtual void markChildren();
|
||||
virtual ~JS2Class();
|
||||
};
|
||||
|
||||
class JS2ArrayClass : public JS2Class {
|
||||
public:
|
||||
JS2ArrayClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const String *name)
|
||||
: JS2Class(super, proto, privateNamespace, dynamic, final, name) { }
|
||||
|
||||
virtual bool Write(JS2Metadata *meta, js2val base, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag);
|
||||
virtual bool WritePublic(JS2Metadata *meta, js2val base, const String *name, bool createIfMissing, js2val newValue);
|
||||
};
|
||||
|
||||
class JS2IntegerClass : public JS2Class {
|
||||
public:
|
||||
JS2IntegerClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const String *name)
|
||||
: JS2Class(super, proto, privateNamespace, dynamic, final, name) { }
|
||||
|
||||
virtual js2val ImplicitCoerce(JS2Metadata *meta, js2val newValue);
|
||||
virtual js2val Is(JS2Metadata *meta, js2val newValue);
|
||||
};
|
||||
|
||||
class JS2StringClass : public JS2Class {
|
||||
public:
|
||||
JS2StringClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const String *name)
|
||||
: JS2Class(super, proto, privateNamespace, dynamic, final, name) { }
|
||||
|
||||
virtual bool BracketRead(JS2Metadata *meta, js2val *base, js2val indexVal, Phase phase, js2val *rval);
|
||||
};
|
||||
|
||||
class JS2NullClass : public JS2Class {
|
||||
public:
|
||||
JS2NullClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const String *name)
|
||||
: JS2Class(super, proto, privateNamespace, dynamic, final, name) { }
|
||||
|
||||
virtual bool Read(JS2Metadata *meta, js2val *base, Multiname *multiname, Environment *env, Phase phase, js2val *rval) { return false; }
|
||||
virtual bool ReadPublic(JS2Metadata *meta, js2val *base, const String *name, Phase phase, js2val *rval) { return false; }
|
||||
virtual bool BracketRead(JS2Metadata *meta, js2val *base, js2val indexVal, Phase phase, js2val *rval) { return false; }
|
||||
virtual bool Write(JS2Metadata *meta, js2val base, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag) { return false; }
|
||||
virtual bool WritePublic(JS2Metadata *meta, js2val base, const String *name, bool createIfMissing, js2val newValue) { return false; }
|
||||
virtual bool BracketWrite(JS2Metadata *meta, js2val base, js2val indexVal, js2val newValue) { return false; }
|
||||
virtual bool Delete(JS2Metadata *meta, js2val base, Multiname *multiname, Environment *env, bool *result) { return false; }
|
||||
virtual bool DeletePublic(JS2Metadata *meta, js2val base, const String *name, bool *result) { return false; }
|
||||
virtual bool BracketDelete(JS2Metadata *meta, js2val base, js2val indexVal, bool *result) { return false; }
|
||||
};
|
||||
|
||||
class Package : public NonWithFrame {
|
||||
@ -987,7 +1030,7 @@ public:
|
||||
js2val getIgnoreCase(JS2Metadata *meta);
|
||||
js2val getSource(JS2Metadata *meta);
|
||||
|
||||
JSRegExp *mRegExp;
|
||||
JS2RegExp *mRegExp;
|
||||
virtual ~RegExpInstance() { }
|
||||
};
|
||||
|
||||
|
@ -42,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, NULL, RunPhase, &a))
|
||||
if (!li->limit->Read(meta, &b, 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, NULL, RunPhase, &a))
|
||||
if (!limit->Read(meta, &b, mn, NULL, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
}
|
||||
push(a);
|
||||
@ -61,7 +61,7 @@
|
||||
b = pop();
|
||||
bool result;
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->deleteProperty(meta, b, limit, mn, NULL, &result))
|
||||
if (!limit->Delete(meta, b, mn, NULL, &result))
|
||||
push(JS2VAL_FALSE);
|
||||
else
|
||||
push(BOOLEAN_TO_JS2VAL(result));
|
||||
@ -81,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, NULL, true, a, false)) {
|
||||
if (!li->limit->Write(meta, b, 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, NULL, true, a, false)) {
|
||||
if (!limit->Write(meta, b, mn, NULL, true, a, false)) {
|
||||
if (!meta->cxt.E3compatibility)
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
}
|
||||
@ -104,7 +104,7 @@
|
||||
pc += sizeof(short);
|
||||
b = pop();
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->read(meta, &b, limit, mn, NULL, RunPhase, &a))
|
||||
if (!limit->Read(meta, &b, mn, NULL, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
push(b);
|
||||
push(a);
|
||||
@ -172,7 +172,7 @@
|
||||
indexVal = pop();
|
||||
b = pop();
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->bracketRead(meta, &b, limit, indexVal, RunPhase, &a))
|
||||
if (!limit->BracketRead(meta, &b, indexVal, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
push(a);
|
||||
indexVal = JS2VAL_VOID;
|
||||
@ -185,7 +185,7 @@
|
||||
b = pop();
|
||||
bool result;
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->bracketDelete(meta, b, limit, indexVal, &result))
|
||||
if (!limit->BracketDelete(meta, b, indexVal, &result))
|
||||
push(JS2VAL_FALSE);
|
||||
else
|
||||
push(BOOLEAN_TO_JS2VAL(result));
|
||||
@ -201,7 +201,7 @@
|
||||
indexVal = pop();
|
||||
b = pop();
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->bracketWrite(meta, b, limit, indexVal, a)) {
|
||||
if (!limit->BracketWrite(meta, b, indexVal, a)) {
|
||||
if (!meta->cxt.E3compatibility)
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
}
|
||||
@ -216,7 +216,7 @@
|
||||
indexVal = pop();
|
||||
b = top();
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->bracketRead(meta, &b, limit, indexVal, RunPhase, &a))
|
||||
if (!limit->BracketRead(meta, &b, indexVal, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
push(a);
|
||||
indexVal = JS2VAL_VOID;
|
||||
@ -232,7 +232,7 @@
|
||||
indexVal = STRING_TO_JS2VAL(astr);
|
||||
push(indexVal);
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->bracketRead(meta, &b, limit, indexVal, RunPhase, &a))
|
||||
if (!limit->BracketRead(meta, &b, indexVal, RunPhase, &a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), astr);
|
||||
push(a);
|
||||
indexVal = JS2VAL_VOID;
|
||||
@ -248,7 +248,7 @@
|
||||
ASSERT(JS2VAL_IS_STRING(indexVal)); // because the readForRef above will have executed first
|
||||
b = pop();
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (!limit->bracketWrite(meta, b, limit, indexVal, a)) {
|
||||
if (!limit->BracketWrite(meta, b, indexVal, a)) {
|
||||
if (!meta->cxt.E3compatibility)
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), JS2VAL_TO_STRING(indexVal));
|
||||
}
|
||||
|
@ -968,10 +968,10 @@
|
||||
pc += sizeof(short);
|
||||
baseVal = pop();
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a))
|
||||
if (!limit->Read(meta, &baseVal, 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, NULL, true, allocNumber(num + 1.0), false))
|
||||
if (!limit->Write(meta, baseVal, mn, NULL, true, allocNumber(num + 1.0), false))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
pushNumber(num);
|
||||
baseVal = JS2VAL_VOID;
|
||||
@ -983,10 +983,10 @@
|
||||
pc += sizeof(short);
|
||||
baseVal = pop();
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a))
|
||||
if (!limit->Read(meta, &baseVal, 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, NULL, true, allocNumber(num - 1.0), false))
|
||||
if (!limit->Write(meta, baseVal, mn, NULL, true, allocNumber(num - 1.0), false))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
pushNumber(num);
|
||||
baseVal = JS2VAL_VOID;
|
||||
@ -998,11 +998,11 @@
|
||||
pc += sizeof(short);
|
||||
baseVal = pop();
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a))
|
||||
if (!limit->Read(meta, &baseVal, 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, NULL, true, a, false))
|
||||
if (!limit->Write(meta, baseVal, mn, NULL, true, a, false))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
baseVal = JS2VAL_VOID;
|
||||
}
|
||||
@ -1013,11 +1013,11 @@
|
||||
pc += sizeof(short);
|
||||
baseVal = pop();
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a))
|
||||
if (!limit->Read(meta, &baseVal, 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, NULL, true, a, false))
|
||||
if (!limit->Write(meta, baseVal, mn, NULL, true, a, false))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name);
|
||||
baseVal = JS2VAL_VOID;
|
||||
}
|
||||
@ -1028,10 +1028,10 @@
|
||||
indexVal = pop();
|
||||
baseVal = pop();
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a))
|
||||
if (!limit->BracketRead(meta, &baseVal, 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, indexVal, allocNumber(num + 1.0)))
|
||||
if (!limit->BracketWrite(meta, baseVal, indexVal, allocNumber(num + 1.0)))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
pushNumber(num);
|
||||
baseVal = JS2VAL_VOID;
|
||||
@ -1043,10 +1043,10 @@
|
||||
indexVal = pop();
|
||||
baseVal = pop();
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a))
|
||||
if (!limit->BracketRead(meta, &baseVal, 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, indexVal, allocNumber(num - 1.0)))
|
||||
if (!limit->BracketWrite(meta, baseVal, indexVal, allocNumber(num - 1.0)))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
pushNumber(num);
|
||||
baseVal = JS2VAL_VOID;
|
||||
@ -1059,11 +1059,11 @@
|
||||
indexVal = pop();
|
||||
baseVal = pop();
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a))
|
||||
if (!limit->BracketRead(meta, &baseVal, 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, indexVal, a))
|
||||
if (!limit->BracketWrite(meta, baseVal, indexVal, a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
baseVal = JS2VAL_VOID;
|
||||
indexVal = JS2VAL_VOID;
|
||||
@ -1075,11 +1075,11 @@
|
||||
indexVal = pop();
|
||||
baseVal = pop();
|
||||
JS2Class *limit = meta->objectType(baseVal);
|
||||
if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a))
|
||||
if (!limit->BracketRead(meta, &baseVal, 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, indexVal, a))
|
||||
if (!limit->BracketWrite(meta, baseVal, indexVal, a))
|
||||
meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal));
|
||||
baseVal = JS2VAL_VOID;
|
||||
indexVal = JS2VAL_VOID;
|
||||
|
@ -66,7 +66,7 @@
|
||||
js2val protoVal = OBJECT_TO_JS2VAL(meta->objectClass->prototype);
|
||||
Multiname mn(prototype_StringAtom); // gc safe because the content is rooted elsewhere
|
||||
JS2Class *limit = meta->objectType(a);
|
||||
if (limit->read(meta, &a, limit, &mn, meta->env, RunPhase, &protoVal)) {
|
||||
if (limit->Read(meta, &a, &mn, meta->env, RunPhase, &protoVal)) {
|
||||
if (!JS2VAL_IS_OBJECT(protoVal))
|
||||
meta->reportError(Exception::badValueError, "Non-object prototype value", errorPos());
|
||||
}
|
||||
@ -158,7 +158,7 @@
|
||||
// Still need to mark the frame as a runtime frame (see stmtnode::return in validate)
|
||||
pFrame = new ParameterFrame(a, fWrap->compileFrame->prototype);
|
||||
pFrame->pluralFrame = fWrap->compileFrame;
|
||||
meta->env->addFrame(pFrame);
|
||||
meta->env->addFrame(pFrame, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -266,7 +266,7 @@
|
||||
if (obj->kind != ClassKind)
|
||||
meta->reportError(Exception::badValueError, "Type expected", errorPos());
|
||||
JS2Class *isClass = checked_cast<JS2Class *>(obj);
|
||||
push(isClass->is(meta, a, isClass));
|
||||
push(isClass->Is(meta, a));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -292,7 +292,7 @@
|
||||
js2val b_protoVal;
|
||||
Multiname mn(prototype_StringAtom); // gc safe because the content is rooted elsewhere
|
||||
JS2Class *limit = meta->objectType(b);
|
||||
if (limit->read(meta, &b, limit, &mn, meta->env, RunPhase, &b_protoVal)) {
|
||||
if (limit->Read(meta, &b, &mn, meta->env, RunPhase, &b_protoVal)) {
|
||||
if (!JS2VAL_IS_OBJECT(b_protoVal))
|
||||
meta->reportError(Exception::typeError, "Non-object prototype value in instanceOf", errorPos());
|
||||
}
|
||||
@ -360,6 +360,6 @@
|
||||
JS2Class *c = BytecodeContainer::getType(pc);
|
||||
pc += sizeof(JS2Class *);
|
||||
a = pop();
|
||||
push(c->implicitCoerce(meta, a, c));
|
||||
push(c->ImplicitCoerce(meta, a));
|
||||
}
|
||||
break;
|
||||
|
@ -111,30 +111,36 @@
|
||||
|
||||
case eThis: // XXX literal?
|
||||
{
|
||||
if (!meta->env->findThis(meta, true, &a) || JS2VAL_IS_INACCESSIBLE(a))
|
||||
pFrame = meta->env->getEnclosingParameterFrame();
|
||||
if ((pFrame == NULL) || JS2VAL_IS_INACCESSIBLE(pFrame->thisObject))
|
||||
a = OBJECT_TO_JS2VAL(meta->env->getPackageFrame());
|
||||
// meta->reportError(Exception::compileExpressionError, "'this' not available", errorPos());
|
||||
else
|
||||
a = pFrame->thisObject;
|
||||
push(a);
|
||||
pFrame = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case eSuper: // XXX literal?
|
||||
{
|
||||
if (!meta->env->findThis(meta, false, &a))
|
||||
ASSERT(false);
|
||||
pFrame = meta->env->getEnclosingParameterFrame();
|
||||
ASSERT(pFrame);
|
||||
a = pFrame->thisObject;
|
||||
if (JS2VAL_IS_INACCESSIBLE(a))
|
||||
meta->reportError(Exception::compileExpressionError, "'this' not available for 'super'", errorPos());
|
||||
makeLimitedInstance:
|
||||
{
|
||||
JS2Class *limit = meta->env->getEnclosingClass()->super;
|
||||
ASSERT(limit);
|
||||
a = limit->implicitCoerce(meta, a, limit);
|
||||
a = limit->ImplicitCoerce(meta, a);
|
||||
ASSERT(JS2VAL_IS_OBJECT(a));
|
||||
if (JS2VAL_IS_NULL(a))
|
||||
push(JS2VAL_NULL);
|
||||
else
|
||||
push(OBJECT_TO_JS2VAL(new LimitedInstance(JS2VAL_TO_OBJECT(a), limit)));
|
||||
}
|
||||
pFrame = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -62,30 +62,30 @@ namespace MetaData {
|
||||
|
||||
void RegExpInstance::setLastIndex(JS2Metadata *meta, js2val a)
|
||||
{
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, meta->engine->allocStringPtr("lastIndex"), true, a);
|
||||
meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->engine->allocStringPtr("lastIndex"), true, a);
|
||||
}
|
||||
void RegExpInstance::setGlobal(JS2Metadata *meta, js2val a)
|
||||
{
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, meta->engine->allocStringPtr("global"), true, a);
|
||||
meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->engine->allocStringPtr("global"), true, a);
|
||||
}
|
||||
void RegExpInstance::setMultiline(JS2Metadata *meta, js2val a)
|
||||
{
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, meta->engine->allocStringPtr("multiline"), true, a);
|
||||
meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->engine->allocStringPtr("multiline"), true, a);
|
||||
}
|
||||
void RegExpInstance::setIgnoreCase(JS2Metadata *meta, js2val a)
|
||||
{
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, meta->engine->allocStringPtr("ignoreCase"), true, a);
|
||||
meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->engine->allocStringPtr("ignoreCase"), true, a);
|
||||
}
|
||||
void RegExpInstance::setSource(JS2Metadata *meta, js2val a)
|
||||
{
|
||||
meta->regexpClass->writePublic(meta, OBJECT_TO_JS2VAL(this), meta->regexpClass, meta->engine->allocStringPtr("source"), true, a);
|
||||
meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->engine->allocStringPtr("source"), true, a);
|
||||
}
|
||||
|
||||
js2val RegExpInstance::getLastIndex(JS2Metadata *meta)
|
||||
{
|
||||
js2val r;
|
||||
js2val thisVal = OBJECT_TO_JS2VAL(this);
|
||||
if (!meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, meta->engine->allocStringPtr("lastIndex"), RunPhase, &r))
|
||||
if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->engine->allocStringPtr("lastIndex"), RunPhase, &r))
|
||||
ASSERT(false);
|
||||
return r;
|
||||
}
|
||||
@ -93,7 +93,7 @@ namespace MetaData {
|
||||
{
|
||||
js2val r;
|
||||
js2val thisVal = OBJECT_TO_JS2VAL(this);
|
||||
if (!meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, meta->engine->allocStringPtr("global"), RunPhase, &r))
|
||||
if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->engine->allocStringPtr("global"), RunPhase, &r))
|
||||
ASSERT(false);
|
||||
return r;
|
||||
}
|
||||
@ -101,7 +101,7 @@ namespace MetaData {
|
||||
{
|
||||
js2val r;
|
||||
js2val thisVal = OBJECT_TO_JS2VAL(this);
|
||||
if (!meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, meta->engine->allocStringPtr("multiline"), RunPhase, &r))
|
||||
if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->engine->allocStringPtr("multiline"), RunPhase, &r))
|
||||
ASSERT(false);
|
||||
return r;
|
||||
}
|
||||
@ -109,7 +109,7 @@ namespace MetaData {
|
||||
{
|
||||
js2val r;
|
||||
js2val thisVal = OBJECT_TO_JS2VAL(this);
|
||||
if (!meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, meta->engine->allocStringPtr("ignoreCase"), RunPhase, &r))
|
||||
if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->engine->allocStringPtr("ignoreCase"), RunPhase, &r))
|
||||
ASSERT(false);
|
||||
return r;
|
||||
}
|
||||
@ -117,7 +117,7 @@ namespace MetaData {
|
||||
{
|
||||
js2val r;
|
||||
js2val thisVal = OBJECT_TO_JS2VAL(this);
|
||||
if (!meta->regexpClass->readPublic(meta, &thisVal, meta->regexpClass, meta->engine->allocStringPtr("source"), RunPhase, &r))
|
||||
if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->engine->allocStringPtr("source"), RunPhase, &r))
|
||||
ASSERT(false);
|
||||
return r;
|
||||
}
|
||||
@ -193,11 +193,11 @@ namespace MetaData {
|
||||
meta->createDynamicProperty(A, meta->engine->allocStringPtr("index"), meta->engine->allocNumber((float64)(match->startIndex)), ReadWriteAccess, false, true);
|
||||
meta->createDynamicProperty(A, meta->engine->allocStringPtr("input"), meta->engine->allocString(str), ReadWriteAccess, false, true);
|
||||
|
||||
meta->stringClass->writePublic(meta, OBJECT_TO_JS2VAL(meta->regexpClass), meta->stringClass, meta->engine->allocStringPtr("lastMatch"), true, matchStr);
|
||||
meta->stringClass->WritePublic(meta, OBJECT_TO_JS2VAL(meta->regexpClass), meta->engine->allocStringPtr("lastMatch"), true, matchStr);
|
||||
js2val leftContextVal = meta->engine->allocString(str->substr(0, (uint32)match->startIndex));
|
||||
meta->stringClass->writePublic(meta, OBJECT_TO_JS2VAL(meta->regexpClass), meta->stringClass, meta->engine->allocStringPtr("leftContext"), true, matchStr);
|
||||
meta->stringClass->WritePublic(meta, OBJECT_TO_JS2VAL(meta->regexpClass), meta->engine->allocStringPtr("leftContext"), true, matchStr);
|
||||
js2val rightContextVal = meta->engine->allocString(str->substr((uint32)match->endIndex, (uint32)str->length() - match->endIndex));
|
||||
meta->stringClass->writePublic(meta, OBJECT_TO_JS2VAL(meta->regexpClass), meta->stringClass, meta->engine->allocStringPtr("rightContext"), true, matchStr);
|
||||
meta->stringClass->WritePublic(meta, OBJECT_TO_JS2VAL(meta->regexpClass), meta->engine->allocStringPtr("rightContext"), true, matchStr);
|
||||
|
||||
if (meta->toBoolean(thisInst->getGlobal(meta))) {
|
||||
index = match->endIndex;
|
||||
@ -255,7 +255,7 @@ namespace MetaData {
|
||||
meta->reportError(Exception::syntaxError, "Failed to parse RegExp : '{0}'", meta->engine->errorPos(), *regexpStr + "/" + *flagStr); // XXX error message?
|
||||
}
|
||||
}
|
||||
JSRegExp *re = RECompile(meta, regexpStr->begin(), (int32)regexpStr->length(), flags);
|
||||
JS2RegExp *re = RECompile(meta, regexpStr->begin(), (int32)regexpStr->length(), flags);
|
||||
if (re) {
|
||||
thisInst->mRegExp = re;
|
||||
// XXX ECMA spec says these are DONTENUM
|
||||
|
@ -131,7 +131,7 @@ static js2val String_search(JS2Metadata *meta, const js2val thisValue, js2val *a
|
||||
regexp = JS2VAL_NULL;
|
||||
regexp = RegExp_Constructor(meta, regexp, argv, 1);
|
||||
}
|
||||
JSRegExp *re = (checked_cast<RegExpInstance *>(JS2VAL_TO_OBJECT(regexp)))->mRegExp;
|
||||
JS2RegExp *re = (checked_cast<RegExpInstance *>(JS2VAL_TO_OBJECT(regexp)))->mRegExp;
|
||||
|
||||
REMatchResult *match = REExecute(meta, re, str->begin(), 0, (int32)str->length(), false);
|
||||
if (match)
|
||||
@ -167,7 +167,7 @@ static js2val String_match(JS2Metadata *meta, const js2val thisValue, js2val *ar
|
||||
|
||||
RegExpInstance *thisInst = checked_cast<RegExpInstance *>(JS2VAL_TO_OBJECT(regexp));
|
||||
DEFINE_ROOTKEEPER(rk1, thisInst);
|
||||
JSRegExp *re = thisInst->mRegExp;
|
||||
JS2RegExp *re = thisInst->mRegExp;
|
||||
if ((re->flags & JSREG_GLOB) == 0) {
|
||||
return RegExp_exec(meta, regexp, &S, 1);
|
||||
}
|
||||
@ -185,7 +185,7 @@ static js2val String_match(JS2Metadata *meta, const js2val thisValue, js2val *ar
|
||||
else
|
||||
lastIndex = match->endIndex;
|
||||
js2val matchStr = meta->engine->allocString(JS2VAL_TO_STRING(S)->substr(toUInt32(match->startIndex), toUInt32(match->endIndex) - match->startIndex));
|
||||
meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(A), meta->arrayClass, meta->engine->numberToString(index), true, matchStr);
|
||||
meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToString(index), true, matchStr);
|
||||
index++;
|
||||
}
|
||||
thisInst->setLastIndex(meta, meta->engine->allocNumber((float64)lastIndex));
|
||||
@ -280,7 +280,7 @@ static js2val String_replace(JS2Metadata *meta, const js2val thisValue, js2val *
|
||||
|
||||
if (meta->objectType(searchValue) != meta->regexpClass) {
|
||||
RegExpInstance *reInst = checked_cast<RegExpInstance *>(JS2VAL_TO_OBJECT(searchValue));
|
||||
JSRegExp *re = reInst->mRegExp;
|
||||
JS2RegExp *re = reInst->mRegExp;
|
||||
REMatchResult *match;
|
||||
String newString;
|
||||
int32 lastIndex = 0;
|
||||
@ -380,7 +380,7 @@ static void strSplitMatch(const String *S, uint32 q, const String *R, MatchResul
|
||||
result.failure = false;
|
||||
}
|
||||
|
||||
static void regexpSplitMatch(JS2Metadata *meta, const String *S, uint32 q, JSRegExp *RE, MatchResult &result)
|
||||
static void regexpSplitMatch(JS2Metadata *meta, const String *S, uint32 q, JS2RegExp *RE, MatchResult &result)
|
||||
{
|
||||
result.failure = true;
|
||||
result.captures = NULL;
|
||||
@ -388,7 +388,7 @@ static void regexpSplitMatch(JS2Metadata *meta, const String *S, uint32 q, JSReg
|
||||
REMatchResult *match = REMatch(meta, RE, S->begin() + q, (int32)(S->length() - q));
|
||||
|
||||
if (match) {
|
||||
result.endIndex = match->startIndex + q;
|
||||
result.endIndex = match->endIndex + q;
|
||||
result.failure = false;
|
||||
result.capturesCount = toUInt32(match->parenCount);
|
||||
if (match->parenCount) {
|
||||
@ -427,7 +427,7 @@ static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *ar
|
||||
uint32 s = S->size();
|
||||
uint32 p = 0;
|
||||
|
||||
JSRegExp *RE = NULL;
|
||||
JS2RegExp *RE = NULL;
|
||||
const String *R = NULL;
|
||||
if (meta->objectType(separatorV) == meta->regexpClass)
|
||||
RE = (checked_cast<RegExpInstance *>(JS2VAL_TO_OBJECT(separatorV)))->mRegExp;
|
||||
@ -452,7 +452,7 @@ static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *ar
|
||||
strSplitMatch(S, 0, R, z);
|
||||
if (!z.failure)
|
||||
return result;
|
||||
meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(A), meta->arrayClass, meta->engine->numberToString((int32)0), true, STRING_TO_JS2VAL(S));
|
||||
meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToString((int32)0), true, STRING_TO_JS2VAL(S));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -464,7 +464,7 @@ static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *ar
|
||||
step11:
|
||||
if (q == s) {
|
||||
js2val v = meta->engine->allocString(S, p, (s - p));
|
||||
meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(A), meta->arrayClass, meta->engine->numberToString(getLength(meta, A)), true, v);
|
||||
meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToString(getLength(meta, A)), true, v);
|
||||
return result;
|
||||
}
|
||||
MatchResult z;
|
||||
@ -483,13 +483,13 @@ step11:
|
||||
}
|
||||
T = meta->engine->allocStringPtr(S, p, (q - p)); // XXX
|
||||
js2val v = STRING_TO_JS2VAL(T);
|
||||
meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(A), meta->arrayClass, meta->engine->numberToString(getLength(meta, A)), true, v);
|
||||
meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToString(getLength(meta, A)), true, v);
|
||||
if (getLength(meta, A) == lim)
|
||||
return result;
|
||||
p = e;
|
||||
|
||||
for (uint32 i = 0; i < z.capturesCount; i++) {
|
||||
meta->arrayClass->writePublic(meta, OBJECT_TO_JS2VAL(A), meta->arrayClass, meta->engine->numberToString(getLength(meta, A)), true, z.captures[i]);
|
||||
meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToString(getLength(meta, A)), true, z.captures[i]);
|
||||
if (getLength(meta, A) == lim)
|
||||
return result;
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ typedef struct REBackTrackData {
|
||||
|
||||
typedef struct REGlobalData {
|
||||
JSBool globalMultiline;
|
||||
JSRegExp *regexp; /* the RE in execution */
|
||||
JS2RegExp *regexp; /* the RE in execution */
|
||||
JSBool ok; /* runtime error (out_of_memory only?) */
|
||||
size_t start; /* offset to start at */
|
||||
ptrdiff_t skipped; /* chars skipped anchoring this r.e. */
|
||||
@ -1318,7 +1318,7 @@ typedef struct {
|
||||
} EmitStateStackEntry;
|
||||
|
||||
static jsbytecode *
|
||||
emitREBytecode(CompilerState *state, JSRegExp *re, intN treeDepth,
|
||||
emitREBytecode(CompilerState *state, JS2RegExp *re, intN treeDepth,
|
||||
jsbytecode *pc, RENode *t)
|
||||
{
|
||||
ptrdiff_t diff;
|
||||
@ -1941,7 +1941,7 @@ lexHex:
|
||||
}
|
||||
|
||||
void
|
||||
js_DestroyRegExp(JSRegExp *re)
|
||||
js_DestroyRegExp(JS2RegExp *re)
|
||||
{
|
||||
uintN i;
|
||||
if (re->classList) {
|
||||
@ -2172,7 +2172,7 @@ static REMatchState *simpleMatch(REGlobalData *gData, REMatchState *x,
|
||||
}
|
||||
|
||||
static REMatchState *
|
||||
executeREBytecode(REGlobalData *gData, REMatchState *x)
|
||||
executeREBytecode(REGlobalData *gData, REMatchState *x, JSBool allowSkip)
|
||||
{
|
||||
REMatchState *result;
|
||||
REBackTrackData *backTrackData;
|
||||
@ -2197,7 +2197,7 @@ executeREBytecode(REGlobalData *gData, REMatchState *x)
|
||||
* the string until that match is made, or fail if it can't be
|
||||
* found at all.
|
||||
*/
|
||||
if (REOP_IS_SIMPLE(op)) {
|
||||
if (allowSkip && REOP_IS_SIMPLE(op)) {
|
||||
anchor = JS_FALSE;
|
||||
while (x->cp <= gData->cpend) {
|
||||
nextpc = pc; /* reset back to start each time */
|
||||
@ -2734,7 +2734,7 @@ MatchRegExp(REGlobalData *gData, REMatchState *x)
|
||||
x->cp = cp2;
|
||||
for (j = 0; j < gData->regexp->parenCount; j++)
|
||||
x->parens[j].index = -1;
|
||||
result = executeREBytecode(gData, x);
|
||||
result = executeREBytecode(gData, x, true);
|
||||
if (!gData->ok || result)
|
||||
return result;
|
||||
gData->backTrackSP = gData->backTrackStack;
|
||||
@ -2747,7 +2747,7 @@ MatchRegExp(REGlobalData *gData, REMatchState *x)
|
||||
|
||||
|
||||
static REMatchState *
|
||||
initMatch(REGlobalData *gData, JSRegExp *re)
|
||||
initMatch(REGlobalData *gData, JS2RegExp *re)
|
||||
{
|
||||
REMatchState *result;
|
||||
uintN i;
|
||||
@ -2787,7 +2787,7 @@ initMatch(REGlobalData *gData, JSRegExp *re)
|
||||
* Call the recursive matcher to do the real work. Return null on mismatch.
|
||||
* On match, return the completed MatchResult structure.
|
||||
*/
|
||||
REMatchResult *REExecute(JS2Metadata *meta, JSRegExp *re, const jschar *str, uint32 index, uint32 length, bool globalMultiline)
|
||||
REMatchResult *REExecute(JS2Metadata *meta, JS2RegExp *re, const jschar *str, uint32 index, uint32 length, bool globalMultiline)
|
||||
{
|
||||
REGlobalData gData;
|
||||
REMatchState *x, *result;
|
||||
@ -2826,7 +2826,7 @@ REMatchResult *REExecute(JS2Metadata *meta, JSRegExp *re, const jschar *str, uin
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
REMatchResult *REMatch(JS2Metadata *meta, JSRegExp *re, const jschar *str, uint32 length)
|
||||
REMatchResult *REMatch(JS2Metadata *meta, JS2RegExp *re, const jschar *str, uint32 length)
|
||||
{
|
||||
REGlobalData gData;
|
||||
REMatchState *x, *result;
|
||||
@ -2847,7 +2847,7 @@ REMatchResult *REMatch(JS2Metadata *meta, JSRegExp *re, const jschar *str, uint3
|
||||
|
||||
for (j = 0; j < re->parenCount; j++)
|
||||
x->parens[j].index = -1;
|
||||
result = executeREBytecode(&gData, x);
|
||||
result = executeREBytecode(&gData, x, false);
|
||||
if (!gData.ok)
|
||||
return NULL;
|
||||
if (!result)
|
||||
@ -2887,9 +2887,9 @@ bool parseFlags(JS2Metadata *meta, const jschar *flagStr, uint32 length, uint32
|
||||
#define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y))
|
||||
|
||||
// Compile the source re, return NULL for failure (error functions called)
|
||||
JSRegExp *RECompile(JS2Metadata *meta, const jschar *str, uint32 length, uint32 flags)
|
||||
JS2RegExp *RECompile(JS2Metadata *meta, const jschar *str, uint32 length, uint32 flags)
|
||||
{
|
||||
JSRegExp *re;
|
||||
JS2RegExp *re;
|
||||
CompilerState state;
|
||||
size_t resize;
|
||||
jsbytecode *endPC;
|
||||
@ -2915,7 +2915,7 @@ JSRegExp *RECompile(JS2Metadata *meta, const jschar *str, uint32 length, uint32
|
||||
goto out;
|
||||
|
||||
resize = sizeof *re + state.progLength + 1;
|
||||
re = (JSRegExp *) malloc(JS_ROUNDUP(resize, sizeof(uint32)));
|
||||
re = (JS2RegExp *) malloc(JS_ROUNDUP(resize, sizeof(uint32)));
|
||||
if (!re)
|
||||
goto out;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user