Moevd access dispatch to classes, fixed E3 bugs

This commit is contained in:
rogerl%netscape.com 2003-05-14 23:06:28 +00:00
parent 5cee333241
commit 3134aa4bd3
12 changed files with 313 additions and 323 deletions

View File

@ -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));

View File

@ -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

View File

@ -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);
}

View File

@ -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));
}
}

View File

@ -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() { }
};

View File

@ -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));
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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;