Incrementing to latest ECMA changes.
git-svn-id: svn://10.0.0.236/trunk@135269 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -266,13 +266,10 @@ js2val dump(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint
|
||||
if (argc) {
|
||||
if (JS2VAL_IS_OBJECT(argv[0])) {
|
||||
JS2Object *fObj = JS2VAL_TO_OBJECT(argv[0]);
|
||||
if ((((fObj->kind == FixedInstanceKind) || (fObj->kind == DynamicInstanceKind))
|
||||
if (((fObj->kind == CallableInstanceKind)
|
||||
&& (meta->objectType(argv[0]) == meta->functionClass))) {
|
||||
FunctionWrapper *fWrap;
|
||||
if (fObj->kind == FixedInstanceKind)
|
||||
fWrap = (checked_cast<FixedInstance *>(fObj))->fWrap;
|
||||
else
|
||||
fWrap = (checked_cast<DynamicInstance *>(fObj))->fWrap;
|
||||
fWrap = (checked_cast<CallableInstance *>(fObj))->fWrap;
|
||||
if (fWrap->code)
|
||||
stdOut << "<native code>\n";
|
||||
else
|
||||
|
||||
@@ -467,7 +467,7 @@ uint32 JS::PrettyPrinter::defaultLineWidth = 20;
|
||||
// be at the beginning of a line. Call end before destroying the Formatter;
|
||||
// otherwise the last line may not be output to f.
|
||||
JS::PrettyPrinter::PrettyPrinter(Formatter &f, uint32 lineWidth):
|
||||
lineWidth(min(lineWidth, static_cast<uint32>(unlimitedLineWidth))),
|
||||
lineWidth(v_min(lineWidth, static_cast<uint32>(unlimitedLineWidth))),
|
||||
outputFormatter(f),
|
||||
outputPos(0),
|
||||
lineNum(0),
|
||||
|
||||
@@ -806,7 +806,7 @@ void initArrayObject(JS2Metadata *meta)
|
||||
|
||||
PrototypeFunction *pf = &arrayProtos[0];
|
||||
while (pf->name) {
|
||||
FixedInstance *fInst = new FixedInstance(meta->functionClass);
|
||||
CallableInstance *fInst = new CallableInstance(meta->functionClass);
|
||||
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
|
||||
|
||||
InstanceMember *m = new InstanceMethod(fInst);
|
||||
|
||||
@@ -1469,7 +1469,7 @@ void initDateObject(JS2Metadata *meta)
|
||||
|
||||
PrototypeFunction *pf = &prototypeFunctions[0];
|
||||
while (pf->name) {
|
||||
FixedInstance *fInst = new FixedInstance(meta->functionClass);
|
||||
CallableInstance *fInst = new CallableInstance(meta->functionClass);
|
||||
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
|
||||
/*
|
||||
XXX not prototype object function properties, like ECMA3, but members of the Date class
|
||||
|
||||
@@ -740,13 +740,10 @@ namespace MetaData {
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(v);
|
||||
ASSERT(obj->kind == ClassKind);
|
||||
JS2Class *c = checked_cast<JS2Class *>(obj);
|
||||
if (c->dynamic)
|
||||
return OBJECT_TO_JS2VAL(new DynamicInstance(c));
|
||||
if (c->prototype)
|
||||
return OBJECT_TO_JS2VAL(new PrototypeInstance(c->prototype, c));
|
||||
else
|
||||
if (c->prototype)
|
||||
return OBJECT_TO_JS2VAL(new PrototypeInstance(c->prototype, c));
|
||||
else
|
||||
return OBJECT_TO_JS2VAL(new FixedInstance(c));
|
||||
return OBJECT_TO_JS2VAL(new CallableInstance(c));
|
||||
}
|
||||
|
||||
// Save current engine state (pc, environment top) and
|
||||
@@ -855,8 +852,8 @@ namespace MetaData {
|
||||
bool ForIteratorObject::buildNameList()
|
||||
{
|
||||
DynamicPropertyMap *dMap = NULL;
|
||||
if (obj->kind == DynamicInstanceKind)
|
||||
dMap = &(checked_cast<DynamicInstance *>(obj))->dynamicProperties;
|
||||
if (obj->kind == CallableInstanceKind)
|
||||
dMap = (checked_cast<CallableInstance *>(obj))->dynamicProperties;
|
||||
else
|
||||
if (obj->kind == GlobalObjectKind)
|
||||
dMap = &(checked_cast<GlobalObject *>(obj))->dynamicProperties;
|
||||
|
||||
@@ -346,7 +346,7 @@ void initMathObject(JS2Metadata *meta)
|
||||
meta->env.addFrame(meta->mathClass);
|
||||
PrototypeFunction *pf = &prototypeFunctions[0];
|
||||
while (pf->name) {
|
||||
FixedInstance *fInst = new FixedInstance(meta->functionClass);
|
||||
CallableInstance *fInst = new CallableInstance(meta->functionClass);
|
||||
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
|
||||
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(fInst), true);
|
||||
meta->defineStaticMember(&meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
|
||||
@@ -116,6 +116,23 @@ namespace MetaData {
|
||||
return result;
|
||||
}
|
||||
|
||||
js2val JS2Metadata::readEvalFile(const char *fileName)
|
||||
{
|
||||
String buffer;
|
||||
int ch;
|
||||
|
||||
js2val result = JS2VAL_VOID;
|
||||
|
||||
FILE* f = fopen(fileName, "r");
|
||||
if (f) {
|
||||
while ((ch = getc(f)) != EOF)
|
||||
buffer += static_cast<char>(ch);
|
||||
fclose(f);
|
||||
result = readEvalString(buffer, widenCString(fileName));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************************************
|
||||
@@ -431,13 +448,13 @@ namespace MetaData {
|
||||
&& (f->attributes == NULL)) {
|
||||
HoistedVar *v = defineHoistedVar(env, f->function.name, p);
|
||||
// XXX Here the spec. has ???, so the following is tentative
|
||||
DynamicInstance *dInst = new DynamicInstance(functionClass);
|
||||
CallableInstance *dInst = new CallableInstance(functionClass);
|
||||
dInst->fWrap = new FunctionWrapper(unchecked, compileFrame);
|
||||
f->fWrap = dInst->fWrap;
|
||||
v->value = OBJECT_TO_JS2VAL(dInst);
|
||||
}
|
||||
else {
|
||||
FixedInstance *fInst = new FixedInstance(functionClass);
|
||||
CallableInstance *fInst = new CallableInstance(functionClass);
|
||||
fInst->fWrap = new FunctionWrapper(unchecked, compileFrame);
|
||||
f->fWrap = fInst->fWrap;
|
||||
switch (memberMod) {
|
||||
@@ -2781,6 +2798,15 @@ doUnary:
|
||||
}
|
||||
|
||||
// Define a hoisted var in the current frame (either Global or a Function)
|
||||
// defineHoistedVar(env, id, initialValue) defines a hoisted variable with the name id in the environment env.
|
||||
// Hoisted variables are hoisted to the global or enclosing function scope. Multiple hoisted variables may be
|
||||
// defined in the same scope, but they may not coexist with non-hoisted variables with the same name. A hoisted
|
||||
// variable can be defined using either a var or a function statement. If it is defined using var, then initialValue
|
||||
// is always undefined (if the var statement has an initialiser, then the variable's value will be written later
|
||||
// when the var statement is executed). If it is defined using function, then initialValue must be a function
|
||||
// instance or open instance. According to rules inherited from ECMAScript Edition 3, if there are multiple
|
||||
// definitions of a hoisted variable, then the initial value of that variable is undefined if none of the definitions
|
||||
// is a function definition; otherwise, the initial value is the last function definition.
|
||||
HoistedVar *JS2Metadata::defineHoistedVar(Environment *env, const StringAtom *id, StmtNode *p)
|
||||
{
|
||||
HoistedVar *result = NULL;
|
||||
@@ -2802,14 +2828,16 @@ doUnary:
|
||||
}
|
||||
}
|
||||
}
|
||||
for (b = regionalFrame->staticWriteBindings.lower_bound(*id),
|
||||
end = regionalFrame->staticWriteBindings.upper_bound(*id); (b != end); b++) {
|
||||
if (b->second->qname == qName) {
|
||||
if (b->second->content->kind != StaticMember::HoistedVariable)
|
||||
reportError(Exception::definitionError, "Duplicate definition {0}", p->pos, id);
|
||||
else {
|
||||
result = checked_cast<HoistedVar *>(b->second->content);
|
||||
break;
|
||||
if (result == NULL) {
|
||||
for (b = regionalFrame->staticWriteBindings.lower_bound(*id),
|
||||
end = regionalFrame->staticWriteBindings.upper_bound(*id); (b != end); b++) {
|
||||
if (b->second->qname == qName) {
|
||||
if (b->second->content->kind != StaticMember::HoistedVariable)
|
||||
reportError(Exception::definitionError, "Duplicate definition {0}", p->pos, id);
|
||||
else {
|
||||
result = checked_cast<HoistedVar *>(b->second->content);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2846,7 +2874,7 @@ doUnary:
|
||||
|
||||
void JS2Metadata::addGlobalObjectFunction(char *name, NativeCode *code)
|
||||
{
|
||||
FixedInstance *fInst = new FixedInstance(functionClass);
|
||||
CallableInstance *fInst = new CallableInstance(functionClass);
|
||||
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_VOID, true), code);
|
||||
writeDynamicProperty(glob, new Multiname(&world.identifiers[name], publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
}
|
||||
@@ -2888,7 +2916,6 @@ doUnary:
|
||||
|
||||
/*** ECMA 3 Global Object ***/
|
||||
// Non-function properties of the global object : 'undefined', 'NaN' and 'Infinity'
|
||||
// XXX Or are these fixed properties?
|
||||
writeDynamicProperty(glob, new Multiname(engine->undefined_StringAtom, publicNamespace), true, JS2VAL_UNDEFINED, RunPhase);
|
||||
writeDynamicProperty(glob, new Multiname(&world.identifiers["NaN"], publicNamespace), true, engine->nanValue, RunPhase);
|
||||
writeDynamicProperty(glob, new Multiname(&world.identifiers["Infinity"], publicNamespace), true, engine->posInfValue, RunPhase);
|
||||
@@ -2900,7 +2927,7 @@ doUnary:
|
||||
// Function properties of the Object prototype object
|
||||
objectClass->prototype = new PrototypeInstance(NULL, objectClass);
|
||||
// XXX Or make this a static class member?
|
||||
FixedInstance *fInst = new FixedInstance(functionClass);
|
||||
CallableInstance *fInst = new CallableInstance(functionClass);
|
||||
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_VOID, true), Object_toString);
|
||||
writeDynamicProperty(objectClass->prototype, new Multiname(engine->toString_StringAtom, publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
|
||||
@@ -2983,10 +3010,10 @@ doUnary:
|
||||
case PrototypeInstanceKind:
|
||||
return prototypeClass;
|
||||
|
||||
case FixedInstanceKind:
|
||||
return checked_cast<FixedInstance *>(obj)->type;
|
||||
case DynamicInstanceKind:
|
||||
return checked_cast<DynamicInstance *>(obj)->type;
|
||||
case SimpleInstanceKind:
|
||||
return checked_cast<SimpleInstance *>(obj)->type;
|
||||
case CallableInstanceKind:
|
||||
return checked_cast<CallableInstance *>(obj)->type;
|
||||
|
||||
case GlobalObjectKind:
|
||||
case PackageKind:
|
||||
@@ -3011,8 +3038,8 @@ doUnary:
|
||||
ASSERT(obj);
|
||||
DynamicPropertyMap *dMap = NULL;
|
||||
bool isPrototypeInstance = false;
|
||||
if (obj->kind == DynamicInstanceKind)
|
||||
dMap = &(checked_cast<DynamicInstance *>(obj))->dynamicProperties;
|
||||
if (obj->kind == CallableInstanceKind)
|
||||
dMap = (checked_cast<CallableInstance *>(obj))->dynamicProperties;
|
||||
else
|
||||
if (obj->kind == GlobalObjectKind)
|
||||
dMap = &(checked_cast<GlobalObject *>(obj))->dynamicProperties;
|
||||
@@ -3041,8 +3068,8 @@ doUnary:
|
||||
ASSERT(obj);
|
||||
DynamicPropertyMap *dMap = NULL;
|
||||
bool isPrototypeInstance = false;
|
||||
if (obj->kind == DynamicInstanceKind)
|
||||
dMap = &(checked_cast<DynamicInstance *>(obj))->dynamicProperties;
|
||||
if (obj->kind == CallableInstanceKind)
|
||||
dMap = (checked_cast<CallableInstance *>(obj))->dynamicProperties;
|
||||
else
|
||||
if (obj->kind == GlobalObjectKind)
|
||||
dMap = &(checked_cast<GlobalObject *>(obj))->dynamicProperties;
|
||||
@@ -3063,7 +3090,7 @@ doUnary:
|
||||
//
|
||||
bool JS2Metadata::readDynamicProperty(JS2Object *container, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval)
|
||||
{
|
||||
ASSERT(container && ((container->kind == DynamicInstanceKind)
|
||||
ASSERT(container && ((container->kind == CallableInstanceKind)
|
||||
|| (container->kind == GlobalObjectKind)
|
||||
|| (container->kind == PrototypeInstanceKind)));
|
||||
if (!multiname->onList(publicNamespace))
|
||||
@@ -3073,8 +3100,8 @@ doUnary:
|
||||
reportError(Exception::compileExpressionError, "Inappropriate compile time expression", engine->errorPos());
|
||||
DynamicPropertyMap *dMap = NULL;
|
||||
bool isPrototypeInstance = false;
|
||||
if (container->kind == DynamicInstanceKind)
|
||||
dMap = &(checked_cast<DynamicInstance *>(container))->dynamicProperties;
|
||||
if (container->kind == CallableInstanceKind)
|
||||
dMap = (checked_cast<CallableInstance *>(container))->dynamicProperties;
|
||||
else
|
||||
if (container->kind == GlobalObjectKind)
|
||||
dMap = &(checked_cast<GlobalObject *>(container))->dynamicProperties;
|
||||
@@ -3100,10 +3127,11 @@ doUnary:
|
||||
return false; // 'None'
|
||||
}
|
||||
|
||||
void DynamicInstance::writeProperty(JS2Metadata * /* meta */, const String *name, js2val newValue)
|
||||
void CallableInstance::writeProperty(JS2Metadata * /* meta */, const String *name, js2val newValue)
|
||||
{
|
||||
ASSERT(dynamicProperties);
|
||||
const DynamicPropertyMap::value_type e(*name, newValue);
|
||||
dynamicProperties.insert(e);
|
||||
dynamicProperties->insert(e);
|
||||
}
|
||||
|
||||
void ArrayInstance::writeProperty(JS2Metadata *meta, const String *name, js2val newValue)
|
||||
@@ -3114,8 +3142,9 @@ doUnary:
|
||||
//
|
||||
// ToString(ToUint32(name)) == name
|
||||
//
|
||||
ASSERT(dynamicProperties);
|
||||
const DynamicPropertyMap::value_type e(*name, newValue);
|
||||
dynamicProperties.insert(e);
|
||||
dynamicProperties->insert(e);
|
||||
|
||||
const char16 *numEnd;
|
||||
float64 f = stringToDouble(name->data(), name->data() + name->length(), numEnd);
|
||||
@@ -3131,15 +3160,15 @@ doUnary:
|
||||
// Write a value to a dynamic container - inserting into the map if not already there (if createIfMissing)
|
||||
bool JS2Metadata::writeDynamicProperty(JS2Object *container, Multiname *multiname, bool createIfMissing, js2val newValue, Phase phase)
|
||||
{
|
||||
ASSERT(container && ((container->kind == DynamicInstanceKind)
|
||||
ASSERT(container && ((container->kind == CallableInstanceKind)
|
||||
|| (container->kind == GlobalObjectKind)
|
||||
|| (container->kind == PrototypeInstanceKind)));
|
||||
if (!multiname->onList(publicNamespace))
|
||||
return false;
|
||||
const String *name = multiname->name;
|
||||
DynamicPropertyMap *dMap = NULL;
|
||||
if (container->kind == DynamicInstanceKind)
|
||||
dMap = &(checked_cast<DynamicInstance *>(container))->dynamicProperties;
|
||||
if (container->kind == CallableInstanceKind)
|
||||
dMap = (checked_cast<CallableInstance *>(container))->dynamicProperties;
|
||||
else
|
||||
if (container->kind == GlobalObjectKind)
|
||||
dMap = &(checked_cast<GlobalObject *>(container))->dynamicProperties;
|
||||
@@ -3153,8 +3182,8 @@ doUnary:
|
||||
}
|
||||
if (!createIfMissing)
|
||||
return false;
|
||||
if (container->kind == DynamicInstanceKind) {
|
||||
DynamicInstance *dynInst = checked_cast<DynamicInstance *>(container);
|
||||
if (container->kind == CallableInstanceKind) {
|
||||
CallableInstance *dynInst = checked_cast<CallableInstance *>(container);
|
||||
InstanceBinding *ib = resolveInstanceMemberName(dynInst->type, multiname, ReadAccess, phase);
|
||||
if (ib == NULL) {
|
||||
dynInst->writeProperty(this, name, newValue);
|
||||
@@ -3244,12 +3273,12 @@ doUnary:
|
||||
// the property or not. If it does, return it's value
|
||||
bool JS2Metadata::readProperty(js2val containerVal, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval)
|
||||
{
|
||||
bool isDynamicInstance = false;
|
||||
bool isCallableInstance = false;
|
||||
if (JS2VAL_IS_PRIMITIVE(containerVal)) {
|
||||
readClassProperty:
|
||||
JS2Class *c = objectType(containerVal);
|
||||
InstanceBinding *ib = resolveInstanceMemberName(c, multiname, ReadAccess, phase);
|
||||
if ((ib == NULL) && isDynamicInstance)
|
||||
if ((ib == NULL) && isCallableInstance)
|
||||
return readDynamicProperty(JS2VAL_TO_OBJECT(containerVal), multiname, lookupKind, phase, rval);
|
||||
else {
|
||||
// XXX Spec. would have us passing a primitive here since ES4 is 'not addressing' the issue
|
||||
@@ -3261,11 +3290,11 @@ readClassProperty:
|
||||
switch (container->kind) {
|
||||
case AttributeObjectKind:
|
||||
case MultinameKind:
|
||||
case FixedInstanceKind:
|
||||
case SimpleInstanceKind:
|
||||
case MethodClosureKind:
|
||||
goto readClassProperty;
|
||||
case DynamicInstanceKind:
|
||||
isDynamicInstance = true;
|
||||
case CallableInstanceKind:
|
||||
isCallableInstance = true;
|
||||
goto readClassProperty;
|
||||
|
||||
case SystemKind:
|
||||
@@ -3279,6 +3308,9 @@ readClassProperty:
|
||||
case PrototypeInstanceKind:
|
||||
return readDynamicProperty(container, multiname, lookupKind, phase, rval);
|
||||
|
||||
case AlienInstanceKind:
|
||||
return (checked_cast<AlienInstance *>(container))->readProperty(multiname, rval);
|
||||
|
||||
default:
|
||||
ASSERT(false);
|
||||
return false;
|
||||
@@ -3289,13 +3321,13 @@ readClassProperty:
|
||||
Slot *JS2Metadata::findSlot(js2val thisObjVal, InstanceVariable *id)
|
||||
{
|
||||
ASSERT(JS2VAL_IS_OBJECT(thisObjVal)
|
||||
&& ((JS2VAL_TO_OBJECT(thisObjVal)->kind == DynamicInstanceKind)
|
||||
|| (JS2VAL_TO_OBJECT(thisObjVal)->kind == FixedInstanceKind)));
|
||||
&& ((JS2VAL_TO_OBJECT(thisObjVal)->kind == CallableInstanceKind)
|
||||
|| (JS2VAL_TO_OBJECT(thisObjVal)->kind == SimpleInstanceKind)));
|
||||
JS2Object *thisObj = JS2VAL_TO_OBJECT(thisObjVal);
|
||||
if (thisObj->kind == DynamicInstanceKind)
|
||||
return &checked_cast<DynamicInstance *>(thisObj)->slots[id->slotIndex];
|
||||
if (thisObj->kind == CallableInstanceKind)
|
||||
return &checked_cast<CallableInstance *>(thisObj)->slots[id->slotIndex];
|
||||
else
|
||||
return &checked_cast<FixedInstance *>(thisObj)->slots[id->slotIndex];
|
||||
return &checked_cast<SimpleInstance *>(thisObj)->slots[id->slotIndex];
|
||||
}
|
||||
|
||||
// Read the value of an instanceMember, if valid
|
||||
@@ -3382,16 +3414,16 @@ readClassProperty:
|
||||
case MethodClosureKind:
|
||||
return false;
|
||||
|
||||
case FixedInstanceKind:
|
||||
c = checked_cast<FixedInstance *>(container)->type;
|
||||
case SimpleInstanceKind:
|
||||
c = checked_cast<SimpleInstance *>(container)->type;
|
||||
goto instanceWrite;
|
||||
case DynamicInstanceKind:
|
||||
c = checked_cast<DynamicInstance *>(container)->type;
|
||||
case CallableInstanceKind:
|
||||
c = checked_cast<CallableInstance *>(container)->type;
|
||||
goto instanceWrite;
|
||||
instanceWrite:
|
||||
{
|
||||
InstanceBinding *ib = resolveInstanceMemberName(c, multiname, WriteAccess, phase);
|
||||
if ((ib == NULL) && (container->kind == DynamicInstanceKind))
|
||||
if ((ib == NULL) && (container->kind == CallableInstanceKind))
|
||||
return writeDynamicProperty(container, multiname, createIfMissing, newValue, phase);
|
||||
else
|
||||
return writeInstanceMember(containerVal, c, (ib) ? &ib->qname : NULL, newValue, phase);
|
||||
@@ -3484,12 +3516,12 @@ readClassProperty:
|
||||
bool JS2Metadata::deleteProperty(js2val containerVal, Multiname *multiname, LookupKind *lookupKind, Phase phase, bool *result)
|
||||
{
|
||||
ASSERT(phase == RunPhase);
|
||||
bool isDynamicInstance = false;
|
||||
bool isCallableInstance = false;
|
||||
if (JS2VAL_IS_PRIMITIVE(containerVal)) {
|
||||
deleteClassProperty:
|
||||
JS2Class *c = objectType(containerVal);
|
||||
InstanceBinding *ib = resolveInstanceMemberName(c, multiname, ReadAccess, phase);
|
||||
if ((ib == NULL) && isDynamicInstance)
|
||||
if ((ib == NULL) && isCallableInstance)
|
||||
return deleteDynamicProperty(JS2VAL_TO_OBJECT(containerVal), multiname, lookupKind, result);
|
||||
else
|
||||
return deleteInstanceMember(c, (ib) ? &ib->qname : NULL, result);
|
||||
@@ -3498,11 +3530,11 @@ deleteClassProperty:
|
||||
switch (container->kind) {
|
||||
case AttributeObjectKind:
|
||||
case MultinameKind:
|
||||
case FixedInstanceKind:
|
||||
case SimpleInstanceKind:
|
||||
case MethodClosureKind:
|
||||
goto deleteClassProperty;
|
||||
case DynamicInstanceKind:
|
||||
isDynamicInstance = true;
|
||||
case CallableInstanceKind:
|
||||
isCallableInstance = true;
|
||||
goto deleteClassProperty;
|
||||
|
||||
case SystemKind:
|
||||
@@ -3557,15 +3589,15 @@ deleteClassProperty:
|
||||
|
||||
bool JS2Metadata::deleteDynamicProperty(JS2Object *container, Multiname *multiname, LookupKind * /* lookupKind */, bool *result)
|
||||
{
|
||||
ASSERT(container && ((container->kind == DynamicInstanceKind)
|
||||
ASSERT(container && ((container->kind == CallableInstanceKind)
|
||||
|| (container->kind == GlobalObjectKind)
|
||||
|| (container->kind == PrototypeInstanceKind)));
|
||||
if (!multiname->onList(publicNamespace))
|
||||
return false;
|
||||
const String *name = multiname->name;
|
||||
DynamicPropertyMap *dMap = NULL;
|
||||
if (container->kind == DynamicInstanceKind)
|
||||
dMap = &(checked_cast<DynamicInstance *>(container))->dynamicProperties;
|
||||
if (container->kind == CallableInstanceKind)
|
||||
dMap = (checked_cast<CallableInstance *>(container))->dynamicProperties;
|
||||
else
|
||||
if (container->kind == GlobalObjectKind)
|
||||
dMap = &(checked_cast<GlobalObject *>(container))->dynamicProperties;
|
||||
@@ -3833,8 +3865,8 @@ deleteClassProperty:
|
||||
if (readProperty(x, &mn, &lookup, RunPhase, &result)) {
|
||||
if (JS2VAL_IS_OBJECT(result)) {
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(result);
|
||||
if ((obj->kind == FixedInstanceKind) && (objectType(result) == functionClass)) {
|
||||
FunctionWrapper *fWrap = (checked_cast<FixedInstance *>(obj))->fWrap;
|
||||
if ((obj->kind == CallableInstanceKind) && (objectType(result) == functionClass)) {
|
||||
FunctionWrapper *fWrap = (checked_cast<CallableInstance *>(obj))->fWrap;
|
||||
if (fWrap->code) {
|
||||
result = (fWrap->code)(this, result, NULL, 0);
|
||||
return result;
|
||||
@@ -3843,7 +3875,7 @@ deleteClassProperty:
|
||||
else
|
||||
if (obj->kind == MethodClosureKind) {
|
||||
MethodClosure *mc = checked_cast<MethodClosure *>(obj);
|
||||
FixedInstance *fInst = mc->method->fInst;
|
||||
CallableInstance *fInst = mc->method->fInst;
|
||||
FunctionWrapper *fWrap = fInst->fWrap;
|
||||
if (fWrap->code) {
|
||||
result = (fWrap->code)(this, mc->thisObject, NULL, 0);
|
||||
@@ -4003,6 +4035,31 @@ deleteClassProperty:
|
||||
delete oldData;
|
||||
}
|
||||
|
||||
js2val JS2Metadata::invokeFunction(const char *fname)
|
||||
{
|
||||
js2val retval;
|
||||
uint8 *savePC = NULL;
|
||||
|
||||
CompilationData *oldData = startCompilationUnit(NULL, bCon->mSource, bCon->mSourceLocation);
|
||||
try {
|
||||
LexicalReference rVal(&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);
|
||||
bCon->emitOp(eReturn, 0);
|
||||
savePC = engine->pc;
|
||||
engine->pc = NULL;
|
||||
retval = engine->interpret(RunPhase, bCon);
|
||||
}
|
||||
catch (Exception &x) {
|
||||
engine->pc = savePC;
|
||||
restoreCompilationUnit(oldData);
|
||||
throw x;
|
||||
}
|
||||
engine->pc = savePC;
|
||||
restoreCompilationUnit(oldData);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Throw an exception of the specified kind, indicating the position 'pos' and
|
||||
@@ -4088,21 +4145,22 @@ deleteClassProperty:
|
||||
|
||||
/************************************************************************************
|
||||
*
|
||||
* DynamicInstance
|
||||
* CallableInstance
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
// Construct a dynamic instance of a class. Set the
|
||||
// initial value of all slots to uninitialized.
|
||||
DynamicInstance::DynamicInstance(JS2Class *type)
|
||||
: JS2Object(DynamicInstanceKind),
|
||||
CallableInstance::CallableInstance(JS2Class *type)
|
||||
: JS2Object(CallableInstanceKind),
|
||||
type(type),
|
||||
fWrap(NULL),
|
||||
call(NULL),
|
||||
construct(NULL),
|
||||
env(NULL),
|
||||
// call(NULL),
|
||||
// construct(NULL),
|
||||
// env(NULL),
|
||||
typeofString(type->getName()),
|
||||
slots(new Slot[type->slotCount])
|
||||
slots(new Slot[type->slotCount]),
|
||||
dynamicProperties(type->dynamic ? new DynamicPropertyMap() : NULL)
|
||||
{
|
||||
for (uint32 i = 0; i < type->slotCount; i++) {
|
||||
slots[i].value = JS2VAL_UNINITIALIZED;
|
||||
@@ -4110,7 +4168,7 @@ deleteClassProperty:
|
||||
}
|
||||
|
||||
// gc-mark all contained JS2Objects and visit contained structures to do likewise
|
||||
void DynamicInstance::markChildren()
|
||||
void CallableInstance::markChildren()
|
||||
{
|
||||
GCMARKOBJECT(type)
|
||||
if (fWrap) {
|
||||
@@ -4124,53 +4182,51 @@ deleteClassProperty:
|
||||
GCMARKVALUE(slots[i].value);
|
||||
}
|
||||
}
|
||||
for (DynamicPropertyIterator i = dynamicProperties.begin(), end = dynamicProperties.end(); (i != end); i++) {
|
||||
GCMARKVALUE(i->second);
|
||||
}
|
||||
if (dynamicProperties) {
|
||||
for (DynamicPropertyIterator i = dynamicProperties->begin(), end = dynamicProperties->end(); (i != end); i++) {
|
||||
GCMARKVALUE(i->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************************************
|
||||
*
|
||||
* FixedInstance
|
||||
* SimpleInstance
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
|
||||
// Construct a fixed instance of a class. Set the
|
||||
// Construct a Simple instance of a class. Set the
|
||||
// initial value of all slots to uninitialized.
|
||||
FixedInstance::FixedInstance(JS2Class *type)
|
||||
: JS2Object(FixedInstanceKind),
|
||||
SimpleInstance::SimpleInstance(JS2Class *type)
|
||||
: JS2Object(SimpleInstanceKind),
|
||||
type(type),
|
||||
fWrap(NULL),
|
||||
call(NULL),
|
||||
construct(NULL),
|
||||
env(NULL),
|
||||
typeofString(type->getName()),
|
||||
slots(new Slot[type->slotCount])
|
||||
slots(new Slot[type->slotCount]),
|
||||
dynamicProperties(type->dynamic ? new DynamicPropertyMap() : NULL)
|
||||
{
|
||||
for (uint32 i = 0; i < type->slotCount; i++) {
|
||||
slots[i].value = JS2VAL_UNINITIALIZED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// gc-mark all contained JS2Objects and visit contained structures to do likewise
|
||||
void FixedInstance::markChildren()
|
||||
void SimpleInstance::markChildren()
|
||||
{
|
||||
GCMARKOBJECT(type)
|
||||
if (fWrap) {
|
||||
GCMARKOBJECT(fWrap->compileFrame);
|
||||
if (fWrap->bCon)
|
||||
fWrap->bCon->mark();
|
||||
}
|
||||
if (slots) {
|
||||
ASSERT(type);
|
||||
for (uint32 i = 0; (i < type->slotCount); i++) {
|
||||
GCMARKVALUE(slots[i].value);
|
||||
}
|
||||
}
|
||||
if (dynamicProperties) {
|
||||
for (DynamicPropertyIterator i = dynamicProperties->begin(), end = dynamicProperties->end(); (i != end); i++) {
|
||||
GCMARKVALUE(i->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -50,7 +50,8 @@ class Context;
|
||||
class CompoundAttribute;
|
||||
class BytecodeContainer;
|
||||
class Pond;
|
||||
class FixedInstance;
|
||||
class SimpleInstance;
|
||||
class CallableInstance;
|
||||
|
||||
|
||||
typedef void (Invokable)();
|
||||
@@ -88,11 +89,11 @@ enum ObjectKind {
|
||||
ClassKind,
|
||||
BlockKind,
|
||||
PrototypeInstanceKind,
|
||||
FixedInstanceKind,
|
||||
DynamicInstanceKind,
|
||||
SimpleInstanceKind,
|
||||
CallableInstanceKind,
|
||||
MultinameKind,
|
||||
MethodClosureKind,
|
||||
|
||||
AlienInstanceKind,
|
||||
ForIteratorKind
|
||||
};
|
||||
|
||||
@@ -298,7 +299,7 @@ public:
|
||||
|
||||
class HoistedVar : public StaticMember {
|
||||
public:
|
||||
HoistedVar() : StaticMember(Member::HoistedVariable), value(JS2VAL_VOID), hasFunctionInitializer(false) { }
|
||||
HoistedVar() : StaticMember(Member::HoistedVariable), value(JS2VAL_UNDEFINED), hasFunctionInitializer(false) { }
|
||||
|
||||
js2val value; // This variable's current value
|
||||
bool hasFunctionInitializer; // true if this variable was created by a function statement
|
||||
@@ -365,10 +366,10 @@ public:
|
||||
|
||||
class InstanceMethod : public InstanceMember {
|
||||
public:
|
||||
InstanceMethod(FixedInstance *fInst) : InstanceMember(InstanceMethodKind, NULL, false), fInst(fInst) { }
|
||||
InstanceMethod(CallableInstance *fInst) : InstanceMember(InstanceMethodKind, NULL, false), fInst(fInst) { }
|
||||
Signature type; // This method's signature
|
||||
Invokable *code; // This method itself (a callable object); null if this method is abstract
|
||||
FixedInstance *fInst;
|
||||
// Invokable *code; // This method itself (a callable object); null if this method is abstract
|
||||
CallableInstance *fInst;
|
||||
|
||||
virtual void mark();
|
||||
};
|
||||
@@ -509,40 +510,39 @@ public:
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Instances of non-dynamic classes are represented as FIXEDINSTANCE records. These instances can contain only fixed properties.
|
||||
class FixedInstance : public JS2Object {
|
||||
// Instances which do not respond to the function call or new operators are represented as SIMPLEINSTANCE records
|
||||
class SimpleInstance : public JS2Object {
|
||||
public:
|
||||
FixedInstance(JS2Class *type);
|
||||
SimpleInstance(JS2Class *type);
|
||||
|
||||
JS2Class *type; // This instance's type
|
||||
const String *typeofString; // A string to return if typeof is invoked on this instance
|
||||
Slot *slots; // A set of slots that hold this instance's fixed property values
|
||||
DynamicPropertyMap *dynamicProperties; // A set of this instance's dynamic properties, or NULL if this is a fixed instance
|
||||
|
||||
JS2Class *type; // This instance's type
|
||||
FunctionWrapper *fWrap;
|
||||
Invokable *call; // A procedure to call when this instance is used in a call expression
|
||||
Invokable *construct; // A procedure to call when this instance is used in a new expression
|
||||
Environment *env; // The environment to pass to the call or construct procedure
|
||||
const String *typeofString; // A string to return if typeof is invoked on this instance
|
||||
Slot *slots; // A set of slots that hold this instance's fixed property values
|
||||
virtual void markChildren();
|
||||
virtual ~FixedInstance() { }
|
||||
virtual ~SimpleInstance() { }
|
||||
};
|
||||
|
||||
// Instances of dynamic classes are represented as DYNAMICINSTANCE records. These instances can contain fixed and dynamic properties.
|
||||
class DynamicInstance : public JS2Object {
|
||||
// If the instance reposnds to the function call or new operators, then that
|
||||
// instance is a CallableInstance
|
||||
class CallableInstance : public JS2Object {
|
||||
public:
|
||||
DynamicInstance(JS2Class *type);
|
||||
CallableInstance(JS2Class *type);
|
||||
|
||||
JS2Class *type; // This instance's type
|
||||
JS2Class *type; // This instance's type
|
||||
// Invokable *call; // A procedure to call when this instance is used in a call expression
|
||||
// Invokable *construct; // A procedure to call when this instance is used in a new expression
|
||||
// Environment *env; // The environment to pass to the call or construct procedure
|
||||
FunctionWrapper *fWrap;
|
||||
Invokable *call; // A procedure to call when this instance is used in a call expression
|
||||
Invokable *construct; // A procedure to call when this instance is used in a new expression
|
||||
Environment *env; // The environment to pass to the call or construct procedure
|
||||
const String *typeofString; // A string to return if typeof is invoked on this instance
|
||||
Slot *slots; // A set of slots that hold this instance's fixed property values
|
||||
DynamicPropertyMap dynamicProperties; // A set of this instance's dynamic properties
|
||||
|
||||
const String *typeofString; // A string to return if typeof is invoked on this instance
|
||||
Slot *slots; // A set of slots that hold this instance's fixed property values
|
||||
DynamicPropertyMap *dynamicProperties; // A set of this instance's dynamic properties, or NULL if this is a fixed instance
|
||||
virtual void markChildren();
|
||||
|
||||
virtual void writeProperty(JS2Metadata *meta, const String *name, js2val newValue);
|
||||
virtual ~DynamicInstance() { }
|
||||
virtual ~CallableInstance() { }
|
||||
};
|
||||
|
||||
// Prototype instances are represented as PROTOTYPE records. Prototype instances
|
||||
@@ -562,20 +562,20 @@ public:
|
||||
virtual ~PrototypeInstance() { }
|
||||
};
|
||||
|
||||
// Date instances are fixed (not dynamic? XXX) instances created by the Date class, they have an extra field
|
||||
// Date instances are Callable instances created by the Date class, they have an extra field
|
||||
// that contains the millisecond count
|
||||
class DateInstance : public FixedInstance {
|
||||
class DateInstance : public CallableInstance {
|
||||
public:
|
||||
DateInstance(JS2Class *type) : FixedInstance(type) { }
|
||||
DateInstance(JS2Class *type) : CallableInstance(type) { }
|
||||
|
||||
float64 ms;
|
||||
};
|
||||
|
||||
// String instances are fixed (not dynamic? XXX) instances created by the String class, they have an extra field
|
||||
// String instances are Callable instances created by the String class, they have an extra field
|
||||
// that contains the string data
|
||||
class StringInstance : public FixedInstance {
|
||||
class StringInstance : public CallableInstance {
|
||||
public:
|
||||
StringInstance(JS2Class *type) : FixedInstance(type), mValue(NULL) { }
|
||||
StringInstance(JS2Class *type) : CallableInstance(type), mValue(NULL) { }
|
||||
|
||||
String *mValue; // has been allocated by engine in the GC'able Pond
|
||||
|
||||
@@ -583,31 +583,31 @@ public:
|
||||
virtual ~StringInstance() { }
|
||||
};
|
||||
|
||||
// Number instances are fixed (not dynamic? XXX) instances created by the Number class, they have an extra field
|
||||
// Number instances are Callable instances created by the Number class, they have an extra field
|
||||
// that contains the float64 data
|
||||
class NumberInstance : public FixedInstance {
|
||||
class NumberInstance : public CallableInstance {
|
||||
public:
|
||||
NumberInstance(JS2Class *type) : FixedInstance(type), mValue(0.0) { }
|
||||
NumberInstance(JS2Class *type) : CallableInstance(type), mValue(0.0) { }
|
||||
|
||||
float64 mValue;
|
||||
};
|
||||
|
||||
// Array instances are dynamic instances created by the Array class, they
|
||||
// Array instances are Callable instances created by the Array class, they
|
||||
// maintain the value of the 'length' property when 'indexable' elements
|
||||
// are added.
|
||||
class ArrayInstance : public DynamicInstance {
|
||||
class ArrayInstance : public CallableInstance {
|
||||
public:
|
||||
ArrayInstance(JS2Class *type) : DynamicInstance(type) { }
|
||||
ArrayInstance(JS2Class *type) : CallableInstance(type) { }
|
||||
|
||||
virtual void writeProperty(JS2Metadata *meta, const String *name, js2val newValue);
|
||||
virtual ~ArrayInstance() { }
|
||||
};
|
||||
|
||||
// RegExp instances are dynamic instances created by the RegExp class, they have an extra field
|
||||
// RegExp instances are Callable instances created by the RegExp class, they have an extra field
|
||||
// that contains the RegExp object
|
||||
class RegExpInstance : public DynamicInstance {
|
||||
class RegExpInstance : public CallableInstance {
|
||||
public:
|
||||
RegExpInstance(JS2Class *type) : DynamicInstance(type) { }
|
||||
RegExpInstance(JS2Class *type) : CallableInstance(type) { }
|
||||
|
||||
void setLastIndex(JS2Metadata *meta, js2val a);
|
||||
void setGlobal(JS2Metadata *meta, js2val a);
|
||||
@@ -625,6 +625,18 @@ public:
|
||||
virtual ~RegExpInstance() { }
|
||||
};
|
||||
|
||||
// A base class for objects from another world
|
||||
// to which read & write property calls are dispatched
|
||||
class AlienInstance : public JS2Object {
|
||||
public:
|
||||
AlienInstance(void *d) : JS2Object(AlienInstanceKind), uData(d) { }
|
||||
|
||||
void *uData;
|
||||
|
||||
virtual bool readProperty(Multiname *m, js2val *rval); // return true/false to signal whether the property is available
|
||||
virtual void writeProperty(Multiname *m, js2val rval);
|
||||
};
|
||||
|
||||
// A helper class for 'for..in' statements
|
||||
class ForIteratorObject : public JS2Object {
|
||||
public:
|
||||
@@ -960,6 +972,7 @@ public:
|
||||
|
||||
js2val readEvalString(const String &str, const String& fileName);
|
||||
js2val readEvalFile(const String& fileName);
|
||||
js2val readEvalFile(const char *fileName);
|
||||
|
||||
|
||||
void ValidateStmtList(Context *cxt, Environment *env, StmtNode *p);
|
||||
@@ -991,6 +1004,7 @@ public:
|
||||
bool findStaticMember(JS2Class *c, Multiname *multiname, Access access, Phase phase, MemberDescriptor *result);
|
||||
JS2Class *getVariableType(Variable *v, Phase phase, size_t pos);
|
||||
|
||||
js2val invokeFunction(const char *fname);
|
||||
|
||||
bool readProperty(js2val container, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
|
||||
bool readProperty(Frame *pf, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
|
||||
|
||||
@@ -244,11 +244,11 @@
|
||||
b = pop();
|
||||
ASSERT(JS2VAL_IS_OBJECT(b));
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(b);
|
||||
ASSERT((obj->kind == FixedInstanceKind) || (obj->kind == DynamicInstanceKind));
|
||||
if (obj->kind == FixedInstanceKind)
|
||||
checked_cast<FixedInstance *>(obj)->slots[slotIndex].value = a;
|
||||
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
|
||||
if (obj->kind == SimpleInstanceKind)
|
||||
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = a;
|
||||
else
|
||||
checked_cast<DynamicInstance *>(obj)->slots[slotIndex].value = a;
|
||||
checked_cast<CallableInstance *>(obj)->slots[slotIndex].value = a;
|
||||
push(a);
|
||||
}
|
||||
break;
|
||||
@@ -260,11 +260,11 @@
|
||||
b = pop();
|
||||
ASSERT(JS2VAL_IS_OBJECT(b));
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(b);
|
||||
ASSERT((obj->kind == FixedInstanceKind) || (obj->kind == DynamicInstanceKind));
|
||||
if (obj->kind == FixedInstanceKind)
|
||||
push(checked_cast<FixedInstance *>(obj)->slots[slotIndex].value);
|
||||
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
|
||||
if (obj->kind == SimpleInstanceKind)
|
||||
push(checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value);
|
||||
else
|
||||
push(checked_cast<DynamicInstance *>(obj)->slots[slotIndex].value);
|
||||
push(checked_cast<CallableInstance *>(obj)->slots[slotIndex].value);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -275,11 +275,11 @@
|
||||
b = top();
|
||||
ASSERT(JS2VAL_IS_OBJECT(b));
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(b);
|
||||
ASSERT((obj->kind == FixedInstanceKind) || (obj->kind == DynamicInstanceKind));
|
||||
if (obj->kind == FixedInstanceKind)
|
||||
push(checked_cast<FixedInstance *>(obj)->slots[slotIndex].value);
|
||||
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
|
||||
if (obj->kind == SimpleInstanceKind)
|
||||
push(checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value);
|
||||
else
|
||||
push(checked_cast<DynamicInstance *>(obj)->slots[slotIndex].value);
|
||||
push(checked_cast<CallableInstance *>(obj)->slots[slotIndex].value);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -1016,16 +1016,16 @@
|
||||
baseVal = pop();
|
||||
ASSERT(JS2VAL_IS_OBJECT(baseVal));
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(baseVal);
|
||||
ASSERT((obj->kind == FixedInstanceKind) || (obj->kind == DynamicInstanceKind));
|
||||
if (obj->kind == FixedInstanceKind)
|
||||
a = checked_cast<FixedInstance *>(obj)->slots[slotIndex].value;
|
||||
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
|
||||
if (obj->kind == SimpleInstanceKind)
|
||||
a = checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value;
|
||||
else
|
||||
a = checked_cast<DynamicInstance *>(obj)->slots[slotIndex].value;
|
||||
a = checked_cast<CallableInstance *>(obj)->slots[slotIndex].value;
|
||||
float64 num = meta->toFloat64(a);
|
||||
if (obj->kind == FixedInstanceKind)
|
||||
checked_cast<FixedInstance *>(obj)->slots[slotIndex].value = allocNumber(num + 1.0);
|
||||
if (obj->kind == SimpleInstanceKind)
|
||||
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = allocNumber(num + 1.0);
|
||||
else
|
||||
checked_cast<DynamicInstance *>(obj)->slots[slotIndex].value = allocNumber(num + 1.0);
|
||||
checked_cast<CallableInstance *>(obj)->slots[slotIndex].value = allocNumber(num + 1.0);
|
||||
pushNumber(num);
|
||||
baseVal = JS2VAL_VOID;
|
||||
}
|
||||
@@ -1037,16 +1037,16 @@
|
||||
baseVal = pop();
|
||||
ASSERT(JS2VAL_IS_OBJECT(baseVal));
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(baseVal);
|
||||
ASSERT((obj->kind == FixedInstanceKind) || (obj->kind == DynamicInstanceKind));
|
||||
if (obj->kind == FixedInstanceKind)
|
||||
a = checked_cast<FixedInstance *>(obj)->slots[slotIndex].value;
|
||||
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
|
||||
if (obj->kind == SimpleInstanceKind)
|
||||
a = checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value;
|
||||
else
|
||||
a = checked_cast<DynamicInstance *>(obj)->slots[slotIndex].value;
|
||||
a = checked_cast<CallableInstance *>(obj)->slots[slotIndex].value;
|
||||
float64 num = meta->toFloat64(a);
|
||||
if (obj->kind == FixedInstanceKind)
|
||||
checked_cast<FixedInstance *>(obj)->slots[slotIndex].value = allocNumber(num - 1.0);
|
||||
if (obj->kind == SimpleInstanceKind)
|
||||
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = allocNumber(num - 1.0);
|
||||
else
|
||||
checked_cast<DynamicInstance *>(obj)->slots[slotIndex].value = allocNumber(num - 1.0);
|
||||
checked_cast<CallableInstance *>(obj)->slots[slotIndex].value = allocNumber(num - 1.0);
|
||||
pushNumber(num);
|
||||
baseVal = JS2VAL_VOID;
|
||||
}
|
||||
@@ -1058,17 +1058,17 @@
|
||||
baseVal = pop();
|
||||
ASSERT(JS2VAL_IS_OBJECT(baseVal));
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(baseVal);
|
||||
ASSERT((obj->kind == FixedInstanceKind) || (obj->kind == DynamicInstanceKind));
|
||||
if (obj->kind == FixedInstanceKind)
|
||||
a = checked_cast<FixedInstance *>(obj)->slots[slotIndex].value;
|
||||
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
|
||||
if (obj->kind == SimpleInstanceKind)
|
||||
a = checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value;
|
||||
else
|
||||
a = checked_cast<DynamicInstance *>(obj)->slots[slotIndex].value;
|
||||
a = checked_cast<CallableInstance *>(obj)->slots[slotIndex].value;
|
||||
float64 num = meta->toFloat64(a);
|
||||
a = pushNumber(num + 1.0);
|
||||
if (obj->kind == FixedInstanceKind)
|
||||
checked_cast<FixedInstance *>(obj)->slots[slotIndex].value = a;
|
||||
if (obj->kind == SimpleInstanceKind)
|
||||
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = a;
|
||||
else
|
||||
checked_cast<DynamicInstance *>(obj)->slots[slotIndex].value = a;
|
||||
checked_cast<CallableInstance *>(obj)->slots[slotIndex].value = a;
|
||||
baseVal = JS2VAL_VOID;
|
||||
}
|
||||
break;
|
||||
@@ -1079,17 +1079,17 @@
|
||||
baseVal = pop();
|
||||
ASSERT(JS2VAL_IS_OBJECT(baseVal));
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(baseVal);
|
||||
ASSERT((obj->kind == FixedInstanceKind) || (obj->kind == DynamicInstanceKind));
|
||||
if (obj->kind == FixedInstanceKind)
|
||||
a = checked_cast<FixedInstance *>(obj)->slots[slotIndex].value;
|
||||
ASSERT((obj->kind == SimpleInstanceKind) || (obj->kind == CallableInstanceKind));
|
||||
if (obj->kind == SimpleInstanceKind)
|
||||
a = checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value;
|
||||
else
|
||||
a = checked_cast<DynamicInstance *>(obj)->slots[slotIndex].value;
|
||||
a = checked_cast<CallableInstance *>(obj)->slots[slotIndex].value;
|
||||
float64 num = meta->toFloat64(a);
|
||||
a = pushNumber(num - 1.0);
|
||||
if (obj->kind == FixedInstanceKind)
|
||||
checked_cast<FixedInstance *>(obj)->slots[slotIndex].value = a;
|
||||
if (obj->kind == SimpleInstanceKind)
|
||||
checked_cast<SimpleInstance *>(obj)->slots[slotIndex].value = a;
|
||||
else
|
||||
checked_cast<DynamicInstance *>(obj)->slots[slotIndex].value = a;
|
||||
checked_cast<CallableInstance *>(obj)->slots[slotIndex].value = a;
|
||||
baseVal = JS2VAL_VOID;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -47,18 +47,11 @@
|
||||
push(a);
|
||||
}
|
||||
else {
|
||||
if ((obj->kind == FixedInstanceKind) || (obj->kind == DynamicInstanceKind)) {
|
||||
if (obj->kind == CallableInstanceKind) {
|
||||
FunctionWrapper *fWrap = NULL;
|
||||
if (obj->kind == FixedInstanceKind) {
|
||||
FixedInstance *fInst = (checked_cast<FixedInstance *>(obj));
|
||||
if (fInst->type == meta->functionClass)
|
||||
fWrap = fInst->fWrap;
|
||||
}
|
||||
else {
|
||||
DynamicInstance *dInst = (checked_cast<DynamicInstance *>(obj));
|
||||
if (dInst->type == meta->functionClass)
|
||||
fWrap = dInst->fWrap;
|
||||
}
|
||||
CallableInstance *dInst = (checked_cast<CallableInstance *>(obj));
|
||||
if (dInst->type == meta->functionClass)
|
||||
fWrap = dInst->fWrap;
|
||||
if (fWrap) {
|
||||
// XXX - I made this stuff up - extract the 'prototype' property from
|
||||
// the function being invoked (defaulting to Object.prototype). Then
|
||||
@@ -112,13 +105,10 @@
|
||||
if (JS2VAL_IS_PRIMITIVE(b))
|
||||
meta->reportError(Exception::badValueError, "Can't call on primitive value", errorPos());
|
||||
JS2Object *fObj = JS2VAL_TO_OBJECT(b);
|
||||
if (((fObj->kind == FixedInstanceKind) || (fObj->kind == DynamicInstanceKind))
|
||||
if ((fObj->kind == CallableInstanceKind)
|
||||
&& (meta->objectType(b) == meta->functionClass)) {
|
||||
FunctionWrapper *fWrap;
|
||||
if (fObj->kind == FixedInstanceKind)
|
||||
fWrap = (checked_cast<FixedInstance *>(fObj))->fWrap;
|
||||
else
|
||||
fWrap = (checked_cast<DynamicInstance *>(fObj))->fWrap;
|
||||
fWrap = (checked_cast<CallableInstance *>(fObj))->fWrap;
|
||||
js2val compileThis = fWrap->compileFrame->thisObject;
|
||||
if (JS2VAL_IS_VOID(compileThis))
|
||||
a = JS2VAL_VOID;
|
||||
@@ -148,7 +138,7 @@
|
||||
else
|
||||
if (fObj->kind == MethodClosureKind) { // XXX I made this up (particularly the frame push of the objectType)
|
||||
MethodClosure *mc = checked_cast<MethodClosure *>(fObj);
|
||||
FixedInstance *fInst = mc->method->fInst;
|
||||
CallableInstance *fInst = mc->method->fInst;
|
||||
FunctionWrapper *fWrap = fInst->fWrap;
|
||||
ParameterFrame *runtimeFrame = new ParameterFrame(fWrap->compileFrame);
|
||||
runtimeFrame->instantiate(&meta->env);
|
||||
@@ -261,11 +251,11 @@
|
||||
case GlobalObjectKind:
|
||||
a = STRING_TO_JS2VAL(object_StringAtom);
|
||||
break;
|
||||
case FixedInstanceKind:
|
||||
a = STRING_TO_JS2VAL(checked_cast<FixedInstance *>(obj)->typeofString);
|
||||
case SimpleInstanceKind:
|
||||
a = STRING_TO_JS2VAL(checked_cast<SimpleInstance *>(obj)->typeofString);
|
||||
break;
|
||||
case DynamicInstanceKind:
|
||||
a = STRING_TO_JS2VAL(checked_cast<DynamicInstance *>(obj)->typeofString);
|
||||
case CallableInstanceKind:
|
||||
a = STRING_TO_JS2VAL(checked_cast<CallableInstance *>(obj)->typeofString);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@
|
||||
for (uint16 i = 0; i < argCount; i++) {
|
||||
b = pop();
|
||||
const DynamicPropertyMap::value_type e(*numberToString((argCount - 1) - i), b);
|
||||
aInst->dynamicProperties.insert(e);
|
||||
aInst->dynamicProperties->insert(e);
|
||||
}
|
||||
setLength(meta, aInst, argCount);
|
||||
push(baseVal);
|
||||
|
||||
@@ -784,7 +784,7 @@ void initStringObject(JS2Metadata *meta)
|
||||
|
||||
PrototypeFunction *pf = &prototypeFunctions[0];
|
||||
while (pf->name) {
|
||||
FixedInstance *fInst = new FixedInstance(meta->functionClass);
|
||||
CallableInstance *fInst = new CallableInstance(meta->functionClass);
|
||||
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
|
||||
/*
|
||||
XXX not prototype object function properties, like ECMA3, but members of the String class
|
||||
|
||||
@@ -182,7 +182,7 @@ namespace JavaScript
|
||||
#ifdef __GNUC__ // why doesn't g++ support numeric_limits<T>?
|
||||
static size_type max_size() {return size_type(-1) / sizeof(T);}
|
||||
#else
|
||||
static size_type max_size() {return std::numeric_limits<size_type>::max() / sizeof(T);}
|
||||
static size_type max_size() {return std::numeric_limits<size_type>::v_max() / sizeof(T);}
|
||||
#endif
|
||||
|
||||
template<class U> struct rebind {typedef ArenaAllocator<U> other;};
|
||||
|
||||
@@ -407,7 +407,7 @@ void JS::BigInt::allocate(uint lgGrossSize)
|
||||
FREE_DTOA_LOCK(0);
|
||||
} else {
|
||||
FREE_DTOA_LOCK(0);
|
||||
w = static_cast<uint32 *>(STD::malloc(max(uint32(grossSize * sizeof(uint32)), uint32(sizeof(uint32 *)))));
|
||||
w = static_cast<uint32 *>(STD::malloc(v_max(uint32(grossSize * sizeof(uint32)), uint32(sizeof(uint32 *)))));
|
||||
if (!w) {
|
||||
std::bad_alloc outOfMemory;
|
||||
throw outOfMemory;
|
||||
|
||||
@@ -82,8 +82,8 @@ namespace JavaScript
|
||||
// Mathematics
|
||||
//
|
||||
|
||||
template<class N> inline N min(N v1, N v2) {return v1 <= v2 ? v1 : v2;}
|
||||
template<class N> inline N max(N v1, N v2) {return v1 >= v2 ? v1 : v2;}
|
||||
template<class N> inline N v_min(N v1, N v2) {return v1 <= v2 ? v1 : v2;}
|
||||
template<class N> inline N v_max(N v1, N v2) {return v1 >= v2 ? v1 : v2;}
|
||||
|
||||
uint ceilingLog2(uint32 n);
|
||||
uint floorLog2(uint32 n);
|
||||
|
||||
@@ -64,7 +64,7 @@ LIB32=link.exe -lib
|
||||
# PROP Intermediate_Dir "fdlibm___Win32_Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "_IEEE_LIBM" /D "_LIB" /D "XP_PC" /D "WIN32" /D "_MBCS" /D "DIKDIK" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "_IEEE_LIBM" /D "_LIB" /D "XP_PC" /D "WIN32" /D "_MBCS" /D "DIKDIK" /FR /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
||||
Reference in New Issue
Block a user