Moved pond and rootlist into Metadata

This commit is contained in:
rogerl%netscape.com 2003-06-04 22:58:22 +00:00
Родитель 8c39557c8a
Коммит 7817956d1f
20 изменённых файлов: 537 добавлений и 465 удалений

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

@ -84,6 +84,13 @@ class JS2Object;
class Frame;
class RegExpInstance;
class StashedMultiname {
public:
uint16 stringIndex; // the name
uint16 namespaceCount; //
uint16 *namespaceList; // if null and count is 1, it's the public namespace.
};
class BytecodeContainer {
public:
BytecodeContainer() : mStackTop(0), mStackMax(0)

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

@ -448,7 +448,7 @@ js2val dumpAt(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], ui
js2val forceGC(JS2Metadata *meta, const js2val /* thisValue */, js2val /* argv */ [], uint32 /* argc */)
{
JS2Object::gc();
meta->gc();
return JS2VAL_VOID;
}
@ -459,7 +459,7 @@ js2val load(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint
if (argc) {
// Save off the current top frame and root it.
Environment *curEnv = meta->env;
DEFINE_ROOTKEEPER(rk, curEnv);
DEFINE_ROOTKEEPER(meta, rk, curEnv);
// Set the environment to global object and system frame so that the
// load happens into the top frame.
meta->env = new Environment(curEnv->getSystemFrame(), curEnv->getPackageFrame());
@ -493,8 +493,12 @@ int main(int argc, char **argv)
stdOut << "Welcome to Epimetheus.\n";
#endif
DEFINE_ROOTKEEPER(rk, metadata);
metadata = new MetaData::JS2Metadata(*world);
delete metadata;
world->identifiers.clear();
delete world;
world = new World();
metadata = new MetaData::JS2Metadata(*world);
metadata->addGlobalObjectFunction("print", print, 1);

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

@ -89,9 +89,9 @@ js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 newLength)
js2val Array_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val *argv, uint32 argc)
{
js2val thatValue = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
js2val thatValue = OBJECT_TO_JS2VAL(new (meta) ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
ArrayInstance *arrInst = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(thatValue));
DEFINE_ROOTKEEPER(rk, arrInst);
DEFINE_ROOTKEEPER(meta, rk, arrInst);
if (argc > 0) {
if (argc == 1) {
if (JS2VAL_IS_NUMBER(argv[0])) {
@ -230,9 +230,9 @@ js2val Array_concat(JS2Metadata *meta, const js2val thisValue, js2val *argv, uin
{
js2val E = thisValue;
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
js2val result = OBJECT_TO_JS2VAL(new (meta) ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
DEFINE_ROOTKEEPER(rk, A);
DEFINE_ROOTKEEPER(meta, rk, A);
uint32 n = 0;
uint32 i = 0;
@ -265,7 +265,7 @@ static js2val Array_join(JS2Metadata *meta, const js2val thisValue, js2val *argv
uint32 length = getLength(meta, thisObj);
const String *separator = NULL;
DEFINE_ROOTKEEPER(rk1, separator);
DEFINE_ROOTKEEPER(meta, rk1, separator);
if ((argc == 0) || JS2VAL_IS_UNDEFINED(argv[0]))
separator = meta->engine->allocStringPtr(",");
else
@ -298,10 +298,10 @@ static js2val Array_reverse(JS2Metadata *meta, const js2val thisValue, js2val *
JS2Class *c = meta->objectType(thisObj);
// XXX Need to root the Strings somewhere, this'll do for now..
Multiname *mn1 = new Multiname(meta->publicNamespace);
Multiname *mn2 = new Multiname(meta->publicNamespace);
DEFINE_ROOTKEEPER(rk1, mn1);
DEFINE_ROOTKEEPER(rk2, mn2);
Multiname *mn1 = new (meta) Multiname(meta->publicNamespace);
Multiname *mn2 = new (meta) Multiname(meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk1, mn1);
DEFINE_ROOTKEEPER(meta, rk2, mn2);
for (uint32 k = 0; k < halfway; k++) {
bool deleteResult;
@ -353,10 +353,10 @@ static js2val Array_shift(JS2Metadata *meta, const js2val thisValue, js2val * /*
JS2Class *c = meta->objectType(thisObj);
// XXX Need to root the Strings somewhere, this'll do for now..
Multiname *mn1 = new Multiname(meta->publicNamespace);
Multiname *mn2 = new Multiname(meta->publicNamespace);
DEFINE_ROOTKEEPER(rk1, mn1);
DEFINE_ROOTKEEPER(rk2, mn2);
Multiname *mn1 = new (meta) Multiname(meta->publicNamespace);
Multiname *mn2 = new (meta) Multiname(meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk1, mn1);
DEFINE_ROOTKEEPER(meta, rk2, mn2);
js2val result;
bool deleteResult;
@ -387,9 +387,9 @@ static js2val Array_slice(JS2Metadata *meta, const js2val thisValue, js2val *arg
ASSERT(JS2VAL_IS_OBJECT(thatValue));
JS2Object *thisObj = JS2VAL_TO_OBJECT(thatValue);
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
js2val result = OBJECT_TO_JS2VAL(new (meta) ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
DEFINE_ROOTKEEPER(rk, A);
DEFINE_ROOTKEEPER(meta, rk, A);
uint32 length = getLength(meta, thisObj);
@ -434,10 +434,10 @@ static js2val Array_slice(JS2Metadata *meta, const js2val thisValue, js2val *arg
JS2Class *c = meta->objectType(thisObj);
// XXX Need to root the Strings somewhere, this'll do for now..
Multiname *mn1 = new Multiname(meta->publicNamespace);
Multiname *mn2 = new Multiname(meta->publicNamespace);
DEFINE_ROOTKEEPER(rk1, mn1);
DEFINE_ROOTKEEPER(rk2, mn2);
Multiname *mn1 = new (meta) Multiname(meta->publicNamespace);
Multiname *mn2 = new (meta) Multiname(meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk1, mn1);
DEFINE_ROOTKEEPER(meta, rk2, mn2);
uint32 n = 0;
while (start < end) {
mn1->name = meta->engine->numberToString(start);
@ -545,9 +545,9 @@ static int32 sort_compare(js2val *a, js2val *b, CompareArgs *arg)
}
else {
const String *astr = meta->toString(av);
DEFINE_ROOTKEEPER(rk1, astr);
DEFINE_ROOTKEEPER(meta, rk1, astr);
const String *bstr = meta->toString(bv);
DEFINE_ROOTKEEPER(rk2, bstr);
DEFINE_ROOTKEEPER(meta, rk2, bstr);
result = astr->compare(*bstr);
}
return result;
@ -596,7 +596,7 @@ static js2val Array_sort(JS2Metadata *meta, const js2val thisValue, js2val *argv
meta->reportError(Exception::internalError, "out of memory", meta->engine->errorPos());
js2val *vec = new js2val[length];
DEFINE_ARRAYROOTKEEPER(rk, vec, length);
DEFINE_ARRAYROOTKEEPER(meta, rk, vec, length);
JS2Class *c = meta->objectType(thisObj);
for (i = 0; i < length; i++) {
@ -621,9 +621,9 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar
JS2Object *thisObj = JS2VAL_TO_OBJECT(thatValue);
uint32 length = getLength(meta, thisObj);
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
js2val result = OBJECT_TO_JS2VAL(new (meta) ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
DEFINE_ROOTKEEPER(rk, A);
DEFINE_ROOTKEEPER(meta, rk, A);
int32 arg0 = meta->valToInt32(argv[0]);
uint32 start;
@ -653,10 +653,10 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar
JS2Class *c = meta->objectType(thisObj);
// XXX Need to root the Strings somewhere, this'll do for now..
Multiname *mn1 = new Multiname(meta->publicNamespace);
Multiname *mn2 = new Multiname(meta->publicNamespace);
DEFINE_ROOTKEEPER(rk1, mn1);
DEFINE_ROOTKEEPER(rk2, mn2);
Multiname *mn1 = new (meta) Multiname(meta->publicNamespace);
Multiname *mn2 = new (meta) Multiname(meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk1, mn1);
DEFINE_ROOTKEEPER(meta, rk2, mn2);
for (k = 0; k < deleteCount; k++) {
mn1->name = meta->engine->numberToString(start + k);
@ -726,10 +726,10 @@ static js2val Array_unshift(JS2Metadata *meta, const js2val thisValue, js2val *a
JS2Class *c = meta->objectType(thisObj);
// XXX Need to root the Strings somewhere, this'll do for now..
Multiname *mn1 = new Multiname(meta->publicNamespace);
Multiname *mn2 = new Multiname(meta->publicNamespace);
DEFINE_ROOTKEEPER(rk1, mn1);
DEFINE_ROOTKEEPER(rk2, mn2);
Multiname *mn1 = new (meta) Multiname(meta->publicNamespace);
Multiname *mn2 = new (meta) Multiname(meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk1, mn1);
DEFINE_ROOTKEEPER(meta, rk2, mn2);
for (k = length; k > 0; k--) {
bool deleteResult;
@ -776,7 +776,7 @@ void initArrayObject(JS2Metadata *meta)
};
meta->initBuiltinClass(meta->arrayClass, NULL, Array_Constructor, Array_Constructor);
meta->arrayClass->prototype = OBJECT_TO_JS2VAL(new ArrayInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->arrayClass));
meta->arrayClass->prototype = OBJECT_TO_JS2VAL(new (meta) ArrayInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->arrayClass));
meta->initBuiltinClassPrototype(meta->arrayClass, &prototypeFunctions[0]);
}

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

@ -57,9 +57,9 @@ namespace MetaData {
js2val Boolean_Constructor(JS2Metadata *meta, const js2val thisValue, js2val argv[], uint32 argc)
{
js2val thatValue = OBJECT_TO_JS2VAL(new BooleanInstance(meta, meta->booleanClass->prototype, meta->booleanClass));
js2val thatValue = OBJECT_TO_JS2VAL(new (meta) BooleanInstance(meta, meta->booleanClass->prototype, meta->booleanClass));
BooleanInstance *boolInst = checked_cast<BooleanInstance *>(JS2VAL_TO_OBJECT(thatValue));
DEFINE_ROOTKEEPER(rk, boolInst);
DEFINE_ROOTKEEPER(meta, rk, boolInst);
if (argc > 0)
boolInst->mValue = meta->toBoolean(argv[0]);
@ -106,7 +106,7 @@ namespace MetaData {
};
meta->initBuiltinClass(meta->booleanClass, NULL, Boolean_Constructor, Boolean_Call);
meta->booleanClass->prototype = OBJECT_TO_JS2VAL(new BooleanInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->booleanClass));
meta->booleanClass->prototype = OBJECT_TO_JS2VAL(new (meta) BooleanInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->booleanClass));
meta->initBuiltinClassPrototype(meta->booleanClass, &prototypeFunctions[0]);
}

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

@ -870,9 +870,9 @@ js2val Date_Call(JS2Metadata *meta, const js2val /* thisValue */, js2val *argv,
#define MAXARGS 7
js2val Date_Constructor(JS2Metadata *meta, const js2val /* thisValue */, js2val *argv, uint32 argc)
{
js2val thatValue = OBJECT_TO_JS2VAL(new DateInstance(meta, meta->dateClass->prototype, meta->dateClass));
js2val thatValue = OBJECT_TO_JS2VAL(new (meta) DateInstance(meta, meta->dateClass->prototype, meta->dateClass));
DateInstance *thisInst = checked_cast<DateInstance *>(JS2VAL_TO_OBJECT(thatValue));
DEFINE_ROOTKEEPER(rk, thisInst);
DEFINE_ROOTKEEPER(meta, rk, thisInst);
/* Date called as constructor */
if (argc == 0) {
@ -1481,7 +1481,7 @@ void initDateObject(JS2Metadata *meta)
LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond);
meta->initBuiltinClass(meta->dateClass, &staticFunctions[0], Date_Constructor, Date_Call);
DateInstance *ur = new DateInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->dateClass);
DateInstance *ur = new (meta) DateInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->dateClass);
meta->dateClass->prototype = OBJECT_TO_JS2VAL(ur);
ur->ms = 0;
meta->initBuiltinClassPrototype(meta->dateClass, &prototypeFunctions[0]);

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

@ -93,14 +93,14 @@ namespace MetaData {
ParameterFrame *pFrame = NULL;
const String *astr = NULL;
const String *bstr = NULL;
DEFINE_ROOTKEEPER(rk1, pFrame);
DEFINE_ROOTKEEPER(rk2, astr);
DEFINE_ROOTKEEPER(rk3, bstr);
DEFINE_ROOTKEEPER(meta, rk1, pFrame);
DEFINE_ROOTKEEPER(meta, rk2, astr);
DEFINE_ROOTKEEPER(meta, rk3, bstr);
DEFINE_ROOTKEEPER(rk4, a);
DEFINE_ROOTKEEPER(rk5, b);
DEFINE_ROOTKEEPER(rk6, baseVal);
DEFINE_ROOTKEEPER(rk7, indexVal);
DEFINE_ROOTKEEPER(meta, rk4, a);
DEFINE_ROOTKEEPER(meta, rk5, b);
DEFINE_ROOTKEEPER(meta, rk6, baseVal);
DEFINE_ROOTKEEPER(meta, rk7, indexVal);
retval = JS2VAL_VOID;
while (true) {
@ -211,7 +211,7 @@ namespace MetaData {
// If not, fill the table or return a un-hashed pointer
float64 *JS2Engine::newDoubleValue(float64 x)
{
float64 *p = (float64 *)JS2Object::alloc(sizeof(float64), PondScum::GenericFlag);
float64 *p = (float64 *)meta->alloc(sizeof(float64), PondScum::GenericFlag);
*p = x;
return p;
@ -243,7 +243,7 @@ namespace MetaData {
String *JS2Engine::allocStringPtr(const char *s)
{
String *p = (String *)(JS2Object::alloc(sizeof(String), PondScum::StringFlag));
String *p = (String *)(meta->alloc(sizeof(String), PondScum::StringFlag));
size_t len = strlen(s);
String *result = new (p) String(len, uni::null);
for (int i = 0; i < len; i++) {
@ -255,26 +255,26 @@ namespace MetaData {
String *JS2Engine::allocStringPtr(const char16 *s, uint32 length)
{
String *p = (String *)(JS2Object::alloc(sizeof(String), PondScum::StringFlag));
String *p = (String *)(meta->alloc(sizeof(String), PondScum::StringFlag));
String *result = new (p) String(s, length);
return result;
}
String *JS2Engine::allocStringPtr(const String *s)
{
String *p = (String *)(JS2Object::alloc(sizeof(String), PondScum::StringFlag));
String *p = (String *)(meta->alloc(sizeof(String), PondScum::StringFlag));
return new (p) String(*s);
}
String *JS2Engine::allocStringPtr(const String *s, uint32 index, uint32 length)
{
String *p = (String *)(JS2Object::alloc(sizeof(String), PondScum::StringFlag));
String *p = (String *)(meta->alloc(sizeof(String), PondScum::StringFlag));
return new (p) String(*s, index, length);
}
String *JS2Engine::concatStrings(const String *s1, const String *s2)
{
String *p = (String *)(JS2Object::alloc(sizeof(String), PondScum::StringFlag));
String *p = (String *)(meta->alloc(sizeof(String), PondScum::StringFlag));
String *result = new (p) String(*s1);
result->append(*s2);
return result;
@ -299,7 +299,7 @@ namespace MetaData {
// Don't store as an int, even if possible, we need to retain 'longness'
js2val JS2Engine::allocULong(uint64 x)
{
uint64 *p = (uint64 *)(JS2Object::alloc(sizeof(uint64), PondScum::GenericFlag));
uint64 *p = (uint64 *)(meta->alloc(sizeof(uint64), PondScum::GenericFlag));
*p = x;
return ULONG_TO_JS2VAL(p);
@ -308,7 +308,7 @@ namespace MetaData {
// Don't store as an int, even if possible, we need to retain 'longness'
js2val JS2Engine::allocLong(int64 x)
{
int64 *p = (int64 *)(JS2Object::alloc(sizeof(int64), PondScum::GenericFlag));
int64 *p = (int64 *)(meta->alloc(sizeof(int64), PondScum::GenericFlag));
*p = x;
return LONG_TO_JS2VAL(p);
}
@ -316,7 +316,7 @@ namespace MetaData {
// Don't store as an int, even if possible, we need to retain 'floatness'
js2val JS2Engine::allocFloat(float32 x)
{
float32 *p = (float32 *)(JS2Object::alloc(sizeof(float32), PondScum::GenericFlag));
float32 *p = (float32 *)(meta->alloc(sizeof(float32), PondScum::GenericFlag));
*p = x;
return FLOAT_TO_JS2VAL(p);
}
@ -455,8 +455,8 @@ namespace MetaData {
#define INIT_STRINGATOM(n) n##_StringAtom(allocStringPtr(#n))
JS2Engine::JS2Engine(World &world)
: meta(NULL),
JS2Engine::JS2Engine(JS2Metadata *meta, World &world)
: meta(meta),
pc(NULL),
bCon(NULL),
phase(RunPhase),
@ -483,7 +483,7 @@ namespace MetaData {
for (int i = 0; i < 256; i++)
float64Table[i] = NULL;
float64 *p = (float64 *)JS2Object::alloc(sizeof(float64), PondScum::GenericFlag);
float64 *p = (float64 *)meta->alloc(sizeof(float64), PondScum::GenericFlag);
*p = nan;
nanValue = DOUBLE_TO_JS2VAL(p);
posInfValue = DOUBLE_TO_JS2VAL(allocNumber(positiveInfinity));
@ -996,8 +996,8 @@ namespace MetaData {
JS2Class *c = checked_cast<JS2Class *>(obj);
if (!c->complete)
meta->reportError(Exception::constantError, "Cannot construct an instance of a class before its definition has been compiled", meta->engine->errorPos());
SimpleInstance *result = new SimpleInstance(meta, c->prototype, c);
DEFINE_ROOTKEEPER(rk, result);
SimpleInstance *result = new (meta) SimpleInstance(meta, c->prototype, c);
DEFINE_ROOTKEEPER(meta, rk, result);
meta->invokeInit(c, OBJECT_TO_JS2VAL(result), argv, argc);
return OBJECT_TO_JS2VAL(result);
}

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

@ -209,7 +209,7 @@ void dumpBytecode(BytecodeContainer *bCon);
class JS2Engine {
public:
JS2Engine(World &world);
JS2Engine(JS2Metadata *meta, World &world);
~JS2Engine();
js2val interpret(Phase execPhase, BytecodeContainer *targetbCon, Environment *env);

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

@ -57,15 +57,15 @@ namespace MetaData {
js2val error_ConstructorCore(JS2Metadata *meta, JS2Class *errorClass, js2val arg)
{
DEFINE_ROOTKEEPER(rk, arg);
DEFINE_ROOTKEEPER(meta, rk, arg);
JS2Object *obj = NULL;
DEFINE_ROOTKEEPER(rk1, obj);
obj = new SimpleInstance(meta, OBJECT_TO_JS2VAL(errorClass->prototype), errorClass);
DEFINE_ROOTKEEPER(meta, rk1, obj);
obj = new (meta) SimpleInstance(meta, OBJECT_TO_JS2VAL(errorClass->prototype), errorClass);
js2val thatValue = OBJECT_TO_JS2VAL(obj);
if (!JS2VAL_IS_VOID(arg)) {
const String *str = NULL;
DEFINE_ROOTKEEPER(rk2, str);
DEFINE_ROOTKEEPER(meta, rk2, str);
str = meta->toString(arg);
errorClass->WritePublic(meta, thatValue, &meta->world.identifiers["message"], true, meta->engine->allocString(str));
}
@ -131,7 +131,7 @@ js2val Error_toString(JS2Metadata *meta, const js2val thisValue, js2val *argv, u
static void initErrorClass(JS2Metadata *meta, JS2Class *c, Constructor *constructor)
{
meta->initBuiltinClass(c, NULL, constructor, constructor);
c->prototype = OBJECT_TO_JS2VAL(new SimpleInstance(meta, meta->errorClass->prototype, meta->errorClass));
c->prototype = OBJECT_TO_JS2VAL(new (meta) SimpleInstance(meta, meta->errorClass->prototype, meta->errorClass));
meta->createDynamicProperty(JS2VAL_TO_OBJECT(c->prototype), &meta->world.identifiers["name"], meta->engine->allocString(c->name), ReadAccess, true, true);
meta->createDynamicProperty(JS2VAL_TO_OBJECT(c->prototype), &meta->world.identifiers["message"], meta->engine->allocString("Message"), ReadAccess, true, true);
}
@ -149,7 +149,7 @@ void initErrorObject(JS2Metadata *meta)
publicNamespaceList.push_back(meta->publicNamespace);
meta->initBuiltinClass(meta->errorClass, NULL, Error_Constructor, Error_Constructor);
meta->errorClass->prototype = OBJECT_TO_JS2VAL(new SimpleInstance(meta, meta->objectClass->prototype, meta->errorClass));
meta->errorClass->prototype = OBJECT_TO_JS2VAL(new (meta) SimpleInstance(meta, meta->objectClass->prototype, meta->errorClass));
meta->createDynamicProperty(JS2VAL_TO_OBJECT(meta->errorClass->prototype), &meta->world.identifiers["name"], meta->engine->allocString("Error"), ReadAccess, true, true);
meta->createDynamicProperty(JS2VAL_TO_OBJECT(meta->errorClass->prototype), &meta->world.identifiers["message"], meta->engine->allocString("Message"), ReadAccess, true, true);
meta->initBuiltinClassPrototype(meta->errorClass, errorProtos);

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

@ -259,7 +259,7 @@ namespace MetaData {
CompilationData *oldData = startCompilationUnit(NULL, bCon->mSource, bCon->mSourceLocation);
try {
LexicalReference rVal(&world.identifiers[widenCString(fname)], false);
LexicalReference rVal(new (this) Multiname(&world.identifiers[widenCString(fname)]), false);
rVal.emitReadForInvokeBytecode(bCon, 0);
bCon->emitOp(eCall, 0, -(0 + 2) + 1); // pop argCount args, the base & function, and push a result
bCon->addShort(0);
@ -285,8 +285,8 @@ namespace MetaData {
if (c) init = c->init;
if (init) {
ParameterFrame *runtimeFrame;
DEFINE_ROOTKEEPER(rk, runtimeFrame);
runtimeFrame = new ParameterFrame(init->fWrap->compileFrame);
DEFINE_ROOTKEEPER(this, rk, runtimeFrame);
runtimeFrame = new (this) ParameterFrame(init->fWrap->compileFrame);
if (!init->fWrap->compileFrame->callsSuperConstructor) {
invokeInit(c->super, thisValue, NULL, 0);
runtimeFrame->superConstructorCalled = true;
@ -320,9 +320,9 @@ namespace MetaData {
BytecodeContainer *bCon = fWrap->bCon;
CompilationData *oldData = startCompilationUnit(bCon, bCon->mSource, bCon->mSourceLocation);
DEFINE_ROOTKEEPER(rk, runtimeFrame);
DEFINE_ROOTKEEPER(this, rk, runtimeFrame);
if (runtimeFrame == NULL)
runtimeFrame = new ParameterFrame(fWrap->compileFrame);
runtimeFrame = new (this) ParameterFrame(fWrap->compileFrame);
runtimeFrame->instantiate(fWrap->env);
runtimeFrame->thisObject = thisValue;
runtimeFrame->assignArguments(this, fnObj, argv, argc, argc);
@ -424,7 +424,7 @@ namespace MetaData {
// if that's not available or returns a non primitive, throw a TypeError
JS2Object *obj = JS2VAL_TO_OBJECT(x);
DEFINE_ROOTKEEPER(rk1, obj);
DEFINE_ROOTKEEPER(this, rk1, obj);
if (obj->kind == ClassKind) // therefore, not an E3 object, so just return
return engine->allocString("Function");// engine->typeofString(x); // the 'typeof' string
@ -715,36 +715,36 @@ namespace MetaData {
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);
DEFINE_ROOTKEEPER(meta, rk1, name);
Multiname *mn = new (meta) Multiname(name, meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk, mn);
return Read(meta, base, mn, NULL, phase, rval);
}
bool JS2Class::DeletePublic(JS2Metadata *meta, js2val base, const String *name, bool *result)
{
DEFINE_ROOTKEEPER(rk1, name);
DEFINE_ROOTKEEPER(meta, rk1, name);
// XXX could speed up by pushing knowledge of single namespace?
Multiname *mn = new Multiname(name, meta->publicNamespace);
DEFINE_ROOTKEEPER(rk, mn);
Multiname *mn = new (meta) Multiname(name, meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk, mn);
return Delete(meta, base, mn, NULL, result);
}
bool JS2Class::WritePublic(JS2Metadata *meta, js2val base, const String *name, bool createIfMissing, js2val newValue)
{
DEFINE_ROOTKEEPER(rk1, name);
DEFINE_ROOTKEEPER(meta, rk1, name);
// XXX could speed up by pushing knowledge of single namespace?
Multiname *mn = new Multiname(name, meta->publicNamespace);
DEFINE_ROOTKEEPER(rk, mn);
Multiname *mn = new (meta) Multiname(name, meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk, mn);
return Write(meta, base, mn, NULL, createIfMissing, newValue, false);
}
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);
DEFINE_ROOTKEEPER(meta, rk, indexStr);
Multiname *mn = new (meta) Multiname(indexStr, meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk1, mn);
return Read(meta, base, mn, NULL, phase, rval);
}
@ -805,9 +805,9 @@ namespace MetaData {
bool JS2ArrayClass::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);
DEFINE_ROOTKEEPER(meta, rk, indexStr);
Multiname *mn = new (meta) Multiname(indexStr, meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk1, mn);
ASSERT(JS2VAL_IS_OBJECT(base));
JS2Object *obj = JS2VAL_TO_OBJECT(base);
@ -838,9 +838,9 @@ namespace MetaData {
bool JS2ArrayClass::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);
DEFINE_ROOTKEEPER(meta, rk, indexStr);
Multiname *mn = new (meta) Multiname(indexStr, meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk1, mn);
return Delete(meta, base, mn, NULL, result);
}
@ -910,27 +910,27 @@ namespace MetaData {
bool JS2ArrayClass::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);
DEFINE_ROOTKEEPER(meta, rk, indexStr);
Multiname *mn = new (meta) Multiname(indexStr, meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk1, mn);
return Read(meta, base, mn, NULL, phase, rval);
}
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);
DEFINE_ROOTKEEPER(meta, rk, indexStr);
Multiname *mn = new (meta) Multiname(indexStr, meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk1, mn);
return Write(meta, base, mn, NULL, true, newValue, false);
}
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);
DEFINE_ROOTKEEPER(meta, rk, indexStr);
Multiname *mn = new (meta) Multiname(indexStr, meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk1, mn);
return Delete(meta, base, mn, NULL, result);
}
@ -948,7 +948,7 @@ namespace MetaData {
if (m == NULL) {
// XXX E3 compatibility...
JS2Object *baseObj = NULL;
DEFINE_ROOTKEEPER(rk, baseObj);
DEFINE_ROOTKEEPER(meta, rk, baseObj);
if (JS2VAL_IS_PRIMITIVE(base)) {
if (meta->cxt.E3compatibility)
baseObj = JS2VAL_TO_OBJECT(meta->toObject(base));
@ -960,8 +960,8 @@ namespace MetaData {
&& ( ((baseObj->kind == SimpleInstanceKind) && !checked_cast<SimpleInstance *>(baseObj)->sealed)
|| ( (baseObj->kind == PackageKind) && !checked_cast<Package *>(baseObj)->sealed)) ) {
QualifiedName qName = multiname->selectPrimaryName(meta);
Multiname *mn = new Multiname(qName);
DEFINE_ROOTKEEPER(rk, mn);
Multiname *mn = new (meta) Multiname(qName);
DEFINE_ROOTKEEPER(meta, rk, mn);
if ( (meta->findBaseInstanceMember(this, mn, ReadAccess) == NULL)
&& (meta->findCommonMember(&base, mn, ReadAccess, true) == NULL) ) {
meta->createDynamicProperty(baseObj, mn->name, newValue, ReadWriteAccess, false, true);

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

@ -77,7 +77,7 @@ namespace MetaData {
ASSERT(parser.lexer.peek(true).hasKind(Token::end));
ASSERT(fnExpr); // otherwise, an exception would have been thrown out of here
fnExpr->function.fn = NULL;
DEFINE_ROOTKEEPER(rk, fnExpr->function.fn);
DEFINE_ROOTKEEPER(meta, rk, fnExpr->function.fn);
meta->ValidateExpression(&meta->cxt, meta->env, fnExpr);
Arena *oldArena = meta->referenceArena;
meta->referenceArena = new Arena;
@ -102,10 +102,10 @@ namespace MetaData {
return OBJECT_TO_JS2VAL(fnExpr->function.fn);
}
else { // construct an empty function wrapper
js2val thatValue = OBJECT_TO_JS2VAL(new FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass));
js2val thatValue = OBJECT_TO_JS2VAL(new (meta) FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass));
FunctionInstance *fnInst = checked_cast<FunctionInstance *>(JS2VAL_TO_OBJECT(thatValue));
DEFINE_ROOTKEEPER(rk, fnInst);
fnInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), meta->env);
DEFINE_ROOTKEEPER(meta, rk, fnInst);
fnInst->fWrap = new FunctionWrapper(meta, true, new (meta) ParameterFrame(JS2VAL_INACCESSIBLE, true), meta->env);
fnInst->fWrap->length = 0;
fnInst->fWrap->bCon->emitOp(eReturnVoid, meta->engine->errorPos());
meta->createDynamicProperty(fnInst, meta->engine->length_StringAtom, INT_TO_JS2VAL(0), ReadAccess, true, false);
@ -137,7 +137,7 @@ namespace MetaData {
FunctionInstance *fnInst = checked_cast<FunctionInstance *>(JS2VAL_TO_OBJECT(thisValue));
js2val callThis = argv[0];
DEFINE_ROOTKEEPER(rk0, callThis);
DEFINE_ROOTKEEPER(meta, rk0, callThis);
if (JS2VAL_IS_NULL(argv[0]) || JS2VAL_IS_UNDEFINED(argv[0]))
callThis = OBJECT_TO_JS2VAL(meta->glob);
else
@ -157,7 +157,7 @@ namespace MetaData {
meta->reportError(Exception::typeError, "Function.apply called on something other than a function thing", meta->engine->errorPos());
FunctionInstance *fnInst = checked_cast<FunctionInstance *>(JS2VAL_TO_OBJECT(thisValue));
js2val callThis = argv[0];
DEFINE_ROOTKEEPER(rk0, callThis);
DEFINE_ROOTKEEPER(meta, rk0, callThis);
if (JS2VAL_IS_NULL(argv[0]) || JS2VAL_IS_UNDEFINED(argv[0]))
callThis = OBJECT_TO_JS2VAL(meta->glob);
else
@ -171,7 +171,7 @@ namespace MetaData {
ArrayInstance *arrInst = checked_cast<ArrayInstance *>(obj);
uint32 length = getLength(meta, arrInst);
js2val *argArray = new js2val[length];
DEFINE_ARRAYROOTKEEPER(rk, argArray, length);
DEFINE_ARRAYROOTKEEPER(meta, rk, argArray, length);
for (uint32 i = 0; i < length; i++)
meta->arrayClass->ReadPublic(meta, &argv[1], meta->engine->numberToString(i), RunPhase, &argArray[i]);
return meta->invokeFunction(fnInst, callThis, argArray, length, NULL);
@ -181,7 +181,7 @@ namespace MetaData {
ArgumentsInstance *argInst = checked_cast<ArgumentsInstance *>(obj);
uint32 length = getLength(meta, argInst);
js2val *argArray = new js2val[length];
DEFINE_ARRAYROOTKEEPER(rk, argArray, length);
DEFINE_ARRAYROOTKEEPER(meta, rk, argArray, length);
for (uint32 i = 0; i < length; i++)
meta->argumentsClass->ReadPublic(meta, &argv[1], meta->engine->numberToString(i), RunPhase, &argArray[i]);
return meta->invokeFunction(fnInst, callThis, argArray, length, NULL);
@ -204,9 +204,9 @@ namespace MetaData {
{ NULL }
};
FunctionInstance *fnInst = new FunctionInstance(meta, meta->objectClass->prototype, meta->functionClass);
DEFINE_ROOTKEEPER(rk, fnInst);
fnInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), meta->env);
FunctionInstance *fnInst = new (meta) FunctionInstance(meta, meta->objectClass->prototype, meta->functionClass);
DEFINE_ROOTKEEPER(meta, rk, fnInst);
fnInst->fWrap = new FunctionWrapper(meta, true, new (meta) ParameterFrame(JS2VAL_INACCESSIBLE, true), meta->env);
fnInst->fWrap->length = 0;
fnInst->fWrap->bCon->emitOp(eReturnVoid, 0);

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

@ -347,8 +347,8 @@ void initMathObject(JS2Metadata *meta, SimpleInstance *mathObject)
FunctionData *pf = &prototypeFunctions[0];
while (pf->name) {
FunctionInstance *callInst = new FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass);
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code, meta->env);
FunctionInstance *callInst = new (meta) FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass);
callInst->fWrap = new FunctionWrapper(meta, true, new (meta) ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code, meta->env);
callInst->fWrap->length = pf->length;
meta->createDynamicProperty(mathObject, &meta->world.identifiers[pf->name], OBJECT_TO_JS2VAL(callInst), ReadAccess, true, false);

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

@ -87,14 +87,14 @@ namespace MetaData {
FunctionInstance *JS2Metadata::createFunctionInstance(Environment *env, bool prototype, bool unchecked, NativeCode *code, uint32 length, DynamicVariable **lengthProperty)
{
ParameterFrame *compileFrame = new ParameterFrame(JS2VAL_VOID, prototype);
DEFINE_ROOTKEEPER(rk1, compileFrame);
FunctionInstance *result = new FunctionInstance(this, functionClass->prototype, functionClass);
DEFINE_ROOTKEEPER(rk2, result);
ParameterFrame *compileFrame = new (this) ParameterFrame(JS2VAL_VOID, prototype);
DEFINE_ROOTKEEPER(this, rk1, compileFrame);
FunctionInstance *result = new (this) FunctionInstance(this, functionClass->prototype, functionClass);
DEFINE_ROOTKEEPER(this, rk2, result);
if (code == NULL)
result->fWrap = new FunctionWrapper(unchecked, compileFrame, env);
result->fWrap = new FunctionWrapper(this, unchecked, compileFrame, env);
else
result->fWrap = new FunctionWrapper(unchecked, compileFrame, code, env);
result->fWrap = new FunctionWrapper(this, unchecked, compileFrame, code, env);
result->fWrap->length = length;
DynamicVariable *dv = createDynamicProperty(result, engine->length_StringAtom, INT_TO_JS2VAL(length), ReadAccess, true, false);
if (lengthProperty)
@ -107,7 +107,7 @@ namespace MetaData {
{
DynamicVariable *lengthVar = NULL;
FunctionInstance *result = createFunctionInstance(env, prototype, unchecked, NULL, 0, &lengthVar);
DEFINE_ROOTKEEPER(rk1, result);
DEFINE_ROOTKEEPER(this, rk1, result);
fnDef->fn = result;
Frame *curTopFrame = env->getTopFrame();
@ -130,7 +130,7 @@ namespace MetaData {
defineHoistedVar(env, pb->name, JS2VAL_UNDEFINED, true, pos);
}
else {
FrameVariable *v = new FrameVariable(result->fWrap->compileFrame->allocateSlot(), FrameVariable::Parameter);
FrameVariable *v = new (this) FrameVariable(result->fWrap->compileFrame->allocateSlot(), FrameVariable::Parameter);
pb->member = v;
defineLocalMember(env, pb->name, NULL, Attribute::NoOverride, false, ReadWriteAccess, v, pb->pos, true);
}
@ -159,7 +159,7 @@ namespace MetaData {
void JS2Metadata::validateStatic(Context *cxt, Environment *env, FunctionDefinition *fnDef, CompoundAttribute *a, bool unchecked, bool hoisted, size_t pos)
{
FunctionInstance *fnInst = NULL;
DEFINE_ROOTKEEPER(rk1, fnInst);
DEFINE_ROOTKEEPER(this, rk1, fnInst);
switch (fnDef->prefix) {
case FunctionName::normal:
fnInst = validateStaticFunction(cxt, env, fnDef, a->prototype, unchecked, false, pos);
@ -216,9 +216,9 @@ namespace MetaData {
reportError(Exception::attributeError, "An instance method cannot have the prototype attribute", pos);
// XXX shouldn't be using validateStaticFunction
FunctionInstance *fnInst = NULL;
DEFINE_ROOTKEEPER(rk1, fnInst);
DEFINE_ROOTKEEPER(this, rk1, fnInst);
fnInst = validateStaticFunction(cxt, env, fnDef, false, false, false, pos);
Multiname *mn = new Multiname(fnDef->name, a->namespaces);
Multiname *mn = new (this) Multiname(fnDef->name, a->namespaces);
InstanceMember *m;
switch (fnDef->prefix) {
case FunctionName::normal:
@ -240,7 +240,7 @@ namespace MetaData {
void JS2Metadata::ValidateStmt(Context *cxt, Environment *env, Plurality pl, StmtNode *p)
{
CompoundAttribute *a = NULL;
DEFINE_ROOTKEEPER(rk, a);
DEFINE_ROOTKEEPER(this, rk, a);
Frame *curTopFrame = env->getTopFrame();
try {
@ -249,7 +249,7 @@ namespace MetaData {
case StmtNode::group:
{
BlockStmtNode *b = checked_cast<BlockStmtNode *>(p);
b->compileFrame = new BlockFrame();
b->compileFrame = new (this) BlockFrame();
bCon->saveFrame(b->compileFrame); // stash this frame so it doesn't get gc'd before eval pass.
env->addFrame(b->compileFrame);
targetList.push_back(p);
@ -522,7 +522,7 @@ namespace MetaData {
ValidateAttributeExpression(cxt, env, f->attributes);
attr = EvalAttributeExpression(env, CompilePhase, f->attributes);
}
a = Attribute::toCompoundAttribute(attr);
a = Attribute::toCompoundAttribute(this, attr);
if (a->dynamic)
reportError(Exception::attributeError, "A function cannot have the dynamic attribute", p->pos);
Frame *topFrame = env->getTopFrame();
@ -600,7 +600,7 @@ namespace MetaData {
defineHoistedVar(env, name, JS2VAL_UNDEFINED, true, p->pos);
}
else {
a = Attribute::toCompoundAttribute(attr);
a = Attribute::toCompoundAttribute(this, attr);
if (a->dynamic || a->prototype)
reportError(Exception::definitionError, "Illegal attribute", p->pos);
Attribute::MemberModifier memberMod = a->memberMod;
@ -624,7 +624,7 @@ namespace MetaData {
case Attribute::Virtual:
case Attribute::Final:
{
Multiname *mn = new Multiname(name, a->namespaces);
Multiname *mn = new (this) Multiname(name, a->namespaces);
JS2Class *c = checked_cast<JS2Class *>(env->getTopFrame());
InstanceMember *m = new InstanceVariable(mn, FUTURE_TYPE, immutable, (memberMod == Attribute::Final), true, c->slotCount++);
vb->member = m;
@ -654,12 +654,12 @@ namespace MetaData {
ValidateAttributeExpression(cxt, env, ns->attributes);
attr = EvalAttributeExpression(env, CompilePhase, ns->attributes);
}
a = Attribute::toCompoundAttribute(attr);
a = Attribute::toCompoundAttribute(this, attr);
if (a->dynamic || a->prototype)
reportError(Exception::definitionError, "Illegal attribute", p->pos);
if ( ! ((a->memberMod == Attribute::NoModifier) || ((a->memberMod == Attribute::Static) && (env->getTopFrame()->kind == ClassKind))) )
reportError(Exception::definitionError, "Illegal attribute", p->pos);
Variable *v = new Variable(namespaceClass, OBJECT_TO_JS2VAL(new Namespace(&ns->name)), true);
Variable *v = new Variable(namespaceClass, OBJECT_TO_JS2VAL(new (this) Namespace(&ns->name)), true);
defineLocalMember(env, &ns->name, &a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, v, p->pos, true);
}
break;
@ -698,7 +698,7 @@ namespace MetaData {
ValidateAttributeExpression(cxt, env, classStmt->attributes);
attr = EvalAttributeExpression(env, CompilePhase, classStmt->attributes);
}
a = Attribute::toCompoundAttribute(attr);
a = Attribute::toCompoundAttribute(this, attr);
if (!superClass->complete || superClass->final)
reportError(Exception::definitionError, "Illegal inheritance", p->pos);
js2val protoVal = JS2VAL_NULL;
@ -719,7 +719,7 @@ namespace MetaData {
reportError(Exception::definitionError, "Illegal modifier for class definition", p->pos);
break;
}
JS2Class *c = new JS2Class(superClass, protoVal, new Namespace(engine->private_StringAtom), (a->dynamic || superClass->dynamic), final, engine->allocStringPtr(&classStmt->name));
JS2Class *c = new (this) JS2Class(superClass, protoVal, new (this) Namespace(engine->private_StringAtom), (a->dynamic || superClass->dynamic), final, engine->allocStringPtr(&classStmt->name));
classStmt->c = c;
Variable *v = new Variable(classClass, OBJECT_TO_JS2VAL(c), true);
defineLocalMember(env, &classStmt->name, &a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, v, p->pos, true);
@ -739,7 +739,7 @@ namespace MetaData {
UnaryStmtNode *w = checked_cast<UnaryStmtNode *>(p);
ValidateExpression(cxt, env, w->expr);
if (w->stmt->getKind() != StmtNode::block) {
w->compileFrame = new BlockFrame();
w->compileFrame = new (this) BlockFrame();
env->addFrame(w->compileFrame);
ValidateStmt(cxt, env, pl, w->stmt);
env->removeTopFrame();
@ -754,7 +754,7 @@ namespace MetaData {
{
PackageStmtNode *ps = checked_cast<PackageStmtNode *>(p);
String packageName = getPackageName(ps->packageIdList);
Package *package = new Package(packageName, new Namespace(&world.identifiers["internal"]));
Package *package = new (this) Package(packageName, new (this) Namespace(&world.identifiers["internal"]));
Variable *v = new Variable(packageClass, OBJECT_TO_JS2VAL(package), true);
defineLocalMember(env, &packageName, NULL, Attribute::NoOverride, false, ReadAccess, v, 0, true);
@ -909,7 +909,7 @@ namespace MetaData {
case StmtNode::group:
{
BlockStmtNode *b = checked_cast<BlockStmtNode *>(p);
// BlockFrame *runtimeFrame = new BlockFrame(b->compileFrame);
// BlockFrame *runtimeFrame = new (this) BlockFrame(b->compileFrame);
env->addFrame(b->compileFrame); // XXX is this right? shouldn't this be the compile frame until execution occurs?
bCon->emitOp(ePushFrame, p->pos);
bCon->addFrame(b->compileFrame);
@ -1004,7 +1004,7 @@ namespace MetaData {
if (f->initializer->getKind() == StmtNode::Var) {
VariableStmtNode *vs = checked_cast<VariableStmtNode *>(f->initializer);
VariableBinding *vb = vs->bindings;
v = new (*referenceArena) LexicalReference(vb->name, cxt.strict);
v = new (*referenceArena) LexicalReference(new (this) Multiname(vb->name), cxt.strict);
referenceArena->registerDestructor(v);
}
else {
@ -1300,7 +1300,7 @@ namespace MetaData {
}
// write the exception object (on stack top) into the named
// local variable
Reference *r = new (*referenceArena) LexicalReference(&c->name, false);
Reference *r = new (*referenceArena) LexicalReference(new (this) Multiname(&c->name), false);
referenceArena->registerDestructor(r);
r->emitWriteBytecode(bCon, p->pos);
bCon->emitOp(ePop, p->pos);
@ -1399,7 +1399,7 @@ namespace MetaData {
throw x;
Reference *r = SetupExprNode(env, phase, vb->initializer, &exprType);
if (r) r->emitReadBytecode(bCon, p->pos);
LexicalReference *lVal = new (*referenceArena) LexicalReference(vb->mn, cxt.strict);
LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(vb->mn), cxt.strict);
referenceArena->registerDestructor(lVal);
lVal->emitWriteBytecode(bCon, p->pos);
bCon->emitOp(ePop, p->pos);
@ -1418,13 +1418,13 @@ namespace MetaData {
if (r) r->emitReadBytecode(bCon, p->pos);
bCon->emitOp(eCoerce, p->pos);
bCon->addType(v->type);
LexicalReference *lVal = new (*referenceArena) LexicalReference(vb->mn, cxt.strict);
LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(vb->mn), cxt.strict);
referenceArena->registerDestructor(lVal);
lVal->emitInitBytecode(bCon, p->pos);
}
else {
v->type->emitDefaultValue(bCon, p->pos);
LexicalReference *lVal = new (*referenceArena) LexicalReference(vb->mn, cxt.strict);
LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(vb->mn), cxt.strict);
referenceArena->registerDestructor(lVal);
lVal->emitInitBytecode(bCon, p->pos);
}
@ -1469,9 +1469,9 @@ namespace MetaData {
if (vb->initializer) {
Reference *r = SetupExprNode(env, phase, vb->initializer, &exprType);
if (r) r->emitReadBytecode(bCon, p->pos);
LexicalReference *lVal = new (*referenceArena) LexicalReference(vb->name, cxt.strict);
LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(vb->name), cxt.strict);
referenceArena->registerDestructor(lVal);
lVal->variableMultiname.addNamespace(publicNamespace);
lVal->variableMultiname->addNamespace(publicNamespace);
lVal->emitInitBytecode(bCon, p->pos);
}
}
@ -1611,9 +1611,9 @@ namespace MetaData {
switch (p->getKind()) {
case ExprNode::boolean:
if (checked_cast<BooleanExprNode *>(p)->value)
return new TrueAttribute();
return new (this) TrueAttribute();
else
return new FalseAttribute();
return new (this) FalseAttribute();
case ExprNode::juxtapose:
{
BinaryExprNode *j = checked_cast<BinaryExprNode *>(p);
@ -1622,7 +1622,7 @@ namespace MetaData {
return a;
Attribute *b = EvalAttributeExpression(env, phase, j->op2);
try {
return Attribute::combineAttributes(a, b);
return Attribute::combineAttributes(this, a, b);
}
catch (char *err) {
reportError(Exception::badValueError, err, p->pos);
@ -1638,7 +1638,7 @@ namespace MetaData {
case Token::Public:
return publicNamespace;
case Token::Final:
ca = new CompoundAttribute();
ca = new (this) CompoundAttribute();
ca->memberMod = Attribute::Final;
return ca;
case Token::Private:
@ -1647,30 +1647,30 @@ namespace MetaData {
return c->privateNamespace;
}
case Token::Static:
ca = new CompoundAttribute();
ca = new (this) CompoundAttribute();
ca->memberMod = Attribute::Static;
return ca;
case Token::identifier:
if (name == world.identifiers["override"]) {
ca = new CompoundAttribute();
ca = new (this) CompoundAttribute();
ca->overrideMod = Attribute::DoOverride;
return ca;
}
else
if (name == world.identifiers["enumerable"]) {
ca = new CompoundAttribute();
ca = new (this) CompoundAttribute();
ca->enumerable = true;
return ca;
}
else
if (name == world.identifiers["virtual"]) {
ca = new CompoundAttribute();
ca = new (this) CompoundAttribute();
ca->memberMod = Attribute::Virtual;
return ca;
}
else
if (name == world.identifiers["dynamic"]) {
ca = new CompoundAttribute();
ca = new (this) CompoundAttribute();
ca->dynamic = true;
return ca;
}
@ -1697,7 +1697,7 @@ namespace MetaData {
// Combine attributes a & b, reporting errors for incompatibilities
// a is not false
Attribute *Attribute::combineAttributes(Attribute *a, Attribute *b)
Attribute *Attribute::combineAttributes(JS2Metadata *meta, Attribute *a, Attribute *b)
{
if (b && (b->attrKind == FalseAttr)) {
if (a) delete a;
@ -1719,7 +1719,7 @@ namespace MetaData {
Namespace *na = checked_cast<Namespace *>(a);
if (b->attrKind == NamespaceAttr) {
Namespace *nb = checked_cast<Namespace *>(b);
CompoundAttribute *c = new CompoundAttribute();
CompoundAttribute *c = new (meta) CompoundAttribute();
c->addNamespace(na);
c->addNamespace(nb);
delete a;
@ -1775,26 +1775,26 @@ namespace MetaData {
// Convert an attribute to a compoundAttribute. If the attribute
// is NULL, return a default compoundAttribute
CompoundAttribute *Attribute::toCompoundAttribute(Attribute *a)
CompoundAttribute *Attribute::toCompoundAttribute(JS2Metadata *meta, Attribute *a)
{
if (a)
return a->toCompoundAttribute();
else
return new CompoundAttribute();
return new (meta) CompoundAttribute();
}
// Convert a simple namespace to a compoundAttribute with that namespace
CompoundAttribute *Namespace::toCompoundAttribute()
CompoundAttribute *Namespace::toCompoundAttribute(JS2Metadata *meta)
{
CompoundAttribute *t = new CompoundAttribute();
CompoundAttribute *t = new (meta) CompoundAttribute();
t->addNamespace(this);
return t;
}
// Convert a 'true' attribute to a default compoundAttribute
CompoundAttribute *TrueAttribute::toCompoundAttribute()
CompoundAttribute *TrueAttribute::toCompoundAttribute(JS2Metadata *meta)
{
return new CompoundAttribute();
return new (meta) CompoundAttribute();
}
// gc-mark all contained JS2Objects and visit contained structures to do likewise
@ -2345,9 +2345,9 @@ doUnary:
RegExpExprNode *v = checked_cast<RegExpExprNode *>(p);
js2val args[2];
const String *reStr = engine->allocStringPtr(&v->re);
DEFINE_ROOTKEEPER(rk1, reStr);
DEFINE_ROOTKEEPER(this, rk1, reStr);
const String *flagStr = engine->allocStringPtr(&v->flags);
DEFINE_ROOTKEEPER(rk2, flagStr);
DEFINE_ROOTKEEPER(this, rk2, flagStr);
args[0] = STRING_TO_JS2VAL(reStr);
args[1] = STRING_TO_JS2VAL(flagStr);
// XXX error handling during this parse? The RegExp_Constructor is
@ -2398,7 +2398,7 @@ doUnary:
reportError(Exception::badValueError, "Namespace expected in qualifier", p->pos);
Namespace *ns = checked_cast<Namespace *>(obj);
returnRef = new (*referenceArena) LexicalReference(&name, ns, cxt.strict);
returnRef = new (*referenceArena) LexicalReference(new (this) Multiname(&name, ns), cxt.strict);
referenceArena->registerDestructor(returnRef);
}
break;
@ -2424,16 +2424,16 @@ doUnary:
fi++;
}
}
returnRef = new (*referenceArena) LexicalReference(&i->name, cxt.strict);
returnRef = new (*referenceArena) LexicalReference(new (this) Multiname(&i->name), cxt.strict);
referenceArena->registerDestructor(returnRef);
((LexicalReference *)returnRef)->variableMultiname.addNamespace(cxt);
((LexicalReference *)returnRef)->variableMultiname->addNamespace(cxt);
// Try to find this identifier at compile time, we have to stop if we reach
// a frame that supports dynamic properties - the identifier could be
// created at runtime without us finding it here.
// We're looking to find both the type of the reference (to store into exprType)
// and to see if we can change the reference to a FrameSlot or Slot (for member
// functions)
Multiname *multiname = &((LexicalReference *)returnRef)->variableMultiname;
Multiname *multiname = ((LexicalReference *)returnRef)->variableMultiname;
FrameListIterator fi = env->getBegin();
bool keepLooking = true;
while (fi != env->getEnd() && keepLooking) {
@ -2635,18 +2635,18 @@ doUnary:
}
if (returnRef == NULL) {
returnRef = new (*referenceArena) DotReference(&i->name);
returnRef = new (*referenceArena) DotReference(new (this) Multiname(&i->name));
referenceArena->registerDestructor(returnRef);
checked_cast<DotReference *>(returnRef)->propertyMultiname.addNamespace(cxt);
checked_cast<DotReference *>(returnRef)->propertyMultiname->addNamespace(cxt);
}
}
else {
if (b->op2->getKind() == ExprNode::qualify) {
Reference *rVal = SetupExprNode(env, phase, b->op2, exprType);
ASSERT(rVal && checked_cast<LexicalReference *>(rVal));
returnRef = new (*referenceArena) DotReference(&((LexicalReference *)rVal)->variableMultiname);
returnRef = new (*referenceArena) DotReference(((LexicalReference *)rVal)->variableMultiname);
referenceArena->registerDestructor(returnRef);
checked_cast<DotReference *>(returnRef)->propertyMultiname.addNamespace(cxt);
checked_cast<DotReference *>(returnRef)->propertyMultiname->addNamespace(cxt);
}
// XXX else bracketRef...
else
@ -3238,7 +3238,7 @@ doUnary:
if ((overrideMod != Attribute::NoOverride) || (xplicit && innerFrame->kind != PackageKind))
reportError(Exception::definitionError, "Illegal definition", pos);
Multiname *multiname = new Multiname(id);
Multiname *multiname = new (this) Multiname(id);
if (!namespaces || namespaces->empty())
multiname->addNamespace(publicNamespace);
else
@ -3360,8 +3360,8 @@ doUnary:
JS2Class *s = c->super;
if (s) {
for (NamespaceListIterator nli = multiname->nsList->begin(), nlend = multiname->nsList->end(); (nli != nlend); nli++) {
Multiname *mn = new Multiname(multiname->name, *nli);
DEFINE_ROOTKEEPER(rk, mn);
Multiname *mn = new (this) Multiname(multiname->name, *nli);
DEFINE_ROOTKEEPER(this, rk, mn);
InstanceMember *m = findBaseInstanceMember(s, mn, access);
if (mBase == NULL)
mBase = m;
@ -3441,7 +3441,7 @@ doUnary:
reportError(Exception::definitionError, "Illegal override", pos);
break;
}
m->multiname = new Multiname(definedMultiname);
m->multiname = new (this) Multiname(definedMultiname);
InstanceBindingEntry *ibe;
if (ibeP == NULL) {
ibe = new InstanceBindingEntry(*id);
@ -3824,14 +3824,14 @@ static const uint8 urlCharType[256] =
void JS2Metadata::addGlobalObjectFunction(char *name, NativeCode *code, uint32 length)
{
FunctionInstance *fInst = createFunctionInstance(env, true, true, code, length, NULL);
DEFINE_ROOTKEEPER(rk1, fInst);
DEFINE_ROOTKEEPER(this, rk1, fInst);
createDynamicProperty(glob, &world.identifiers[name], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, true);
}
static js2val Object_Constructor(JS2Metadata *meta, const js2val thisValue, js2val argv[], uint32 argc)
{
if ((argc == 0) || JS2VAL_IS_NULL(argv[0]) || JS2VAL_IS_UNDEFINED(argv[0]))
return OBJECT_TO_JS2VAL(new SimpleInstance(meta, meta->objectClass->prototype, meta->objectClass));
return OBJECT_TO_JS2VAL(new (meta) SimpleInstance(meta, meta->objectClass->prototype, meta->objectClass));
else {
if (JS2VAL_IS_OBJECT(argv[0]))
return argv[0]; // XXX special handling for host objects?
@ -3957,8 +3957,8 @@ static const uint8 urlCharType[256] =
if (newLength < arrInst->length) {
// need to delete all the elements above the new length
bool deleteResult;
Multiname *mn = new Multiname(NULL, meta->publicNamespace);
DEFINE_ROOTKEEPER(rk, mn);
Multiname *mn = new (meta) Multiname(NULL, meta->publicNamespace);
DEFINE_ROOTKEEPER(meta, rk, mn);
for (uint32 i = newLength; i < arrInst->length; i++) {
mn->name = meta->engine->numberToString(i);
meta->arrayClass->Delete(meta, thisValue, mn, NULL, &deleteResult);
@ -3974,47 +3974,54 @@ static const uint8 urlCharType[256] =
}
#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;
#define MAKEBUILTINCLASS(c, super, dynamic, final, name, defaultVal) c = new (this) JS2Class(super, NULL, new (this) Namespace(engine->private_StringAtom), dynamic, final, name); c->complete = true; c->defaultValue = defaultVal;
JS2Metadata::JS2Metadata(World &world) : JS2Object(MetaDataKind),
JS2Metadata::JS2Metadata(World &world) :
world(world),
engine(new JS2Engine(world)),
publicNamespace(new Namespace(engine->public_StringAtom)),
// engine(new JS2Engine(world)),
// publicNamespace(new Namespace(engine->public_StringAtom)),
bCon(new BytecodeContainer()),
glob(new Package(widenCString("global"), new Namespace(&world.identifiers["internal"]))),
env(new Environment(new MetaData::SystemFrame(), glob)),
// glob(new Package(widenCString("global"), new Namespace(&world.identifiers["internal"]))),
// env(new Environment(new MetaData::SystemFrame(), glob)),
flags(JS1),
version(JS2VERSION_DEFAULT),
showTrees(false),
referenceArena(NULL)
referenceArena(NULL),
pond(POND_SIZE, NULL)
{
engine = new JS2Engine(this, world);
publicNamespace = new (this) Namespace(engine->public_StringAtom);
glob = new (this) Package(widenCString("global"), new (this) Namespace(&world.identifiers["internal"]));
env = new (this) Environment(new (this) SystemFrame(), glob);
rngInitialized = false;
engine->meta = this;
// engine->meta = this;
cxt.openNamespaces.clear();
cxt.openNamespaces.push_back(publicNamespace);
MAKEBUILTINCLASS(objectClass, NULL, false, false, engine->Object_StringAtom, JS2VAL_VOID);
MAKEBUILTINCLASS(undefinedClass, objectClass, false, true, engine->undefined_StringAtom, JS2VAL_VOID);
nullClass = new JS2NullClass(objectClass, NULL, new Namespace(engine->private_StringAtom), false, true, engine->null_StringAtom); nullClass->complete = true; nullClass->defaultValue = JS2VAL_NULL;
nullClass = new (this) JS2NullClass(objectClass, NULL, new (this) 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);
integerClass = new JS2IntegerClass(numberClass, NULL, new Namespace(engine->private_StringAtom), false, true, engine->allocStringPtr(&world.identifiers["Integer"])); integerClass->complete = true; integerClass->defaultValue = JS2VAL_ZERO;
integerClass = new (this) JS2IntegerClass(numberClass, NULL, new (this) 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);
stringClass = new JS2StringClass(objectClass, NULL, new Namespace(engine->private_StringAtom), false, true, engine->allocStringPtr(&world.identifiers["String"])); stringClass->complete = true; stringClass->defaultValue = JS2VAL_NULL;
stringClass = new (this) JS2StringClass(objectClass, NULL, new (this) 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);
MAKEBUILTINCLASS(functionClass, objectClass, true, true, engine->Function_StringAtom, JS2VAL_NULL);
MAKEBUILTINCLASS(packageClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["Package"]), JS2VAL_NULL);
argumentsClass = new JS2ArgumentsClass(objectClass, NULL, new Namespace(engine->private_StringAtom), false, true, engine->allocStringPtr(&world.identifiers["Object"])); argumentsClass->complete = true; argumentsClass->defaultValue = JS2VAL_NULL;
argumentsClass = new (this) JS2ArgumentsClass(objectClass, NULL, new (this) Namespace(engine->private_StringAtom), false, true, engine->allocStringPtr(&world.identifiers["Object"])); argumentsClass->complete = true; argumentsClass->defaultValue = JS2VAL_NULL;
// A 'forbidden' member, used to mark hidden bindings
forbiddenMember = new LocalMember(Member::ForbiddenMember, true);
FunctionInstance *fInst = NULL;
DEFINE_ROOTKEEPER(rk1, fInst);
DEFINE_ROOTKEEPER(this, rk1, fInst);
Variable *v;
// XXX Built-in Attributes... XXX
@ -4038,7 +4045,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
v = new Variable(classClass, OBJECT_TO_JS2VAL(objectClass), true);
defineLocalMember(env, &world.identifiers["Object"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
// Function properties of the Object prototype object
objectClass->prototype = OBJECT_TO_JS2VAL(new SimpleInstance(this, NULL, objectClass));
objectClass->prototype = OBJECT_TO_JS2VAL(new (this) SimpleInstance(this, NULL, objectClass));
objectClass->construct = Object_Constructor;
objectClass->call = Object_Constructor;
// Adding "prototype" as a static member of the class - not a dynamic property
@ -4139,13 +4146,13 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
/*** ECMA 3 Math Object ***/
MAKEBUILTINCLASS(mathClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["Math"]), JS2VAL_FALSE);
SimpleInstance *mathObject = new SimpleInstance(this, objectClass->prototype, mathClass);
SimpleInstance *mathObject = new (this) SimpleInstance(this, objectClass->prototype, mathClass);
v = new Variable(objectClass, OBJECT_TO_JS2VAL(mathObject), true);
defineLocalMember(env, &world.identifiers["Math"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
initMathObject(this, mathObject);
/*** ECMA 3 Array Class ***/
arrayClass = new JS2ArrayClass(objectClass, NULL, new Namespace(engine->private_StringAtom), true, true, engine->allocStringPtr(&world.identifiers["Array"])); arrayClass->complete = true; arrayClass->defaultValue = JS2VAL_NULL;
arrayClass = new (this) JS2ArrayClass(objectClass, NULL, new (this) 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);
@ -4188,7 +4195,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
{
bConList.clear();
targetList.clear();
JS2Object::clear(this); // don't blow off the contents of 'this' as the destructors for
clear(); // don't blow off the contents of 'this' as the destructors for
// embedded objects will get messed up (as they run on exit).
delete engine;
if (bCon) delete bCon;
@ -4395,7 +4402,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
InstanceMethod *im = checked_cast<InstanceMethod *>(m);
if (phase == CompilePhase)
reportError(Exception::compileExpressionError, "Inappropriate compile time expression", engine->errorPos());
FunctionInstance *fInst = new FunctionInstance(this, functionClass->prototype, functionClass);
FunctionInstance *fInst = new (this) FunctionInstance(this, functionClass->prototype, functionClass);
fInst->isMethodClosure = true;
fInst->fWrap = im->fInst->fWrap;
fInst->thisObject = containerVal;
@ -4571,8 +4578,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
bool JS2Metadata::hasOwnProperty(JS2Object *obj, const String *name)
{
Multiname *mn = new Multiname(name, publicNamespace);
DEFINE_ROOTKEEPER(rk, mn);
Multiname *mn = new (this) Multiname(name, publicNamespace);
DEFINE_ROOTKEEPER(this, rk, mn);
js2val val = OBJECT_TO_JS2VAL(obj);
return (findCommonMember(&val, mn, ReadWriteAccess, true) != NULL);
}
@ -4584,7 +4591,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
/*
DynamicVariable *JS2Metadata::createDynamicProperty(JS2Object *obj, const String *name, js2val initVal, Access access, bool sealed, bool enumerable)
{
DEFINE_ROOTKEEPER(rk, name);
DEFINE_ROOTKEEPER(this, rk, name);
QualifiedName qName(publicNamespace, name);
return createDynamicProperty(obj, &qName, initVal, access, sealed, enumerable);
}
@ -4794,6 +4801,84 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
}
// Add a pointer to the (address of a) gc-allocated object to the root list
// (Note - we hand out an iterator, so it's essential to
// use something like std::list that doesn't mess with locations)
RootIterator JS2Metadata::addRoot(RootKeeper *t)
{
return rootList.insert(rootList.end(), t);
}
// Remove a root pointer
void JS2Metadata::removeRoot(RootIterator ri)
{
rootList.erase(ri);
}
// Remove everything, regardless of rootlist
void JS2Metadata::clear()
{
pond.resetMarks();
pond.moveUnmarkedToFreeList(this);
}
// Mark all reachable objects and put the rest back on the freelist
uint32 JS2Metadata::gc()
{
pond.resetMarks();
markChildren();
// Anything on the root list may also be a pointer to a JS2Object.
for (RootIterator i = rootList.begin(), end = rootList.end(); (i != end); i++) {
RootKeeper *r = *i;
PondScum *scum = NULL;
if (r->is_js2val) {
if (r->js2val_count) {
js2val *valp = *((js2val **)(r->p));
for (uint32 c = 0; c < r->js2val_count; c++)
JS2Object::markJS2Value(*valp++);
}
else {
js2val *valp = (js2val *)(r->p);
JS2Object::markJS2Value(*valp);
}
}
else {
JS2Object **objp = (JS2Object **)(r->p);
if (*objp) {
scum = ((PondScum *)(*objp) - 1);
ASSERT(scum->owner && (scum->getSize() >= sizeof(PondScum)) && (scum->owner->sanity == POND_SANITY));
if (scum->isJS2Object()) {
JS2Object *obj = (JS2Object *)(scum + 1);
GCMARKOBJECT(obj)
}
else
JS2Object::mark(scum + 1);
}
}
}
return pond.moveUnmarkedToFreeList(this);
}
// Allocate a chunk of size s
void *JS2Metadata::alloc(size_t s, PondScum::ScumFlag flag)
{
s += sizeof(PondScum);
// make sure that the thing is a multiple of 16 bytes
if (s & 0xF) s += 16 - (s & 0xF);
ASSERT(s <= 0x7FFFFFFF);
void *p = pond.allocFromPond(this, s, flag);
ASSERT(((ptrdiff_t)p & 0xF) == 0);
return p;
}
// Release a chunk back to it's pond
void JS2Metadata::unalloc(void *t)
{
PondScum *p = (PondScum *)t - 1;
ASSERT(p->owner && (p->getSize() >= sizeof(PondScum)) && (p->owner->sanity == POND_SANITY));
p->owner->returnToPond(p);
}
/************************************************************************************
@ -5022,10 +5107,10 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
{
// Add prototype property
JS2Object *result = this;
DEFINE_ROOTKEEPER(rk1, result);
DEFINE_ROOTKEEPER(meta, rk1, result);
JS2Object *protoObj = new SimpleInstance(meta, meta->objectClass->prototype, meta->objectClass);
DEFINE_ROOTKEEPER(rk2, protoObj);
JS2Object *protoObj = new (meta) SimpleInstance(meta, meta->objectClass->prototype, meta->objectClass);
DEFINE_ROOTKEEPER(meta, rk2, protoObj);
meta->createDynamicProperty(this, meta->engine->prototype_StringAtom, OBJECT_TO_JS2VAL(protoObj), ReadWriteAccess, true, false);
meta->createDynamicProperty(protoObj, &meta->world.identifiers["constructor"], OBJECT_TO_JS2VAL(this), ReadWriteAccess, true, false);
@ -5188,7 +5273,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
ParameterFrame *plural = checked_cast<ParameterFrame *>(pluralFrame);
ArgumentsInstance *argsObj = NULL;
DEFINE_ROOTKEEPER(rk2, argsObj);
DEFINE_ROOTKEEPER(meta, rk2, argsObj);
// slotCount is the number of slots required by the parameter frame
uint32 slotCount = (plural->frameSlots) ? plural->frameSlots->size() : 0;
@ -5197,7 +5282,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
if (plural->buildArguments) {
// If we're building an arguments object, the slots for the parameter frame are located
// there so that the arguments object itself can survive beyond the life of the function.
argsObj = new ArgumentsInstance(meta, meta->objectClass->prototype, meta->argumentsClass);
argsObj = new (meta) ArgumentsInstance(meta, meta->objectClass->prototype, meta->argumentsClass);
if (argCount > slotCount)
slotCount = argCount;
if (slotCount) {
@ -5311,86 +5396,6 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
*
************************************************************************************/
Pond JS2Object::pond(POND_SIZE, NULL);
std::list<RootKeeper *> JS2Object::rootList;
// Add a pointer to the (address of a) gc-allocated object to the root list
// (Note - we hand out an iterator, so it's essential to
// use something like std::list that doesn't mess with locations)
JS2Object::RootIterator JS2Object::addRoot(RootKeeper *t)
{
return rootList.insert(rootList.end(), t);
}
// Remove a root pointer
void JS2Object::removeRoot(RootIterator ri)
{
rootList.erase(ri);
}
void JS2Object::clear(JS2Metadata *meta)
{
pond.resetMarks();
JS2Object::mark(meta);
pond.moveUnmarkedToFreeList();
}
// Mark all reachable objects and put the rest back on the freelist
uint32 JS2Object::gc()
{
pond.resetMarks();
// Anything on the root list may also be a pointer to a JS2Object.
for (RootIterator i = rootList.begin(), end = rootList.end(); (i != end); i++) {
RootKeeper *r = *i;
PondScum *scum = NULL;
if (r->is_js2val) {
if (r->js2val_count) {
js2val *valp = *((js2val **)(r->p));
for (uint32 c = 0; c < r->js2val_count; c++)
markJS2Value(*valp++);
}
else {
js2val *valp = (js2val *)(r->p);
markJS2Value(*valp);
}
}
else {
JS2Object **objp = (JS2Object **)(r->p);
if (*objp) {
scum = ((PondScum *)(*objp) - 1);
ASSERT(scum->owner && (scum->getSize() >= sizeof(PondScum)) && (scum->owner->sanity == POND_SANITY));
if (scum->isJS2Object()) {
JS2Object *obj = (JS2Object *)(scum + 1);
GCMARKOBJECT(obj)
}
else
mark(scum + 1);
}
}
}
return pond.moveUnmarkedToFreeList();
}
// Allocate a chunk of size s
void *JS2Object::alloc(size_t s, PondScum::ScumFlag flag)
{
s += sizeof(PondScum);
// make sure that the thing is a multiple of 16 bytes
if (s & 0xF) s += 16 - (s & 0xF);
ASSERT(s <= 0x7FFFFFFF);
void *p = pond.allocFromPond(s, flag);
ASSERT(((ptrdiff_t)p & 0xF) == 0);
return p;
}
// Release a chunk back to it's pond
void JS2Object::unalloc(void *t)
{
PondScum *p = (PondScum *)t - 1;
ASSERT(p->owner && (p->getSize() >= sizeof(PondScum)) && (p->owner->sanity == POND_SANITY));
p->owner->returnToPond(p);
}
void JS2Object::markJS2Value(js2val v)
{
if (JS2VAL_IS_OBJECT(v)) {
@ -5440,7 +5445,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
}
// Allocate from this or the next Pond (make a new one if necessary)
void *Pond::allocFromPond(size_t sz, PondScum::ScumFlag flag)
void *Pond::allocFromPond(JS2Metadata *meta, size_t sz, PondScum::ScumFlag flag)
{
// See if there's room left...
if (sz > pondSize) {
@ -5469,12 +5474,12 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
// ok, then try the next Pond
if (nextPond == NULL) {
// there isn't one; run the gc
uint32 released = JS2Object::gc();
uint32 released = meta->gc();
if (released > sz)
return JS2Object::alloc(sz - sizeof(PondScum), flag);
return meta->alloc(sz - sizeof(PondScum), flag);
nextPond = new Pond(sz, nextPond);
}
return nextPond->allocFromPond(sz, flag);
return nextPond->allocFromPond(meta, sz, flag);
}
// there was room, so acquire it
PondScum *p = (PondScum *)pondTop;
@ -5515,7 +5520,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
}
// Anything left unmarked is now moved to the free list
uint32 Pond::moveUnmarkedToFreeList()
uint32 Pond::moveUnmarkedToFreeList(JS2Metadata *meta)
{
uint32 released = 0;
uint8 *t = pondBottom;
@ -5538,7 +5543,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
t += p->getSize();
}
if (nextPond)
released += nextPond->moveUnmarkedToFreeList();
released += nextPond->moveUnmarkedToFreeList(meta);
return released;
}

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

@ -126,7 +126,6 @@ enum ObjectKind {
LimitedInstanceKind,
EnvironmentKind, // Not an available JS2 runtime kind
MetaDataKind
};
enum Plurality { Singular, Plural };
@ -184,11 +183,11 @@ class Pond {
public:
Pond(size_t sz, Pond *nextPond);
void *allocFromPond(size_t sz, PondScum::ScumFlag flag);
void *allocFromPond(JS2Metadata *meta, size_t sz, PondScum::ScumFlag flag);
uint32 returnToPond(PondScum *p);
void resetMarks();
uint32 moveUnmarkedToFreeList();
uint32 moveUnmarkedToFreeList(JS2Metadata *meta);
uint32 sanity;
@ -206,6 +205,8 @@ public:
#define GCMARKVALUE(v) JS2Object::markJS2Value(v)
class RootKeeper;
typedef std::list<RootKeeper *>::iterator RootIterator;
class JS2Object {
// Every object is either undefined, null, a Boolean,
@ -218,21 +219,12 @@ public:
ObjectKind kind;
static Pond pond;
static std::list<RootKeeper *> rootList;
typedef std::list<RootKeeper *>::iterator RootIterator;
static RootIterator addRoot(RootKeeper *t);
static uint32 gc();
static void clear(JS2Metadata *meta);
static void removeRoot(RootIterator ri);
static void *alloc(size_t s, PondScum::ScumFlag flag);
static void unalloc(void *p);
void *operator new(size_t s) { return alloc(s, PondScum::JS2ObjectFlag); }
void *operator new(size_t s) { ASSERT(false); return 0; }
void operator delete(void *p) { }
void *operator new(size_t s, JS2Metadata *meta);
void operator delete(void *p, JS2Metadata *meta) { ASSERT(false); } // only called if constructor fails
virtual void markChildren() { } // XXX !!!! XXXX these are supposed to not have vtables !!!!
virtual void finalize() { }
@ -243,57 +235,54 @@ public:
static void markJS2Value(js2val v);
};
#ifdef DEBUG
#define ROOTKEEPER_CONSTRUCTOR(type) RootKeeper(type **p, int line, char *pfile) : is_js2val(false), p(p) { init(line, pfile); }
#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj, __LINE__, __FILE__);
#define DEFINE_ARRAYROOTKEEPER(rk_var, obj, count) RootKeeper rk_var(&obj, count, __LINE__, __FILE__);
#else
#define ROOTKEEPER_CONSTRUCTOR(type) RootKeeper(type **p) : is_js2val(false), p(p) { ri = JS2Object::addRoot(this); }
#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj);
#define DEFINE_ARRAYROOTKEEPER(rk_var, obj, count) RootKeeper rk_var(&obj, count);
#endif
class RootKeeper {
public:
ROOTKEEPER_CONSTRUCTOR(JS2Object)
ROOTKEEPER_CONSTRUCTOR(RegExpInstance)
ROOTKEEPER_CONSTRUCTOR(CompoundAttribute)
ROOTKEEPER_CONSTRUCTOR(const String)
ROOTKEEPER_CONSTRUCTOR(String)
ROOTKEEPER_CONSTRUCTOR(ArrayInstance)
ROOTKEEPER_CONSTRUCTOR(BooleanInstance)
ROOTKEEPER_CONSTRUCTOR(StringInstance)
ROOTKEEPER_CONSTRUCTOR(JS2Metadata)
ROOTKEEPER_CONSTRUCTOR(Environment)
ROOTKEEPER_CONSTRUCTOR(Multiname)
ROOTKEEPER_CONSTRUCTOR(ParameterFrame)
ROOTKEEPER_CONSTRUCTOR(SimpleInstance)
ROOTKEEPER_CONSTRUCTOR(FunctionInstance)
ROOTKEEPER_CONSTRUCTOR(DateInstance)
ROOTKEEPER_CONSTRUCTOR(ArgumentsInstance)
#ifdef DEBUG
RootKeeper(js2val *p, int line, char *pfile) : is_js2val(true), js2val_count(0), p(p) { init(line, pfile); }
RootKeeper(js2val **p, uint32 count, int line, char *pfile) : is_js2val(true), js2val_count(count), p(p) { init(line, pfile); }
~RootKeeper() { JS2Object::removeRoot(ri); delete file; }
void RootKeeper::init(int ln, char *pfile)
{
line = ln;
file = new char[strlen(pfile) + 1];
strcpy(file, pfile);
ri = JS2Object::addRoot(this);
}
#define DECLARE_ROOTKEEPER_CONSTRUCTOR(type) RootKeeper(JS2Metadata *meta, type **p, int line, char *pfile);
#define DEFINE_ROOTKEEPER_CONSTRUCTOR(type) inline RootKeeper::RootKeeper(JS2Metadata *meta, type **p, int line, char *pfile) : is_js2val(false), p(p), meta(meta) { init(meta, line, pfile); }
#else
RootKeeper(js2val *p) : is_js2val(true), js2val_count(0), p(p) { ri = JS2Object::addRoot(this); }
RootKeeper(js2val **p, uint32 count) : is_js2val(true), js2val_count(count), p(p) { ri = JS2Object::addRoot(this); }
~RootKeeper() { JS2Object::removeRoot(ri); }
#define DECLARE_ROOTKEEPER_CONSTRUCTOR(type) RootKeeper(JS2Metadata *meta, type **p);
#define DEFINE_ROOTKEEPER_CONSTRUCTOR(type) inline RootKeeper::RootKeeper(JS2Metadata *meta, type **p) : is_js2val(false), p(p), meta(meta) { ri = meta->addRoot(this); }
#endif
JS2Object::RootIterator ri;
DECLARE_ROOTKEEPER_CONSTRUCTOR(JS2Object)
DECLARE_ROOTKEEPER_CONSTRUCTOR(RegExpInstance)
DECLARE_ROOTKEEPER_CONSTRUCTOR(CompoundAttribute)
DECLARE_ROOTKEEPER_CONSTRUCTOR(const String)
DECLARE_ROOTKEEPER_CONSTRUCTOR(String)
DECLARE_ROOTKEEPER_CONSTRUCTOR(ArrayInstance)
DECLARE_ROOTKEEPER_CONSTRUCTOR(BooleanInstance)
DECLARE_ROOTKEEPER_CONSTRUCTOR(StringInstance)
DECLARE_ROOTKEEPER_CONSTRUCTOR(JS2Metadata)
DECLARE_ROOTKEEPER_CONSTRUCTOR(Environment)
DECLARE_ROOTKEEPER_CONSTRUCTOR(Multiname)
DECLARE_ROOTKEEPER_CONSTRUCTOR(ParameterFrame)
DECLARE_ROOTKEEPER_CONSTRUCTOR(SimpleInstance)
DECLARE_ROOTKEEPER_CONSTRUCTOR(FunctionInstance)
DECLARE_ROOTKEEPER_CONSTRUCTOR(DateInstance)
DECLARE_ROOTKEEPER_CONSTRUCTOR(ArgumentsInstance)
#ifdef DEBUG
RootKeeper(JS2Metadata *meta, js2val *p, int line, char *pfile);
RootKeeper(JS2Metadata *meta, js2val **p, uint32 count, int line, char *pfile);
~RootKeeper();
void init(JS2Metadata *meta, int ln, char *pfile);
#else
RootKeeper(JS2Metadata *meta, js2val *p);
RootKeeper(JS2Metadata *meta, js2val **p, uint32 count);
~RootKeeper();
#endif
RootIterator ri;
bool is_js2val;
uint32 js2val_count;
void *p;
JS2Metadata *meta;
#ifdef DEBUG
int line;
@ -301,6 +290,19 @@ public:
#endif
};
#ifdef DEBUG
#define DEFINE_ROOTKEEPER(meta, rk_var, obj) RootKeeper rk_var(meta, &obj, __LINE__, __FILE__);
#define DEFINE_ARRAYROOTKEEPER(meta, rk_var, obj, count) RootKeeper rk_var(meta, &obj, count, __LINE__, __FILE__);
#else
#define DEFINE_ROOTKEEPER(meta, rk_var, obj) RootKeeper rk_var(meta, &obj);
#define DEFINE_ARRAYROOTKEEPER(meta, rk_var, obj, count) RootKeeper rk_var(meta, &obj, count);
#endif
class Attribute : public JS2Object {
public:
@ -313,8 +315,8 @@ public:
virtual ~Attribute() { }
virtual void markChildren() { }
static Attribute *combineAttributes(Attribute *a, Attribute *b);
static CompoundAttribute *toCompoundAttribute(Attribute *a);
static Attribute *combineAttributes(JS2Metadata *meta, Attribute *a, Attribute *b);
static CompoundAttribute *toCompoundAttribute(JS2Metadata *meta, Attribute *a);
virtual CompoundAttribute *toCompoundAttribute() { ASSERT(false); return NULL; }
@ -326,7 +328,7 @@ class Namespace : public Attribute {
public:
Namespace(const String *name) : Attribute(NamespaceAttr), name(name) { }
virtual CompoundAttribute *toCompoundAttribute();
virtual CompoundAttribute *toCompoundAttribute(JS2Metadata *meta);
virtual void markChildren() { if (name) JS2Object::mark(name); }
const String *name; // The namespace's name (used by toString)
@ -361,6 +363,7 @@ public:
Multiname(const String *name, NamespaceList *ns) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList()) { addNamespace(ns); }
Multiname(const String *name, NamespaceList &ns) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList()) { addNamespace(ns); }
Multiname(const String *name, Context *cxt) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList()) { addNamespace(*cxt); }
Multiname(Multiname *m) : JS2Object(MultinameKind), name(m->name), nsList(new NamespaceList()) { addNamespace(m->nsList); }
Multiname(const Multiname& m) : JS2Object(MultinameKind), name(m.name), nsList(new NamespaceList()) { addNamespace(m.nsList); }
void operator =(const Multiname& m) { name = m.name; delete nsList; nsList = new NamespaceList(); addNamespace(m.nsList); }
@ -893,35 +896,35 @@ class ParameterFrame;
class FunctionWrapper {
public:
FunctionWrapper(bool unchecked, ParameterFrame *compileFrame, Environment *env)
FunctionWrapper(JS2Metadata *meta, bool unchecked, ParameterFrame *compileFrame, Environment *env)
: bCon(new BytecodeContainer()),
code(NULL),
alien(NULL),
unchecked(unchecked),
compileFrame(compileFrame),
env(new Environment(env)),
env(new (meta) Environment(env)),
length(0),
resultType(NULL)
{ }
FunctionWrapper(bool unchecked, ParameterFrame *compileFrame, NativeCode *code, Environment *env)
FunctionWrapper(JS2Metadata *meta, bool unchecked, ParameterFrame *compileFrame, NativeCode *code, Environment *env)
: bCon(NULL),
code(code),
alien(NULL),
unchecked(unchecked),
compileFrame(compileFrame),
env(new Environment(env)),
env(new (meta) Environment(env)),
length(0),
resultType(NULL)
{ }
FunctionWrapper(bool unchecked, ParameterFrame *compileFrame, AlienCode *code, Environment *env)
FunctionWrapper(JS2Metadata *meta, bool unchecked, ParameterFrame *compileFrame, AlienCode *code, Environment *env)
: bCon(NULL),
code(NULL),
alien(code),
unchecked(unchecked),
compileFrame(compileFrame),
env(new Environment(env)),
env(new (meta) Environment(env)),
length(0),
resultType(NULL)
{ }
@ -1136,29 +1139,29 @@ class LexicalReference : public Reference {
// of a given set of qualified names. LEXICALREFERENCE tuples arise from evaluating identifiers a and qualified identifiers
// q::a.
public:
LexicalReference(Multiname *mname, bool strict) : variableMultiname(*mname), env(NULL), strict(strict) { }
LexicalReference(const String *name, bool strict) : variableMultiname(name), env(NULL), strict(strict) { }
LexicalReference(const String *name, Namespace *nameSpace, bool strict) : variableMultiname(name, nameSpace), env(NULL), strict(strict) { }
LexicalReference(Multiname *mname, bool strict) : variableMultiname(mname), env(NULL), strict(strict) { }
// LexicalReference(const String *name, bool strict) : variableMultiname(name), env(NULL), strict(strict) { }
// LexicalReference(const String *name, Namespace *nameSpace, bool strict) : variableMultiname(name, nameSpace), env(NULL), strict(strict) { }
virtual ~LexicalReference() { }
Multiname variableMultiname; // A nonempty set of qualified names to which this reference can refer
Multiname *variableMultiname; // A nonempty set of qualified names to which this reference can refer
Environment *env; // The environment in which the reference was created.
bool strict; // The strict setting from the context in effect at the point where the reference was created
void emitInitBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalInit, pos); bCon->addMultiname(new Multiname(variableMultiname)); }
void emitInitBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalInit, pos); bCon->addMultiname(variableMultiname); }
virtual void emitReadBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalRead, pos); bCon->addMultiname(new Multiname(variableMultiname)); }
virtual void emitWriteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalWrite, pos); bCon->addMultiname(new Multiname(variableMultiname)); }
virtual void emitReadForInvokeBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalRef, pos); bCon->addMultiname(new Multiname(variableMultiname)); }
virtual void emitReadBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalRead, pos); bCon->addMultiname(variableMultiname); }
virtual void emitWriteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalWrite, pos); bCon->addMultiname(variableMultiname); }
virtual void emitReadForInvokeBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalRef, pos); bCon->addMultiname(variableMultiname); }
virtual void emitReadForWriteBackBytecode(BytecodeContainer *bCon, size_t pos) { emitReadBytecode(bCon, pos); }
virtual void emitWriteBackBytecode(BytecodeContainer *bCon, size_t pos) { emitWriteBytecode(bCon, pos); }
virtual void emitPostIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPostInc, pos); bCon->addMultiname(new Multiname(variableMultiname)); }
virtual void emitPostDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPostDec, pos); bCon->addMultiname(new Multiname(variableMultiname)); }
virtual void emitPreIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPreInc, pos); bCon->addMultiname(new Multiname(variableMultiname)); }
virtual void emitPreDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPreDec, pos); bCon->addMultiname(new Multiname(variableMultiname)); }
virtual void emitPostIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPostInc, pos); bCon->addMultiname(variableMultiname); }
virtual void emitPostDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPostDec, pos); bCon->addMultiname(variableMultiname); }
virtual void emitPreIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPreInc, pos); bCon->addMultiname(variableMultiname); }
virtual void emitPreDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPreDec, pos); bCon->addMultiname(variableMultiname); }
virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalDelete, pos); bCon->addMultiname(new Multiname(variableMultiname)); }
virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalDelete, pos); bCon->addMultiname(variableMultiname); }
virtual int hasStackEffect() { return 0; }
};
@ -1168,8 +1171,8 @@ class DotReference : public Reference {
// object with one of a given set of qualified names. DOTREFERENCE tuples arise from evaluating subexpressions such as a.b or
// a.q::b.
public:
DotReference(const String *name) : propertyMultiname(name) { }
DotReference(Multiname *mn) : propertyMultiname(*mn) { }
// DotReference(const String *name) : propertyMultiname(name) { }
DotReference(Multiname *mn) : propertyMultiname(mn) { }
virtual ~DotReference() { }
// In this implementation, the base is established by the execution of the preceding expression and
@ -1178,21 +1181,21 @@ public:
// object may be a LIMITEDINSTANCE if a is a super expression, in which case
// the property lookup will be restricted to members defined in proper ancestors
// of base.limit.
Multiname propertyMultiname; // A nonempty set of qualified names to which this reference can refer (b
Multiname *propertyMultiname; // A nonempty set of qualified names to which this reference can refer (b
// qualified with the namespace q or all currently open namespaces in the
// example above)
virtual void emitReadBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotRead, pos); bCon->addMultiname(new Multiname(propertyMultiname)); }
virtual void emitWriteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotWrite, pos); bCon->addMultiname(new Multiname(propertyMultiname)); }
virtual void emitReadForInvokeBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotRef, pos); bCon->addMultiname(new Multiname(propertyMultiname)); }
virtual void emitReadBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotRead, pos); bCon->addMultiname(propertyMultiname); }
virtual void emitWriteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotWrite, pos); bCon->addMultiname(propertyMultiname); }
virtual void emitReadForInvokeBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotRef, pos); bCon->addMultiname(propertyMultiname); }
virtual void emitReadForWriteBackBytecode(BytecodeContainer *bCon, size_t pos) { emitReadForInvokeBytecode(bCon, pos); }
virtual void emitWriteBackBytecode(BytecodeContainer *bCon, size_t pos) { emitWriteBytecode(bCon, pos); }
virtual void emitPostIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPostInc, pos); bCon->addMultiname(new Multiname(propertyMultiname)); }
virtual void emitPostDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPostDec, pos); bCon->addMultiname(new Multiname(propertyMultiname)); }
virtual void emitPreIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPreInc, pos); bCon->addMultiname(new Multiname(propertyMultiname)); }
virtual void emitPreDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPreDec, pos); bCon->addMultiname(new Multiname(propertyMultiname)); }
virtual void emitPostIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPostInc, pos); bCon->addMultiname(propertyMultiname); }
virtual void emitPostDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPostDec, pos); bCon->addMultiname(propertyMultiname); }
virtual void emitPreIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPreInc, pos); bCon->addMultiname(propertyMultiname); }
virtual void emitPreDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPreDec, pos); bCon->addMultiname(propertyMultiname); }
virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotDelete, pos); bCon->addMultiname(new Multiname(propertyMultiname)); }
virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotDelete, pos); bCon->addMultiname(propertyMultiname); }
virtual int hasStackEffect() { return 1; }
};
@ -1409,7 +1412,7 @@ public:
class TrueAttribute : public Attribute {
public:
TrueAttribute() : Attribute(TrueAttr) { }
virtual CompoundAttribute *toCompoundAttribute();
virtual CompoundAttribute *toCompoundAttribute(JS2Metadata *meta);
};
// The 'false' attribute
@ -1456,7 +1459,7 @@ public:
BytecodeContainer *execution_bCon;
};
class JS2Metadata : public JS2Object {
class JS2Metadata {
public:
JS2Metadata(World &world);
@ -1636,8 +1639,6 @@ public:
TargetList targetList; // stack of potential break/continue targets
virtual void markChildren();
bool showTrees; // debug only, causes parse tree dump
Arena *referenceArena; // allocation arena for all reference objects
@ -1649,8 +1650,61 @@ public:
void loadPackage(const String &packageName, const String &filename); // load package from file
String getPackageName(IdentifierList *packageIdList);
// iterates over contained gc allocated objects
void markChildren();
Pond pond;
std::list<RootKeeper *> rootList;
RootIterator addRoot(RootKeeper *t);
uint32 gc();
void clear();
void removeRoot(RootIterator ri);
void *alloc(size_t s, PondScum::ScumFlag flag);
void unalloc(void *p);
};
DEFINE_ROOTKEEPER_CONSTRUCTOR(JS2Object)
DEFINE_ROOTKEEPER_CONSTRUCTOR(RegExpInstance)
DEFINE_ROOTKEEPER_CONSTRUCTOR(CompoundAttribute)
DEFINE_ROOTKEEPER_CONSTRUCTOR(const String)
DEFINE_ROOTKEEPER_CONSTRUCTOR(String)
DEFINE_ROOTKEEPER_CONSTRUCTOR(ArrayInstance)
DEFINE_ROOTKEEPER_CONSTRUCTOR(BooleanInstance)
DEFINE_ROOTKEEPER_CONSTRUCTOR(StringInstance)
DEFINE_ROOTKEEPER_CONSTRUCTOR(JS2Metadata)
DEFINE_ROOTKEEPER_CONSTRUCTOR(Environment)
DEFINE_ROOTKEEPER_CONSTRUCTOR(Multiname)
DEFINE_ROOTKEEPER_CONSTRUCTOR(ParameterFrame)
DEFINE_ROOTKEEPER_CONSTRUCTOR(SimpleInstance)
DEFINE_ROOTKEEPER_CONSTRUCTOR(FunctionInstance)
DEFINE_ROOTKEEPER_CONSTRUCTOR(DateInstance)
DEFINE_ROOTKEEPER_CONSTRUCTOR(ArgumentsInstance)
#ifdef DEBUG
inline RootKeeper::RootKeeper(JS2Metadata *meta, js2val *p, int line, char *pfile) : is_js2val(true), js2val_count(0), p(p), meta(meta) { init(meta, line, pfile); }
inline RootKeeper::RootKeeper(JS2Metadata *meta, js2val **p, uint32 count, int line, char *pfile) : is_js2val(true), js2val_count(count), p(p), meta(meta) { init(meta, line, pfile); }
inline RootKeeper::~RootKeeper() { meta->removeRoot(ri); delete file; }
inline void RootKeeper::init(JS2Metadata *meta, int ln, char *pfile)
{
line = ln;
file = new char[strlen(pfile) + 1];
strcpy(file, pfile);
ri = meta->addRoot(this);
}
#else
inline RootKeeper::RootKeeper(JS2Metadata *meta, js2val *p) : is_js2val(true), js2val_count(0), p(p), meta(meta) { ri = meta->addRoot(this); }
inline RootKeeper::RootKeeper(JS2Metadata *meta, js2val **p, uint32 count) : is_js2val(true), js2val_count(count), p(p), meta(meta) { ri = meta->addRoot(this); }
inline RootKeeper::~RootKeeper() { meta->removeRoot(ri); }
#endif
inline void *JS2Object::operator new(size_t s, JS2Metadata *meta) { return meta->alloc(s, PondScum::JS2ObjectFlag); }
inline char narrow(char16 ch) { return char(ch); }
inline void Setter::mark() { GCMARKOBJECT(type); GCMARKOBJECT(code); }

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

@ -57,7 +57,7 @@ namespace MetaData {
js2val Number_Constructor(JS2Metadata *meta, const js2val thisValue, js2val argv[], uint32 argc)
{
js2val thatValue = OBJECT_TO_JS2VAL(new NumberInstance(meta, meta->numberClass->prototype, meta->numberClass));
js2val thatValue = OBJECT_TO_JS2VAL(new (meta) NumberInstance(meta, meta->numberClass->prototype, meta->numberClass));
NumberInstance *numInst = checked_cast<NumberInstance *>(JS2VAL_TO_OBJECT(thatValue));
if (argc > 0)
@ -184,7 +184,7 @@ namespace MetaData {
};
meta->initBuiltinClass(meta->numberClass, NULL, Number_Constructor, Number_Call);
meta->numberClass->prototype = OBJECT_TO_JS2VAL(new NumberInstance(meta, meta->objectClass->prototype, meta->numberClass));
meta->numberClass->prototype = OBJECT_TO_JS2VAL(new (meta) NumberInstance(meta, meta->objectClass->prototype, meta->numberClass));
meta->initBuiltinClassPrototype(meta->numberClass, &prototypeFunctions[0]);
}

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

@ -114,7 +114,7 @@
{
a = pop();
b = meta->toObject(a);
ForIteratorObject *fi = new ForIteratorObject(JS2VAL_TO_OBJECT(b));
ForIteratorObject *fi = new (meta) ForIteratorObject(JS2VAL_TO_OBJECT(b));
push(OBJECT_TO_JS2VAL(fi));
push(BOOLEAN_TO_JS2VAL(fi->first(this)));
}

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

@ -81,9 +81,9 @@
push(a);
}
else {
pFrame = new ParameterFrame(fWrap->compileFrame);
pFrame = new (meta) ParameterFrame(fWrap->compileFrame);
pFrame->instantiate(meta->env);
baseVal = OBJECT_TO_JS2VAL(new SimpleInstance(meta, protoVal, meta->objectType(protoVal)));
baseVal = OBJECT_TO_JS2VAL(new (meta) SimpleInstance(meta, protoVal, meta->objectType(protoVal)));
pFrame->thisObject = baseVal;
pFrame->assignArguments(meta, obj, base(argCount), argCount, length);
jsr(phase, fWrap->bCon, base(argCount + 1) - execStack, baseVal, fWrap->env); // seems out of order, but we need to catch the current top frame
@ -142,7 +142,7 @@ doCall:
}
else {
if (length || fInst->isMethodClosure || fWrap->compileFrame->buildArguments) {
pFrame = new ParameterFrame(fWrap->compileFrame);
pFrame = new (meta) ParameterFrame(fWrap->compileFrame);
pFrame->instantiate(meta->env);
pFrame->thisObject = a;
// XXX (use fWrap->compileFrame->signature)
@ -160,7 +160,7 @@ doCall:
// need to find a more efficient way of stashing 'this'
// used to be : "meta->env->addFrame(fWrap->compileFrame->prototype);"
// Still need to mark the frame as a runtime frame (see stmtnode::return in validate)
pFrame = new ParameterFrame(a, fWrap->compileFrame->prototype);
pFrame = new (meta) ParameterFrame(a, fWrap->compileFrame->prototype);
pFrame->pluralFrame = fWrap->compileFrame;
meta->env->addFrame(pFrame);
}
@ -261,7 +261,7 @@ doCall:
{
a = pop();
a = meta->toObject(a);
meta->env->addFrame(new WithFrame(JS2VAL_TO_OBJECT(a)));
meta->env->addFrame(new (meta) WithFrame(JS2VAL_TO_OBJECT(a)));
}
break;

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

@ -115,7 +115,7 @@
closure_fi++;
current_fi++;
}
x->fWrap->env = new Environment(meta->env);
x->fWrap->env = new (meta) Environment(meta->env);
}
break;
@ -160,7 +160,7 @@ makeLimitedInstance:
if (JS2VAL_IS_NULL(a))
push(JS2VAL_NULL);
else
push(OBJECT_TO_JS2VAL(new LimitedInstance(JS2VAL_TO_OBJECT(a), limit)));
push(OBJECT_TO_JS2VAL(new (meta) LimitedInstance(JS2VAL_TO_OBJECT(a), limit)));
}
pFrame = NULL;
}
@ -177,7 +177,7 @@ makeLimitedInstance:
{
uint16 argCount = BytecodeContainer::getShort(pc);
pc += sizeof(uint16);
SimpleInstance *sInst = new SimpleInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->objectClass);
SimpleInstance *sInst = new (meta) SimpleInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->objectClass);
baseVal = OBJECT_TO_JS2VAL(sInst);
for (uint16 i = 0; i < argCount; i++) {
a = pop();
@ -196,7 +196,7 @@ makeLimitedInstance:
{
uint16 argCount = BytecodeContainer::getShort(pc);
pc += sizeof(uint16);
ArrayInstance *aInst = new ArrayInstance(meta, OBJECT_TO_JS2VAL(meta->arrayClass->prototype), meta->arrayClass);
ArrayInstance *aInst = new (meta) ArrayInstance(meta, OBJECT_TO_JS2VAL(meta->arrayClass->prototype), meta->arrayClass);
baseVal = OBJECT_TO_JS2VAL(aInst);
for (uint16 i = 0; i < argCount; i++) {
b = pop();

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

@ -158,7 +158,7 @@ namespace MetaData {
RegExpInstance *thisInst = checked_cast<RegExpInstance *>(JS2VAL_TO_OBJECT(thisValue));
const String *str = NULL;
DEFINE_ROOTKEEPER(rk0, str);
DEFINE_ROOTKEEPER(meta, rk0, str);
js2val regexpClassVal = OBJECT_TO_JS2VAL(meta->regexpClass);
js2val result = JS2VAL_NULL;
@ -193,21 +193,21 @@ namespace MetaData {
}
// construct the result array and set $1.. in RegExp statics
ArrayInstance *A = NULL;
DEFINE_ROOTKEEPER(rk, A);
DEFINE_ROOTKEEPER(meta, rk, A);
if (test)
result = JS2VAL_TRUE;
else {
A = new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass);
A = new (meta) ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass);
result = OBJECT_TO_JS2VAL(A);
}
js2val matchStr = meta->engine->allocString(str->substr((uint32)match->startIndex, (uint32)match->endIndex - match->startIndex));
DEFINE_ROOTKEEPER(rk1, matchStr);
DEFINE_ROOTKEEPER(meta, rk1, matchStr);
js2val inputStr = meta->engine->allocString(str);
DEFINE_ROOTKEEPER(rk2, inputStr);
DEFINE_ROOTKEEPER(meta, rk2, inputStr);
if (!test)
meta->createDynamicProperty(A, meta->engine->numberToString((long)0), matchStr, ReadWriteAccess, false, true);
js2val parenStr = JS2VAL_VOID;
DEFINE_ROOTKEEPER(rk3, parenStr);
DEFINE_ROOTKEEPER(meta, rk3, parenStr);
if (match->parenCount == 0) // arrange to set the lastParen to "", not undefined (it's a non-ecma 1.2 thing)
parenStr = meta->engine->allocString("");
for (int32 i = 0; i < match->parenCount; i++) {
@ -245,10 +245,10 @@ namespace MetaData {
meta->classClass->WritePublic(meta, regexpClassVal, meta->engine->allocStringPtr("lastMatch"), true, matchStr);
meta->classClass->WritePublic(meta, regexpClassVal, meta->engine->allocStringPtr("lastParen"), true, parenStr);
js2val leftContextVal = meta->engine->allocString(str->substr(0, (uint32)match->startIndex));
DEFINE_ROOTKEEPER(rk4, leftContextVal);
DEFINE_ROOTKEEPER(meta, rk4, leftContextVal);
meta->classClass->WritePublic(meta, regexpClassVal, meta->engine->allocStringPtr("leftContext"), true, leftContextVal);
js2val rightContextVal = meta->engine->allocString(str->substr((uint32)match->endIndex, (uint32)str->length() - match->endIndex));
DEFINE_ROOTKEEPER(rk5, rightContextVal);
DEFINE_ROOTKEEPER(meta, rk5, rightContextVal);
meta->classClass->WritePublic(meta, regexpClassVal, meta->engine->allocStringPtr("rightContext"), true, rightContextVal);
}
return result;
@ -288,9 +288,9 @@ namespace MetaData {
uint32 flags = 0;
const String *regexpStr = meta->engine->Empty_StringAtom;
DEFINE_ROOTKEEPER(rk1, regexpStr);
DEFINE_ROOTKEEPER(meta, rk1, regexpStr);
const String *flagStr = meta->engine->Empty_StringAtom;
DEFINE_ROOTKEEPER(rk2, flagStr);
DEFINE_ROOTKEEPER(meta, rk2, flagStr);
if (argc > 0) {
if (JS2VAL_IS_OBJECT(argv[0]) && !JS2VAL_IS_NULL(argv[0])
&& (JS2VAL_TO_OBJECT(argv[0])->kind == SimpleInstanceKind)
@ -335,16 +335,16 @@ namespace MetaData {
js2val RegExp_ConstructorOpt(JS2Metadata *meta, const js2val /* thisValue */, js2val *argv, uint32 argc, bool flat)
{
RegExpInstance *thisInst = new RegExpInstance(meta, meta->regexpClass->prototype, meta->regexpClass);
DEFINE_ROOTKEEPER(rk, thisInst);
RegExpInstance *thisInst = new (meta) RegExpInstance(meta, meta->regexpClass->prototype, meta->regexpClass);
DEFINE_ROOTKEEPER(meta, rk, thisInst);
js2val thatValue = OBJECT_TO_JS2VAL(thisInst);
return RegExp_compile_sub(meta, thatValue, argv, argc, flat);
}
js2val RegExp_Constructor(JS2Metadata *meta, const js2val /* thisValue */, js2val *argv, uint32 argc)
{
RegExpInstance *thisInst = new RegExpInstance(meta, meta->regexpClass->prototype, meta->regexpClass);
DEFINE_ROOTKEEPER(rk, thisInst);
RegExpInstance *thisInst = new (meta) RegExpInstance(meta, meta->regexpClass->prototype, meta->regexpClass);
DEFINE_ROOTKEEPER(meta, rk, thisInst);
js2val thatValue = OBJECT_TO_JS2VAL(thisInst);
return RegExp_compile_sub(meta, thatValue, argv, argc, false);
}
@ -423,13 +423,13 @@ namespace MetaData {
for (i = 0; i < INSTANCE_VAR_COUNT; i++)
{
Multiname *mn = new Multiname(meta->engine->allocStringPtr(RegExpInstanceVars[i].name), &publicNamespaceList);
Multiname *mn = new (meta) Multiname(meta->engine->allocStringPtr(RegExpInstanceVars[i].name), &publicNamespaceList);
InstanceMember *m = new InstanceVariable(mn, RegExpInstanceVars[i].type, false, true, true, meta->regexpClass->slotCount++);
meta->defineInstanceMember(meta->regexpClass, &meta->cxt, mn->name, *mn->nsList, Attribute::NoOverride, false, m, 0);
}
RegExpInstance *reProto = new RegExpInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->regexpClass);
DEFINE_ROOTKEEPER(rk, reProto);
RegExpInstance *reProto = new (meta) RegExpInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->regexpClass);
DEFINE_ROOTKEEPER(meta, rk, reProto);
meta->regexpClass->prototype = OBJECT_TO_JS2VAL(reProto);
meta->initBuiltinClassPrototype(meta->regexpClass, &prototypeFunctions[0]);

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

@ -57,9 +57,9 @@ namespace MetaData {
js2val String_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val *argv, uint32 argc)
{
js2val thatValue = OBJECT_TO_JS2VAL(new StringInstance(meta, meta->stringClass->prototype, meta->stringClass));
js2val thatValue = OBJECT_TO_JS2VAL(new (meta) StringInstance(meta, meta->stringClass->prototype, meta->stringClass));
StringInstance *strInst = checked_cast<StringInstance *>(JS2VAL_TO_OBJECT(thatValue));
DEFINE_ROOTKEEPER(rk, strInst);
DEFINE_ROOTKEEPER(meta, rk, strInst);
if (argc > 0)
strInst->mValue = meta->engine->allocStringPtr(meta->toString(argv[0]));
else
@ -120,7 +120,7 @@ static js2val String_valueOf(JS2Metadata *meta, const js2val thisValue, js2val *
static js2val String_search(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)
{
const String *str = NULL;
DEFINE_ROOTKEEPER(rk, str);
DEFINE_ROOTKEEPER(meta, rk, str);
str = meta->toString(thisValue);
js2val S = STRING_TO_JS2VAL(str);
@ -158,7 +158,7 @@ static js2val String_search(JS2Metadata *meta, const js2val thisValue, js2val *a
static js2val String_match(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)
{
js2val S = STRING_TO_JS2VAL(meta->toString(thisValue));
DEFINE_ROOTKEEPER(rk0, S);
DEFINE_ROOTKEEPER(meta, rk0, S);
js2val regexp = argv[0];
if ((argc == 0) || (meta->objectType(argv[0]) != meta->regexpClass)) {
@ -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);
DEFINE_ROOTKEEPER(meta, rk1, thisInst);
JS2RegExp *re = thisInst->mRegExp;
if ((re->flags & JSREG_GLOB) == 0) {
return RegExp_exec(meta, regexp, &S, 1);
@ -180,7 +180,7 @@ static js2val String_match(JS2Metadata *meta, const js2val thisValue, js2val *ar
bool globalMultiline = meta->toBoolean(globalMultilineVal);
ArrayInstance *A = NULL;
DEFINE_ROOTKEEPER(rk2, A);
DEFINE_ROOTKEEPER(meta, rk2, A);
int32 index = 0;
int32 lastIndex = 0;
while (true) {
@ -192,9 +192,9 @@ 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));
DEFINE_ROOTKEEPER(rk3, matchStr);
DEFINE_ROOTKEEPER(meta, rk3, matchStr);
if (A == NULL)
A = new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass);
A = new (meta) ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass);
meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToString(index), true, matchStr);
index++;
}
@ -278,7 +278,7 @@ static const String interpretDollar(JS2Metadata *meta, const String *replaceStr,
static js2val String_replace(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)
{
const String *S = meta->toString(thisValue);
DEFINE_ROOTKEEPER(rk1, S);
DEFINE_ROOTKEEPER(meta, rk1, S);
js2val searchValue = JS2VAL_UNDEFINED;
js2val replaceValue = JS2VAL_UNDEFINED;
@ -297,7 +297,7 @@ static js2val String_replace(JS2Metadata *meta, const js2val thisValue, js2val *
if (argc > 1) replaceValue = argv[1];
const String *replaceStr = meta->toString(replaceValue);
DEFINE_ROOTKEEPER(rk2, replaceStr);
DEFINE_ROOTKEEPER(meta, rk2, replaceStr);
RegExpInstance *reInst = checked_cast<RegExpInstance *>(JS2VAL_TO_OBJECT(searchValue));
@ -397,11 +397,11 @@ static void regexpSplitMatch(JS2Metadata *meta, const String *S, uint32 q, JS2Re
static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)
{
const String *S = meta->toString(thisValue);
DEFINE_ROOTKEEPER(rk0, S);
DEFINE_ROOTKEEPER(meta, rk0, S);
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
js2val result = OBJECT_TO_JS2VAL(new (meta) ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass));
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
DEFINE_ROOTKEEPER(rk1, A);
DEFINE_ROOTKEEPER(meta, rk1, A);
setLength(meta, A, 0);
uint32 lim;
@ -418,7 +418,7 @@ static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *ar
JS2RegExp *RE = NULL;
const String *R = NULL;
DEFINE_ROOTKEEPER(rk2, R);
DEFINE_ROOTKEEPER(meta, rk2, R);
if (meta->objectType(separatorV) == meta->regexpClass)
RE = (checked_cast<RegExpInstance *>(JS2VAL_TO_OBJECT(separatorV)))->mRegExp;
else
@ -447,9 +447,9 @@ static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *ar
}
String *T = NULL;
DEFINE_ROOTKEEPER(rk3, T);
DEFINE_ROOTKEEPER(meta, rk3, T);
js2val v = JS2VAL_VOID;
DEFINE_ROOTKEEPER(rk4, v);
DEFINE_ROOTKEEPER(meta, rk4, v);
while (true) {
uint32 q = p;
@ -491,7 +491,7 @@ step11:
static js2val String_charAt(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)
{
const String *str = meta->toString(thisValue);
DEFINE_ROOTKEEPER(rk, str);
DEFINE_ROOTKEEPER(meta, rk, str);
uint32 pos = 0;
if (argc > 0)
@ -507,7 +507,7 @@ static js2val String_charAt(JS2Metadata *meta, const js2val thisValue, js2val *a
static js2val String_charCodeAt(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)
{
const String *str = meta->toString(thisValue);
DEFINE_ROOTKEEPER(rk, str);
DEFINE_ROOTKEEPER(meta, rk, str);
float64 posd = 0.0;
if (argc > 0)
@ -522,9 +522,9 @@ static js2val String_charCodeAt(JS2Metadata *meta, const js2val thisValue, js2va
static js2val String_concat(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)
{
const String *str = meta->toString(thisValue);
DEFINE_ROOTKEEPER(rk1, str);
DEFINE_ROOTKEEPER(meta, rk1, str);
String *result = meta->engine->allocStringPtr(str);
DEFINE_ROOTKEEPER(rk2, result);
DEFINE_ROOTKEEPER(meta, rk2, result);
for (uint32 i = 0; i < argc; i++) {
*result += *meta->toString(argv[i]);
@ -539,9 +539,9 @@ static js2val String_indexOf(JS2Metadata *meta, const js2val thisValue, js2val *
return meta->engine->allocNumber(-1.0);
const String *str = meta->toString(thisValue);
DEFINE_ROOTKEEPER(rk1, str);
DEFINE_ROOTKEEPER(meta, rk1, str);
const String *searchStr = meta->toString(argv[0]);
DEFINE_ROOTKEEPER(rk2, searchStr);
DEFINE_ROOTKEEPER(meta, rk2, searchStr);
uint32 pos = 0;
if (argc > 1) {
@ -568,9 +568,9 @@ static js2val String_lastIndexOf(JS2Metadata *meta, const js2val thisValue, js2v
return meta->engine->allocNumber(-1.0);
const String *str = meta->toString(thisValue);
DEFINE_ROOTKEEPER(rk1, str);
DEFINE_ROOTKEEPER(meta, rk1, str);
const String *searchStr = meta->toString(argv[0]);
DEFINE_ROOTKEEPER(rk2, searchStr);
DEFINE_ROOTKEEPER(meta, rk2, searchStr);
uint32 pos = str->size();
if (argc > 1) {
@ -601,11 +601,11 @@ static js2val String_localeCompare(JS2Metadata * /* meta */, const js2val /*this
static js2val String_toLowerCase(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
{
const String *str = meta->toString(thisValue);
DEFINE_ROOTKEEPER(rk1, str);
DEFINE_ROOTKEEPER(meta, rk1, str);
js2val S = STRING_TO_JS2VAL(str);
String *result = meta->engine->allocStringPtr(str);
DEFINE_ROOTKEEPER(rk2, result);
DEFINE_ROOTKEEPER(meta, rk2, result);
for (String::iterator i = result->begin(), end = result->end(); i != end; i++)
*i = toLower(*i);
@ -615,11 +615,11 @@ static js2val String_toLowerCase(JS2Metadata *meta, const js2val thisValue, js2v
static js2val String_toUpperCase(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
{
const String *str = meta->toString(thisValue);
DEFINE_ROOTKEEPER(rk1, str);
DEFINE_ROOTKEEPER(meta, rk1, str);
js2val S = STRING_TO_JS2VAL(str);
String *result = meta->engine->allocStringPtr(JS2VAL_TO_STRING(S));
DEFINE_ROOTKEEPER(rk2, result);
DEFINE_ROOTKEEPER(meta, rk2, result);
for (String::iterator i = result->begin(), end = result->end(); i != end; i++)
*i = toUpper(*i);
@ -650,7 +650,7 @@ static js2val String_toUpperCase(JS2Metadata *meta, const js2val thisValue, js2v
static js2val String_slice(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)
{
const String *sourceString = meta->toString(thisValue);
DEFINE_ROOTKEEPER(rk1, sourceString);
DEFINE_ROOTKEEPER(meta, rk1, sourceString);
uint32 sourceLength = sourceString->size();
uint32 start, end;
@ -723,7 +723,7 @@ static js2val String_slice(JS2Metadata *meta, const js2val thisValue, js2val *ar
static js2val String_substring(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc)
{
const String *sourceString = meta->toString(thisValue);
DEFINE_ROOTKEEPER(rk1, sourceString);
DEFINE_ROOTKEEPER(meta, rk1, sourceString);
uint32 sourceLength = sourceString->size();
uint32 start, end;
@ -803,8 +803,8 @@ void initStringObject(JS2Metadata *meta)
{ NULL }
};
StringInstance *strInst = new StringInstance(meta, meta->objectClass->prototype, meta->stringClass);
DEFINE_ROOTKEEPER(rk1, strInst);
StringInstance *strInst = new (meta) StringInstance(meta, meta->objectClass->prototype, meta->stringClass);
DEFINE_ROOTKEEPER(meta, rk1, strInst);
meta->stringClass->prototype = OBJECT_TO_JS2VAL(strInst);
strInst->mValue = meta->engine->allocStringPtr("");

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

@ -146,7 +146,7 @@ NPBool nsPluginInstance::init(NPWindow* aWindow)
world = new World();
metadata = new JavaScript::MetaData::JS2Metadata(*world);
spiderMonkeyClass = new JS2SpiderMonkeyClass(&world->identifiers[widenCString("SpiderMonkey")]);
spiderMonkeyClass = new (metadata) JS2SpiderMonkeyClass(&world->identifiers[widenCString("SpiderMonkey")]);
mInitialized = TRUE;
@ -218,7 +218,7 @@ void nsPluginInstance::SetDocument(nsISupports *aDocument)
if (NS_SUCCEEDED(xpc->WrapNative(aJSContext, aJSContext->globalObject, doc, nsIDOMDocument::GetIID(), &wrappedDoc))) {
JSObject *obj;
if (NS_SUCCEEDED(wrappedDoc->GetJSObject(&obj))) {
SpiderMonkeyInstance *smInst = new SpiderMonkeyInstance(metadata, metadata->objectClass->prototype, spiderMonkeyClass);
SpiderMonkeyInstance *smInst = new (metadata) SpiderMonkeyInstance(metadata, metadata->objectClass->prototype, spiderMonkeyClass);
smInst->jsObject = obj;
smInst->pluginInstance = this;
metadata->createDynamicProperty(metadata->glob, "document", OBJECT_TO_JS2VAL(smInst), ReadWriteAccess, true, false);
@ -399,17 +399,17 @@ js2val callJSFunction(JS2Metadata *meta, FunctionInstance *fnInst, const js2val
if (argc) {
outgoingArgs = new jsval[argc];
for (uint32 i = 0; i < argc; i++) {
if (!plug->convertJS2ValueToJSValue(meta, aJSContext, argv[i], &outgoingArgs[i]))
if (!plug->convertJS2ValueToJSValue(aJSContext, argv[i], &outgoingArgs[i]))
goto out;
}
}
jsval resultVal;
jsval thisVal;
if (!plug->convertJS2ValueToJSValue(meta, aJSContext, thisValue, &thisVal))
if (!plug->convertJS2ValueToJSValue(aJSContext, thisValue, &thisVal))
goto out;
ASSERT(JSVAL_IS_OBJECT(thisVal));
if (JS_CallFunctionValue(aJSContext, JSVAL_TO_OBJECT(thisVal), OBJECT_TO_JSVAL(smFun->jsObject), argc, outgoingArgs, &resultVal))
plug->convertJSValueToJS2Value(meta, aJSContext, resultVal, &result);
plug->convertJSValueToJS2Value(aJSContext, resultVal, &result);
NS_RELEASE(aCurrentNativeCallContext);
}
}
@ -420,17 +420,17 @@ out:
return result;
}
bool nsPluginInstance::convertJSValueToJS2Value(JavaScript::MetaData::JS2Metadata *meta, JSContext *cx, jsval v, js2val *rval)
bool nsPluginInstance::convertJSValueToJS2Value(JSContext *cx, jsval v, js2val *rval)
{
bool result = true;
if (JSVAL_IS_INT(v))
*rval = INT_TO_JS2VAL(JSVAL_TO_INT(v));
else
if (JSVAL_IS_NUMBER(v))
*rval = meta->engine->allocNumber(*JSVAL_TO_DOUBLE(v));
*rval = metadata->engine->allocNumber(*JSVAL_TO_DOUBLE(v));
else
if (JSVAL_IS_STRING(v))
*rval = meta->engine->allocString(JS_GetStringChars(JSVAL_TO_STRING(v)), JS_GetStringLength(JSVAL_TO_STRING(v)));
*rval = metadata->engine->allocString(JS_GetStringChars(JSVAL_TO_STRING(v)), JS_GetStringLength(JSVAL_TO_STRING(v)));
else
if (JSVAL_IS_BOOLEAN(v))
*rval = BOOLEAN_TO_JS2VAL(JSVAL_TO_BOOLEAN(v));
@ -444,15 +444,17 @@ bool nsPluginInstance::convertJSValueToJS2Value(JavaScript::MetaData::JS2Metadat
if (JSVAL_IS_OBJECT(v)) {
JSObject *jsObj = JSVAL_TO_OBJECT(v);
if (JS_ObjectIsFunction(cx, jsObj)) {
SpiderMonkeyFunction *smFun = new SpiderMonkeyFunction(meta);
smFun->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_VOID, true), callJSFunction, meta->env);
SpiderMonkeyFunction *smFun = new (metadata) SpiderMonkeyFunction(metadata);
JS2Object *rooter = smFun;
DEFINE_ROOTKEEPER(metadata, rk, rooter);
smFun->fWrap = new FunctionWrapper(metadata, true, new (metadata) ParameterFrame(JS2VAL_VOID, true), callJSFunction, metadata->env);
smFun->fWrap->length = 0;
smFun->jsObject = jsObj;
smFun->pluginInstance = this;
*rval = OBJECT_TO_JS2VAL(smFun);
}
else {
SpiderMonkeyInstance *smInst = new SpiderMonkeyInstance(meta, meta->objectClass->prototype, spiderMonkeyClass);
SpiderMonkeyInstance *smInst = new (metadata) SpiderMonkeyInstance(metadata, metadata->objectClass->prototype, spiderMonkeyClass);
smInst->jsObject = jsObj;
smInst->pluginInstance = this;
*rval = OBJECT_TO_JS2VAL(smInst);
@ -463,7 +465,7 @@ bool nsPluginInstance::convertJSValueToJS2Value(JavaScript::MetaData::JS2Metadat
return result;
}
bool nsPluginInstance::convertJS2ValueToJSValue(JavaScript::MetaData::JS2Metadata *meta, JSContext *cx, js2val v, jsval *rval)
bool nsPluginInstance::convertJS2ValueToJSValue(JSContext *cx, js2val v, jsval *rval)
{
bool result = true;
if (JS2VAL_IS_INT(v))
@ -517,7 +519,7 @@ bool JS2SpiderMonkeyClass::Read(JS2Metadata *meta, js2val *base, Multiname *mult
std::string str(multiname->name->length(), char());
std::transform(multiname->name->begin(), multiname->name->end(), str.begin(), narrow);
if (JS_GetProperty(aJSContext, smInst->jsObject, str.c_str(), &v))
result = plug->convertJSValueToJS2Value(meta, aJSContext, v, rval);
result = plug->convertJSValueToJS2Value(aJSContext, v, rval);
NS_RELEASE(aCurrentNativeCallContext);
}
}
@ -545,7 +547,7 @@ bool JS2SpiderMonkeyClass::Write(JS2Metadata *meta, js2val base, Multiname *mult
JSContext *aJSContext;
if (NS_SUCCEEDED(aCurrentNativeCallContext->GetJSContext(&aJSContext))) {
jsval v;
if (plug->convertJS2ValueToJSValue(meta, aJSContext, newValue, &v)) {
if (plug->convertJS2ValueToJSValue(aJSContext, newValue, &v)) {
std::string str(multiname->name->length(), char());
std::transform(multiname->name->begin(), multiname->name->end(), str.begin(), narrow);
if (JS_SetProperty(aJSContext, smInst->jsObject, str.c_str(), &v))