This commit is contained in:
rogerl%netscape.com 2003-04-11 18:53:59 +00:00
Родитель 967e208b55
Коммит 5ad3348af0
6 изменённых файлов: 89 добавлений и 49 удалений

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

@ -72,7 +72,7 @@ static void initConsole(StringPtr consoleName,
#endif
JavaScript::World world;
JavaScript::World *world = new World();
JavaScript::Arena a;
namespace JavaScript {
@ -114,7 +114,7 @@ static int readEvalPrint(FILE *in)
appendChars(buffer, line.data(), line.size());
try {
Pragma::Flags flags = Pragma::es4;
Parser p(world, a, flags, buffer, ConsoleName);
Parser p(*world, a, flags, buffer, ConsoleName);
if (showTokens) {
Lexer &l = p.lexer;
while (true) {
@ -392,7 +392,7 @@ int main(int argc, char **argv)
DEFINE_ROOTKEEPER(rk, metadata);
metadata = new MetaData::JS2Metadata(world);
metadata = new MetaData::JS2Metadata(*world);
metadata->addGlobalObjectFunction("print", print, 1);
metadata->addGlobalObjectFunction("load", load, 1);
@ -413,6 +413,8 @@ int main(int argc, char **argv)
if (doInteractive)
result = readEvalPrint(stdin);
delete metadata;
world->identifiers.clear();
delete world;
return result;
}
catch (Exception &e) {

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

@ -196,13 +196,13 @@ namespace MetaData {
if (*float64Table[hash] == x)
return float64Table[hash];
else {
float64 *p = (float64 *)JS2Object::alloc(sizeof(float64), false);
float64 *p = (float64 *)JS2Object::alloc(sizeof(float64), PondScum::GenericFlag);
*p = x;
return p;
}
}
else {
float64 *p = (float64 *)JS2Object::alloc(sizeof(float64), false);
float64 *p = (float64 *)JS2Object::alloc(sizeof(float64), PondScum::GenericFlag);
float64Table[hash] = p;
*p = x;
return p;
@ -211,28 +211,31 @@ namespace MetaData {
String *JS2Engine::allocStringPtr(const char *s)
{
String *p = (String *)(JS2Object::alloc(sizeof(String), false));
String *p = (String *)(JS2Object::alloc(sizeof(String), PondScum::StringFlag));
size_t len = strlen(s);
String *result = new (p) String(len, uni::null);
std::transform(s, s+len, result->begin(), widen);
for (int i = 0; i < len; i++) {
(*result)[i] = widen(s[i]);
}
// std::transform(s, s+len, result->begin(), widen);
return result;
}
String *JS2Engine::allocStringPtr(const String *s)
{
String *p = (String *)(JS2Object::alloc(sizeof(String), false));
String *p = (String *)(JS2Object::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), false));
String *p = (String *)(JS2Object::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), false));
String *p = (String *)(JS2Object::alloc(sizeof(String), PondScum::StringFlag));
String *result = new (p) String(*s1);
result->append(*s2);
return result;
@ -257,7 +260,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), false));
uint64 *p = (uint64 *)(JS2Object::alloc(sizeof(uint64), PondScum::GenericFlag));
*p = x;
return ULONG_TO_JS2VAL(p);
@ -266,7 +269,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), false));
int64 *p = (int64 *)(JS2Object::alloc(sizeof(int64), PondScum::GenericFlag));
*p = x;
return LONG_TO_JS2VAL(p);
}
@ -274,7 +277,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), false));
float32 *p = (float32 *)(JS2Object::alloc(sizeof(float32), PondScum::GenericFlag));
*p = x;
return FLOAT_TO_JS2VAL(p);
}
@ -393,7 +396,7 @@ namespace MetaData {
}
#define INIT_STRINGATOM(n) n##_StringAtom(allocStringPtr(&world.identifiers[#n]))
#define INIT_STRINGATOM(n) n##_StringAtom(allocStringPtr(#n))
JS2Engine::JS2Engine(World &world)
: meta(NULL),
@ -428,7 +431,7 @@ namespace MetaData {
for (int i = 0; i < 256; i++)
float64Table[i] = NULL;
float64 *p = (float64 *)JS2Object::alloc(sizeof(float64), false);
float64 *p = (float64 *)JS2Object::alloc(sizeof(float64), PondScum::GenericFlag);
*p = nan;
nanValue = DOUBLE_TO_JS2VAL(p);
posInfValue = DOUBLE_TO_JS2VAL(allocNumber(positiveInfinity));

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

@ -2949,11 +2949,18 @@ doUnary:
break;
}
m->multiname = new Multiname(definedMultiname);
InstanceBinding *ib = new InstanceBinding(access, m);
if (ibeP) {
for (NamespaceListIterator nli = definedMultiname.nsList->begin(), nlend = definedMultiname.nsList->end(); (nli != nlend); nli++) {
(*ibeP)->bindingList.push_back(InstanceBindingEntry::NamespaceBinding(*nli, ib));
InstanceBindingEntry *ibe;
if (ibeP == NULL) {
ibe = new InstanceBindingEntry(*id);
c->instanceBindings.insert(*id, ibe);
}
else
ibe = *ibeP;
for (NamespaceListIterator nli = definedMultiname.nsList->begin(), nlend = definedMultiname.nsList->end(); (nli != nlend); nli++) {
// XXX here and in defineLocal... why a new binding for each namespace?
// (other than it would mess up the destructor sequence :-)
InstanceBinding *ib = new InstanceBinding(access, m);
ibe->bindingList.push_back(InstanceBindingEntry::NamespaceBinding(*nli, ib));
}
return mOverridden;
}
@ -3907,14 +3914,15 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
pf = protoFunctions;
if (pf) {
while (pf->name) {
/*
SimpleInstance *callInst = new SimpleInstance(this, functionClass->prototype, functionClass);
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code, env);
Multiname *mn = new Multiname(&world.identifiers[pf->name], publicNamespaceList);
InstanceMember *m = new InstanceMethod(mn, callInst, true, false);
defineInstanceMember(builtinClass, &cxt, mn->name, *mn->nsList, Attribute::NoOverride, false, m, 0);
*/
FunctionInstance *fInst = new FunctionInstance(this, functionClass->prototype, functionClass);
fInst->fWrap = callInst->fWrap;
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code, env);
createDynamicProperty(JS2VAL_TO_OBJECT(builtinClass->prototype), &world.identifiers[pf->name], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false);
createDynamicProperty(fInst, engine->length_StringAtom, INT_TO_JS2VAL(pf->length), ReadAccess, true, false);
pf++;
@ -4110,7 +4118,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
}
}
void SimpleInstance::finalize()
SimpleInstance::~SimpleInstance()
{
for (LocalBindingIterator bi = localBindings.begin(), bend = localBindings.end(); (bi != bend); bi++) {
LocalBindingEntry *lbe = *bi;
@ -4121,6 +4129,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
delete lbe;
}
delete [] slots;
if (fWrap)
delete fWrap;
}
/************************************************************************************
@ -4208,6 +4218,18 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
}
/************************************************************************************
*
* InstanceMethod
*
************************************************************************************/
InstanceMethod::~InstanceMethod()
{
delete fInst;
}
/************************************************************************************
*
* MethodClosure
@ -4500,13 +4522,13 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
}
// Allocate a chunk of size s
void *JS2Object::alloc(size_t s, bool isJS2Object)
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, isJS2Object);
void *p = pond.allocFromPond(s, flag);
ASSERT(((ptrdiff_t)p & 0xF) == 0);
return p;
}
@ -4568,7 +4590,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, bool isJS2Object)
void *Pond::allocFromPond(size_t sz, PondScum::ScumFlag flag)
{
// See if there's room left...
if (sz > pondSize) {
@ -4584,10 +4606,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
freeHeader = (PondScum *)(p->owner);
p->owner = this;
p->resetMark(); // might have lingering mark from previous gc
if (isJS2Object)
p->setIsJS2Object();
else
p->clearIsJS2Object();
p->clearFlags();
p->setFlag(flag);
#ifdef DEBUG
memset((p + 1), 0xB7, p->getSize() - sizeof(PondScum));
#endif
@ -4601,10 +4621,10 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
// there isn't one; run the gc
uint32 released = JS2Object::gc();
if (released > sz)
return JS2Object::alloc(sz - sizeof(PondScum), isJS2Object);
return JS2Object::alloc(sz - sizeof(PondScum), flag);
nextPond = new Pond(sz, nextPond);
}
return nextPond->allocFromPond(sz, isJS2Object);
return nextPond->allocFromPond(sz, flag);
}
// there was room, so acquire it
PondScum *p = (PondScum *)pondTop;
@ -4613,10 +4633,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
#endif
p->owner = this;
p->setSize(sz);
if (isJS2Object)
p->setIsJS2Object();
else
p->clearIsJS2Object();
p->setFlag(flag);
pondTop += sz;
pondSize -= sz;
return (p + 1);
@ -4660,6 +4677,11 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
obj->finalize();
delete obj;
}
else
if (p->isString()) {
String *s = (String *)(p + 1);
s->erase();
}
released += returnToPond(p);
}
t += p->getSize();

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

@ -148,23 +148,31 @@ enum Hint { NoHint, NumberHint, StringHint };
class PondScum {
public:
typedef enum { JS2ObjectFlag, StringFlag, GenericFlag } ScumFlag;
void resetMark() { markFlag = 0; }
void mark() { markFlag = 1; }
bool isMarked() { return (markFlag != 0); }
void setIsJS2Object() { js2Flag = 1; }
void clearIsJS2Object() { js2Flag = 0; }
bool isJS2Object() { return (js2Flag != 0); }
void setFlag(ScumFlag f){ flag = f; }
void setIsJS2Object() { flag = JS2ObjectFlag; }
bool isJS2Object() { return (flag == JS2ObjectFlag); }
void setIsString() { flag = StringFlag; }
bool isString() { return (flag == StringFlag); }
void clearFlags() { flag = GenericFlag; }
uint32 getSize() { return size; }
void setSize(uint32 sz) { ASSERT(sz < JS_BIT(30)); size = sz; }
void setSize(uint32 sz) { ASSERT(sz < JS_BIT(29)); size = sz; }
Pond *owner; // for a piece of scum in use, this points to it's own Pond
// otherwise it's a link to the next item on the free list
private:
unsigned int markFlag:1;
unsigned int js2Flag:1;
unsigned int size:30;
ScumFlag flag:2;
unsigned int size:29;
};
// A pond is a place to get chunks of PondScum from and to return them to
@ -174,7 +182,7 @@ class Pond {
public:
Pond(size_t sz, Pond *nextPond);
void *allocFromPond(size_t sz, bool isJS2Object);
void *allocFromPond(size_t sz, PondScum::ScumFlag flag);
uint32 returnToPond(PondScum *p);
void resetMarks();
@ -223,10 +231,10 @@ public:
static void clear(JS2Metadata *meta);
static void removeRoot(RootIterator ri);
static void *alloc(size_t s, bool isJS2Object);
static void *alloc(size_t s, PondScum::ScumFlag flag);
static void unalloc(void *p);
void *operator new(size_t s) { return alloc(s, true); }
void *operator new(size_t s) { return alloc(s, PondScum::JS2ObjectFlag); }
void operator delete(void *p) { }
virtual void markChildren() { } // XXX !!!! XXXX these are supposed to not have vtables !!!!
@ -516,6 +524,7 @@ public:
// Invokable *code; // This method itself (a callable object); null if this method is abstract
SimpleInstance *fInst;
virtual ~InstanceMethod();
virtual void mark();
};
@ -756,6 +765,8 @@ public:
FunctionWrapper(bool unchecked, ParameterFrame *compileFrame, NativeCode *code, Environment *env)
: bCon(NULL), code(code), unchecked(unchecked), compileFrame(compileFrame), env(new Environment(env)) { }
virtual ~FunctionWrapper() { if (bCon) delete bCon; }
BytecodeContainer *bCon;
NativeCode *code;
bool unchecked; // true if the function is untyped, non-method, normal
@ -778,8 +789,7 @@ public:
FunctionWrapper *fWrap;
virtual void markChildren();
virtual void finalize();
virtual ~SimpleInstance() { }
virtual ~SimpleInstance();
};
// Date instances are simple instances created by the Date class, they have an extra field

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

@ -327,8 +327,10 @@ const uchar JS::Token::kindFlags[kindsEnd] = {
void JS::Token::initKeywords(World &world)
{
const char *const*keywordName = kindNames + keywordsBegin;
for (Kind kind = keywordsBegin; kind != keywordsEnd; kind = Kind(kind+1))
world.identifiers[widenCString(*keywordName++)].tokenKind = kind;
for (Kind kind = keywordsBegin; kind != keywordsEnd; kind = Kind(kind+1)) {
String s = widenCString(*keywordName++);
world.identifiers[s].tokenKind = kind;
}
}

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

@ -70,6 +70,7 @@ namespace JavaScript {
public:
StringAtom &operator[](const String &s);
StringAtom &operator[](const char *s) {return operator[](widenCString(s));}
void clear() { ht.clear(); }
};
#ifdef DIKDIK