Minor e3 fixes. Adding type handling for function parameters & result.

This commit is contained in:
rogerl%netscape.com 2003-05-10 19:30:34 +00:00
Родитель 6d8f204fda
Коммит 31c6b3b53c
6 изменённых файлов: 91 добавлений и 15 удалений

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

@ -263,6 +263,18 @@ void printLocalBindings(LocalBindingMap *lMap, ValueList *frameSlots)
stdOut << " forbidden\n";
}
break;
case Member::GetterMember:
{
Getter *g = checked_cast<Getter *>(m);
stdOut << " get" << ":" << *g->type->name << "\n";
}
break;
case Member::SetterMember:
{
Setter *s = checked_cast<Setter *>(m);
stdOut << " set" << ":" << *s->type->name << "\n";
}
break;
case Member::DynamicVariableMember:
{
DynamicVariable *dv = checked_cast<DynamicVariable *>(m);

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

@ -395,7 +395,7 @@ namespace MetaData {
if ((d == 0.0) || !JSDOUBLE_IS_FINITE(d) )
return 0;
d = fd::fmod(d, two32);
d = (d >= 0) ? d : d + two32;
d = (d >= 0) ? fd::floor(d) : fd::ceil(d) + two32;
if (d >= two31)
return (int32)(d - two32);
else

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

@ -477,6 +477,8 @@ namespace MetaData {
d = stringToDouble(str1, strEnd, numEnd);
if (numEnd == str1)
return nan;
if (skipWhiteSpace(numEnd, strEnd) != strEnd)
return nan;
}
return (neg) ? -d : d;
}

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

@ -110,10 +110,15 @@ namespace MetaData {
pb = fnDef->parameters;
while (pb) {
FrameVariable *v = new FrameVariable(compileFrame->allocateSlot(), FrameVariable::Parameter);
if (pb->type)
ValidateTypeExpression(cxt, env, pb->type);
pb->member = v;
pb->mn = defineLocalMember(env, pb->name, NULL, Attribute::NoOverride, false, ReadWriteAccess, v, pb->pos, true);
pb = pb->next;
}
}
if (fnDef->resultType)
ValidateTypeExpression(cxt, env, fnDef->resultType);
createDynamicProperty(result, engine->length_StringAtom, INT_TO_JS2VAL(pCount), ReadAccess, true, false);
result->fWrap->length = pCount;
compileFrame->isConstructor = isConstructor;
@ -150,7 +155,7 @@ namespace MetaData {
ASSERT(!(unchecked || hoisted));
// XXX shouldn't be using validateStaticFunction
fnInst = validateStaticFunction(cxt, env, fnDef, false, false, false, pos);
Getter *g = new Getter(fnInst);
Getter *g = new Getter(fnInst->fWrap->resultType, fnInst);
defineLocalMember(env, fnDef->name, &a->namespaces, a->overrideMod, a->xplicit, ReadAccess, g, pos, true);
}
break;
@ -161,7 +166,7 @@ namespace MetaData {
ASSERT(!(unchecked || hoisted));
// XXX shouldn't be using validateStaticFunction
fnInst = validateStaticFunction(cxt, env, fnDef, false, false, false, pos);
Setter *s = new Setter(fnInst);
Setter *s = new Setter(fnInst->fWrap->resultType, fnInst);
defineLocalMember(env, fnDef->name, &a->namespaces, a->overrideMod, a->xplicit, WriteAccess, s, pos, true);
}
break;
@ -1297,6 +1302,20 @@ namespace MetaData {
#ifdef DEBUG
bCon->fName = *f->function.name;
#endif
VariableBinding *pb = f->function.parameters;
while (pb) {
FrameVariable *v = checked_cast<FrameVariable *>(pb->member);
if (pb->type)
v->type = EvalTypeExpression(env, CompilePhase, pb->type);
else
v->type = objectClass;
pb = pb->next;
}
if (f->function.resultType)
f->function.fWrap->resultType = EvalTypeExpression(env, CompilePhase, f->function.resultType);
else
f->function.fWrap->resultType = objectClass;
SetupStmt(env, phase, f->function.body);
// XXX need to make sure that all paths lead to an exit of some kind
bCon->emitOp(eReturnVoid, p->pos);
@ -1369,7 +1388,6 @@ namespace MetaData {
}
}
else {
ASSERT(vb->member->memberKind == Member::InstanceVariableMember);
InstanceVariable *v = checked_cast<InstanceVariable *>(vb->member);
JS2Class *t;
if (vb->type)
@ -3960,7 +3978,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
initBooleanObject(this);
/*** ECMA 3 Math Object ***/
SimpleInstance *mathObject = new SimpleInstance(this, objectClass->prototype, objectClass);
MAKEBUILTINCLASS(mathClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["Math"]), JS2VAL_FALSE);
SimpleInstance *mathObject = new 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);
@ -4444,6 +4463,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
GCMARKOBJECT(generalNumberClass);
GCMARKOBJECT(integerClass);
GCMARKOBJECT(numberClass);
GCMARKOBJECT(mathClass);
GCMARKOBJECT(characterClass);
GCMARKOBJECT(stringClass);
GCMARKOBJECT(namespaceClass);
@ -4553,6 +4573,16 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
}
}
}
static js2val class_ProtoGetter(JS2Metadata *meta, const js2val thisValue, js2val /* argv */ [], uint32 /* argc */)
{
ASSERT(JS2VAL_IS_OBJECT(thisValue));
JS2Object *obj = JS2VAL_TO_OBJECT(thisValue);
ASSERT(obj->kind == ClassKind);
JS2Class *c = checked_cast<JS2Class *>(obj);
return OBJECT_TO_JS2VAL(c->super);
}
void JS2Metadata::initBuiltinClass(JS2Class *builtinClass, FunctionData *staticFunctions, NativeCode *construct, NativeCode *call)
{
@ -4567,10 +4597,17 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
Variable *v = new Variable(builtinClass, INT_TO_JS2VAL(1), true);
defineLocalMember(env, engine->length_StringAtom, NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false);
FunctionInstance *callInst = new FunctionInstance(this, functionClass->prototype, functionClass);
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), class_ProtoGetter, env);
callInst->fWrap->length = 0;
Getter *g = new Getter(objectClass, callInst);
defineLocalMember(env, &world.identifiers["__proto__"], NULL, Attribute::NoOverride, false, ReadAccess, g, 0, true);
pf = staticFunctions;
if (pf) {
while (pf->name) {
FunctionInstance *callInst = new FunctionInstance(this, functionClass->prototype, functionClass);
callInst = new FunctionInstance(this, functionClass->prototype, functionClass);
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code, env);
callInst->fWrap->length = pf->length;
v = new Variable(functionClass, OBJECT_TO_JS2VAL(callInst), true);

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

@ -488,11 +488,19 @@ public:
typedef enum { Local, Package, Parameter } FrameVariableKind;
FrameVariable(uint16 frameSlot, FrameVariableKind kind) : LocalMember(Member::FrameVariableMember), frameSlot(frameSlot), kind(kind), sealed(false) { }
FrameVariable(uint16 frameSlot, FrameVariableKind kind)
: LocalMember(Member::FrameVariableMember),
frameSlot(frameSlot),
kind(kind),
type(NULL),
sealed(false)
{ }
uint16 frameSlot;
FrameVariableKind kind; // the kind of frame this variable is in
JS2Class *type;
bool sealed; // true if this variable cannot be deleted using the delete operator
virtual LocalMember *clone() { return new FrameVariable(frameSlot, kind); }
};
@ -509,7 +517,7 @@ public:
class Getter : public LocalMember {
public:
Getter(FunctionInstance *code) : LocalMember(Member::GetterMember), type(NULL), code(code) { }
Getter(JS2Class *type, FunctionInstance *code) : LocalMember(Member::GetterMember), type(type), code(code) { }
JS2Class *type; // The type of the value read from this getter
FunctionInstance *code; // calling this object does the read
@ -519,7 +527,7 @@ public:
class Setter : public LocalMember {
public:
Setter(FunctionInstance *code) : LocalMember(Member::SetterMember), type(NULL), code(code) { }
Setter(JS2Class *type, FunctionInstance *code) : LocalMember(Member::SetterMember), type(type), code(code) { }
JS2Class *type; // The type of the value written into the setter
FunctionInstance *code; // calling this object does the write
@ -836,9 +844,24 @@ class ParameterFrame;
class FunctionWrapper {
public:
FunctionWrapper(bool unchecked, ParameterFrame *compileFrame, Environment *env)
: bCon(new BytecodeContainer()), code(NULL), unchecked(unchecked), compileFrame(compileFrame), env(new Environment(env)), length(0) { }
: bCon(new BytecodeContainer()),
code(NULL),
unchecked(unchecked),
compileFrame(compileFrame),
env(new Environment(env)),
length(0),
resultType(NULL)
{ }
FunctionWrapper(bool unchecked, ParameterFrame *compileFrame, NativeCode *code, Environment *env)
: bCon(NULL), code(code), unchecked(unchecked), compileFrame(compileFrame), env(new Environment(env)), length(0) { }
: bCon(NULL),
code(code),
unchecked(unchecked),
compileFrame(compileFrame),
env(new Environment(env)),
length(0),
resultType(NULL)
{ }
virtual ~FunctionWrapper() { if (bCon) delete bCon; }
@ -848,6 +871,7 @@ public:
ParameterFrame *compileFrame;
Environment *env;
uint32 length;
JS2Class *resultType;
};
@ -1491,6 +1515,7 @@ public:
JS2Class *booleanClass;
JS2Class *generalNumberClass;
JS2Class *numberClass;
JS2Class *mathClass;
JS2Class *integerClass;
JS2Class *characterClass;
JS2Class *stringClass;

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

@ -756,7 +756,7 @@ static js2val String_substring(JS2Metadata *meta, const js2val thisValue, js2val
if (argc > 1) {
float64 farg1 = meta->toFloat64(argv[1]);
if (JSDOUBLE_IS_NaN(farg1) || (farg1 < 0))
end = sourceLength;
end = 0;
else {
if (!JSDOUBLE_IS_FINITE(farg1))
end = sourceLength;
@ -788,14 +788,14 @@ void initStringObject(JS2Metadata *meta)
{ "charAt", 1, String_charAt },
{ "charCodeAt", 1, String_charCodeAt },
{ "concat", 1, String_concat },
{ "indexOf", 2, String_indexOf }, // XXX ECMA spec says 1, but tests want 2 XXX
{ "lastIndexOf", 2, String_lastIndexOf }, // XXX ECMA spec says 1, but tests want 2 XXX
{ "indexOf", 1, String_indexOf },
{ "lastIndexOf", 1, String_lastIndexOf },
{ "localeCompare", 1, String_localeCompare },
{ "match", 1, String_match },
{ "replace", 2, String_replace },
{ "search", 1, String_search },
{ "slice", 2, String_slice },
{ "split", 1, String_split }, // XXX ECMA spec says 2, but tests want 1 XXX
{ "split", 2, String_split },
{ "substring", 2, String_substring },
{ "toSource", 0, String_toString },
{ "toLocaleUpperCase", 0, String_toUpperCase }, // (sic)