зеркало из https://github.com/mozilla/gecko-dev.git
More ECMA 3 mucking about to support constructors etc.
This commit is contained in:
Родитель
20e63b772d
Коммит
c30779b359
|
@ -41,7 +41,7 @@
|
|||
NEW_ARRAY, /* dest */
|
||||
NEW_CLASS, /* dest, class */
|
||||
NEW_FUNCTION, /* dest, ICodeModule */
|
||||
NEW_OBJECT, /* dest */
|
||||
NEW_OBJECT, /* dest, constructor */
|
||||
NOP, /* do nothing and like it */
|
||||
NOT, /* dest, source */
|
||||
OR, /* dest, source1, source2 */
|
||||
|
@ -582,18 +582,18 @@
|
|||
}
|
||||
};
|
||||
|
||||
class NewObject : public Instruction_1<TypedRegister> {
|
||||
class NewObject : public Instruction_2<TypedRegister, TypedRegister> {
|
||||
public:
|
||||
/* dest */
|
||||
NewObject (TypedRegister aOp1) :
|
||||
Instruction_1<TypedRegister>
|
||||
(NEW_OBJECT, aOp1) {};
|
||||
/* dest, constructor */
|
||||
NewObject (TypedRegister aOp1, TypedRegister aOp2) :
|
||||
Instruction_2<TypedRegister, TypedRegister>
|
||||
(NEW_OBJECT, aOp1, aOp2) {};
|
||||
virtual Formatter& print(Formatter& f) {
|
||||
f << opcodeNames[NEW_OBJECT] << "\t" << mOp1;
|
||||
f << opcodeNames[NEW_OBJECT] << "\t" << mOp1 << ", " << mOp2;
|
||||
return f;
|
||||
}
|
||||
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
||||
f << mOp1.first;
|
||||
f << mOp1.first << ", " << mOp2.first;
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -211,10 +211,10 @@ TypedRegister ICodeGenerator::loadBoolean(bool value)
|
|||
return dest;
|
||||
}
|
||||
|
||||
TypedRegister ICodeGenerator::newObject(RegisterList * /*args*/)
|
||||
TypedRegister ICodeGenerator::newObject(TypedRegister constructor)
|
||||
{
|
||||
TypedRegister dest(getTempRegister(), &Any_Type);
|
||||
NewObject *instr = new NewObject(dest);
|
||||
NewObject *instr = new NewObject(dest, constructor);
|
||||
iCode->push_back(instr);
|
||||
return dest;
|
||||
}
|
||||
|
@ -1103,11 +1103,19 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
|||
call(getStatic(clazz, className), ret, &args);
|
||||
}
|
||||
else
|
||||
NOT_REACHED("New <name>, where <name> is not a known class"); // XXX Runtime error.
|
||||
NOT_REACHED("new <name>, where <name> is not a new-able type (whatever that means)"); // XXX Runtime error.
|
||||
}
|
||||
else
|
||||
if (value.isFunction()) {
|
||||
TypedRegister f = loadName(className, value.type);
|
||||
ret = newObject(f);
|
||||
call(f, ret, &args);
|
||||
}
|
||||
else
|
||||
NOT_REACHED("new <name>, where <name> is not a function"); // XXX Runtime error.
|
||||
}
|
||||
else
|
||||
ret = newObject(&args); // XXX more ?
|
||||
ret = newObject(TypedRegister(NotARegister, &Any_Type)); // XXX more ?
|
||||
}
|
||||
break;
|
||||
case ExprNode::Delete:
|
||||
|
@ -1449,7 +1457,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
|||
|
||||
case ExprNode::objectLiteral:
|
||||
{
|
||||
ret = newObject(NULL);
|
||||
ret = newObject(TypedRegister(NotARegister, &Any_Type));
|
||||
PairListExprNode *plen = static_cast<PairListExprNode *>(p);
|
||||
ExprPairList *e = plen->pairs;
|
||||
while (e) {
|
||||
|
|
|
@ -254,7 +254,7 @@ namespace ICG {
|
|||
TypedRegister loadString(const String &value);
|
||||
TypedRegister loadString(const StringAtom &name);
|
||||
|
||||
TypedRegister newObject(RegisterList *args);
|
||||
TypedRegister newObject(TypedRegister constructor);
|
||||
TypedRegister newArray();
|
||||
TypedRegister newFunction(ICodeModule *icm);
|
||||
TypedRegister newClass(JSClass *clazz);
|
||||
|
|
|
@ -500,13 +500,17 @@ void Context::initContext()
|
|||
// set up the correct [[Class]] for the global object (matching SpiderMonkey)
|
||||
mGlobal->setClass(new JSString("global"));
|
||||
|
||||
|
||||
// add (XXX some) of the global object properties
|
||||
mGlobal->setProperty(widenCString("NaN"), kNaNValue);
|
||||
mGlobal->setProperty(widenCString("undefined"), kUndefinedValue);
|
||||
|
||||
|
||||
// 'Object', 'Date', 'RegExp', 'Array' etc are all (constructor) properties of the global object
|
||||
|
||||
mGlobal->setProperty(widenCString("Math"), JSValue(new JSMath()));
|
||||
JSObject::initObjectObject(mGlobal);
|
||||
|
||||
// the 'Math' object just has some useful properties
|
||||
JSMath::initMathObject(mGlobal);
|
||||
|
||||
|
||||
// This initializes the state of the binary operator overload mechanism.
|
||||
|
@ -712,7 +716,10 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
|||
{
|
||||
NewObject* no = static_cast<NewObject*>(instruction);
|
||||
JSObject *obj = new JSObject();
|
||||
(*registers)[dst(no).first] = new JSObject();
|
||||
if (src1(no).first != NotARegister)
|
||||
(*registers)[dst(no).first] = new JSObject((*registers)[src1(no).first]);
|
||||
else
|
||||
(*registers)[dst(no).first] = new JSObject();
|
||||
}
|
||||
break;
|
||||
case NEW_CLASS:
|
||||
|
|
|
@ -235,6 +235,7 @@ static void readEvalPrint(FILE *in, World &world)
|
|||
// list of zero or more statements
|
||||
ICodeModule* icm = cx.genCode(parsedStatements, ConsoleName);
|
||||
if (icm) {
|
||||
stdOut << *icm;
|
||||
JSValue result = cx.interpret(icm, JSValues());
|
||||
stdOut << "result = " << result << "\n";
|
||||
delete icm;
|
||||
|
|
|
@ -186,18 +186,23 @@ struct MathConstantEntry {
|
|||
{ "SQRT1_2", M_SQRT1_2 }
|
||||
};
|
||||
|
||||
JSMath::JSMath()
|
||||
{
|
||||
setClass(new JSString("Math"));
|
||||
// There is no constructor for Math, we simply initialize
|
||||
// the properties of the Math object
|
||||
void JSMath::initMathObject(JSScope *g)
|
||||
{
|
||||
int i;
|
||||
JSMath *m = new JSMath();
|
||||
m->setClass(new JSString("Math"));
|
||||
|
||||
for (int i = 0; i < sizeof(MathFunctions) / sizeof(MathFunctionEntry); i++)
|
||||
setProperty(widenCString(MathFunctions[i].name), JSValue(new JSNativeFunction(MathFunctions[i].fn) ) );
|
||||
for (i = 0; i < sizeof(MathFunctions) / sizeof(MathFunctionEntry); i++)
|
||||
m->setProperty(widenCString(MathFunctions[i].name), JSValue(new JSNativeFunction(MathFunctions[i].fn) ) );
|
||||
|
||||
for (int i = 0; i < sizeof(MathConstants) / sizeof(MathConstantEntry); i++)
|
||||
setProperty(widenCString(MathConstants[i].name), JSValue(MathConstants[i].value) );
|
||||
for (i = 0; i < sizeof(MathConstants) / sizeof(MathConstantEntry); i++)
|
||||
m->setProperty(widenCString(MathConstants[i].name), JSValue(MathConstants[i].value) );
|
||||
|
||||
g->setProperty(widenCString("Math"), JSValue(m));
|
||||
|
||||
}
|
||||
|
||||
|
||||
} /* JSMathClass */
|
||||
} /* JavaScript */
|
||||
|
|
|
@ -41,11 +41,13 @@ namespace JSMathClass {
|
|||
|
||||
using JSTypes::JSObject;
|
||||
using JSTypes::JSString;
|
||||
using JSTypes::JSScope;
|
||||
|
||||
class JSMath : public JSObject {
|
||||
private:
|
||||
JSMath() { }
|
||||
public:
|
||||
JSMath();
|
||||
|
||||
static void initMathObject(JSScope *g);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -55,17 +55,49 @@ JSValue object_toString(Context *cx, const JSValues& argv)
|
|||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
JSValue objectConstructor(Context *cx, const JSValues& argv)
|
||||
{
|
||||
ASSERT(argv.size() > 0);
|
||||
JSValue theThis = argv[0];
|
||||
|
||||
// the prototype and class have been established already
|
||||
|
||||
return theThis;
|
||||
}
|
||||
|
||||
struct ObjectFunctionEntry {
|
||||
char *name;
|
||||
JSNativeFunction::JSCode fn;
|
||||
} ObjectFunctions[] = {
|
||||
{ "toString", object_toString },
|
||||
};
|
||||
|
||||
|
||||
JSObject *JSObject::objectPrototypeObject = JSObject::initJSObject();
|
||||
JSString *JSObject::ObjectString = new JSString("Object");
|
||||
String JSObject::ObjectString = widenCString("Object");
|
||||
|
||||
// This establishes the ur-prototype, there's a timing issue
|
||||
// here - the JSObject static initializers have to run before
|
||||
// any other JSObject objects are constructed.
|
||||
JSObject *JSObject::initJSObject()
|
||||
{
|
||||
JSObject *result = new JSObject();
|
||||
result->setProperty(widenCString("toString"), JSValue(new JSNativeFunction(object_toString) ) );
|
||||
|
||||
for (int i = 0; i < sizeof(ObjectFunctions) / sizeof(ObjectFunctionEntry); i++)
|
||||
result->setProperty(widenCString(ObjectFunctions[i].name), JSValue(new JSNativeFunction(ObjectFunctions[i].fn) ) );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Install the 'Object' constructor into the scope, mostly irrelevant since making
|
||||
// a new JSObject does all the work of setting the prototype and [[class]] values.
|
||||
void JSObject::initObjectObject(JSScope *g)
|
||||
{
|
||||
JSObject* o = new JSObject();
|
||||
|
||||
g->setProperty(ObjectString, JSValue(new JSNativeFunction(objectConstructor)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ namespace JSTypes {
|
|||
class JSObject;
|
||||
class JSArray;
|
||||
class JSFunction;
|
||||
class JSScope;
|
||||
class JSString;
|
||||
class JSType;
|
||||
class Context;
|
||||
|
@ -224,12 +225,17 @@ namespace JSTypes {
|
|||
JSType* mType;
|
||||
JSString* mClass; // this is the internal [[Class]] property
|
||||
|
||||
public:
|
||||
JSObject() : mPrototype(objectPrototypeObject), mType(&Any_Type), mClass(ObjectString) {}
|
||||
|
||||
static JSObject *objectPrototypeObject;
|
||||
static JSObject *initJSObject();
|
||||
static JSString *ObjectString;
|
||||
static String ObjectString;
|
||||
static JSObject *objectPrototypeObject;
|
||||
|
||||
void init(JSObject* prototype);
|
||||
|
||||
public:
|
||||
JSObject() { init(objectPrototypeObject); }
|
||||
JSObject(JSValue &constructor) { init(constructor.object->getProperty(widenCString("prototype")).object); }
|
||||
|
||||
static void initObjectObject(JSScope *g);
|
||||
|
||||
bool hasProperty(const String& name)
|
||||
{
|
||||
|
@ -551,6 +557,9 @@ namespace JSTypes {
|
|||
};
|
||||
|
||||
|
||||
inline void JSObject::init(JSObject* prototype) { mPrototype = prototype; mType = &Any_Type; mClass = new JSString(ObjectString); }
|
||||
|
||||
|
||||
} /* namespace JSTypes */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
|
|
|
@ -128,9 +128,9 @@ $ops{"SAVE_NAME"} =
|
|||
};
|
||||
$ops{"NEW_OBJECT"} =
|
||||
{
|
||||
super => "Instruction_1",
|
||||
rem => "dest",
|
||||
params => [ ("TypedRegister") ]
|
||||
super => "Instruction_2",
|
||||
rem => "dest, constructor",
|
||||
params => [ ("TypedRegister", "TypedRegister") ]
|
||||
};
|
||||
$ops{"NEW_CLASS"} =
|
||||
{
|
||||
|
|
|
@ -195,6 +195,10 @@ SOURCE=..\jsclasses.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jsmath.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jstypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
NEW_ARRAY, /* dest */
|
||||
NEW_CLASS, /* dest, class */
|
||||
NEW_FUNCTION, /* dest, ICodeModule */
|
||||
NEW_OBJECT, /* dest */
|
||||
NEW_OBJECT, /* dest, constructor */
|
||||
NOP, /* do nothing and like it */
|
||||
NOT, /* dest, source */
|
||||
OR, /* dest, source1, source2 */
|
||||
|
@ -582,18 +582,18 @@
|
|||
}
|
||||
};
|
||||
|
||||
class NewObject : public Instruction_1<TypedRegister> {
|
||||
class NewObject : public Instruction_2<TypedRegister, TypedRegister> {
|
||||
public:
|
||||
/* dest */
|
||||
NewObject (TypedRegister aOp1) :
|
||||
Instruction_1<TypedRegister>
|
||||
(NEW_OBJECT, aOp1) {};
|
||||
/* dest, constructor */
|
||||
NewObject (TypedRegister aOp1, TypedRegister aOp2) :
|
||||
Instruction_2<TypedRegister, TypedRegister>
|
||||
(NEW_OBJECT, aOp1, aOp2) {};
|
||||
virtual Formatter& print(Formatter& f) {
|
||||
f << opcodeNames[NEW_OBJECT] << "\t" << mOp1;
|
||||
f << opcodeNames[NEW_OBJECT] << "\t" << mOp1 << ", " << mOp2;
|
||||
return f;
|
||||
}
|
||||
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
||||
f << mOp1.first;
|
||||
f << mOp1.first << ", " << mOp2.first;
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -211,10 +211,10 @@ TypedRegister ICodeGenerator::loadBoolean(bool value)
|
|||
return dest;
|
||||
}
|
||||
|
||||
TypedRegister ICodeGenerator::newObject(RegisterList * /*args*/)
|
||||
TypedRegister ICodeGenerator::newObject(TypedRegister constructor)
|
||||
{
|
||||
TypedRegister dest(getTempRegister(), &Any_Type);
|
||||
NewObject *instr = new NewObject(dest);
|
||||
NewObject *instr = new NewObject(dest, constructor);
|
||||
iCode->push_back(instr);
|
||||
return dest;
|
||||
}
|
||||
|
@ -1103,11 +1103,19 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
|||
call(getStatic(clazz, className), ret, &args);
|
||||
}
|
||||
else
|
||||
NOT_REACHED("New <name>, where <name> is not a known class"); // XXX Runtime error.
|
||||
NOT_REACHED("new <name>, where <name> is not a new-able type (whatever that means)"); // XXX Runtime error.
|
||||
}
|
||||
else
|
||||
if (value.isFunction()) {
|
||||
TypedRegister f = loadName(className, value.type);
|
||||
ret = newObject(f);
|
||||
call(f, ret, &args);
|
||||
}
|
||||
else
|
||||
NOT_REACHED("new <name>, where <name> is not a function"); // XXX Runtime error.
|
||||
}
|
||||
else
|
||||
ret = newObject(&args); // XXX more ?
|
||||
ret = newObject(TypedRegister(NotARegister, &Any_Type)); // XXX more ?
|
||||
}
|
||||
break;
|
||||
case ExprNode::Delete:
|
||||
|
@ -1449,7 +1457,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
|||
|
||||
case ExprNode::objectLiteral:
|
||||
{
|
||||
ret = newObject(NULL);
|
||||
ret = newObject(TypedRegister(NotARegister, &Any_Type));
|
||||
PairListExprNode *plen = static_cast<PairListExprNode *>(p);
|
||||
ExprPairList *e = plen->pairs;
|
||||
while (e) {
|
||||
|
|
|
@ -254,7 +254,7 @@ namespace ICG {
|
|||
TypedRegister loadString(const String &value);
|
||||
TypedRegister loadString(const StringAtom &name);
|
||||
|
||||
TypedRegister newObject(RegisterList *args);
|
||||
TypedRegister newObject(TypedRegister constructor);
|
||||
TypedRegister newArray();
|
||||
TypedRegister newFunction(ICodeModule *icm);
|
||||
TypedRegister newClass(JSClass *clazz);
|
||||
|
|
|
@ -500,13 +500,17 @@ void Context::initContext()
|
|||
// set up the correct [[Class]] for the global object (matching SpiderMonkey)
|
||||
mGlobal->setClass(new JSString("global"));
|
||||
|
||||
|
||||
// add (XXX some) of the global object properties
|
||||
mGlobal->setProperty(widenCString("NaN"), kNaNValue);
|
||||
mGlobal->setProperty(widenCString("undefined"), kUndefinedValue);
|
||||
|
||||
|
||||
// 'Object', 'Date', 'RegExp', 'Array' etc are all (constructor) properties of the global object
|
||||
|
||||
mGlobal->setProperty(widenCString("Math"), JSValue(new JSMath()));
|
||||
JSObject::initObjectObject(mGlobal);
|
||||
|
||||
// the 'Math' object just has some useful properties
|
||||
JSMath::initMathObject(mGlobal);
|
||||
|
||||
|
||||
// This initializes the state of the binary operator overload mechanism.
|
||||
|
@ -712,7 +716,10 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
|||
{
|
||||
NewObject* no = static_cast<NewObject*>(instruction);
|
||||
JSObject *obj = new JSObject();
|
||||
(*registers)[dst(no).first] = new JSObject();
|
||||
if (src1(no).first != NotARegister)
|
||||
(*registers)[dst(no).first] = new JSObject((*registers)[src1(no).first]);
|
||||
else
|
||||
(*registers)[dst(no).first] = new JSObject();
|
||||
}
|
||||
break;
|
||||
case NEW_CLASS:
|
||||
|
|
|
@ -186,18 +186,23 @@ struct MathConstantEntry {
|
|||
{ "SQRT1_2", M_SQRT1_2 }
|
||||
};
|
||||
|
||||
JSMath::JSMath()
|
||||
{
|
||||
setClass(new JSString("Math"));
|
||||
// There is no constructor for Math, we simply initialize
|
||||
// the properties of the Math object
|
||||
void JSMath::initMathObject(JSScope *g)
|
||||
{
|
||||
int i;
|
||||
JSMath *m = new JSMath();
|
||||
m->setClass(new JSString("Math"));
|
||||
|
||||
for (int i = 0; i < sizeof(MathFunctions) / sizeof(MathFunctionEntry); i++)
|
||||
setProperty(widenCString(MathFunctions[i].name), JSValue(new JSNativeFunction(MathFunctions[i].fn) ) );
|
||||
for (i = 0; i < sizeof(MathFunctions) / sizeof(MathFunctionEntry); i++)
|
||||
m->setProperty(widenCString(MathFunctions[i].name), JSValue(new JSNativeFunction(MathFunctions[i].fn) ) );
|
||||
|
||||
for (int i = 0; i < sizeof(MathConstants) / sizeof(MathConstantEntry); i++)
|
||||
setProperty(widenCString(MathConstants[i].name), JSValue(MathConstants[i].value) );
|
||||
for (i = 0; i < sizeof(MathConstants) / sizeof(MathConstantEntry); i++)
|
||||
m->setProperty(widenCString(MathConstants[i].name), JSValue(MathConstants[i].value) );
|
||||
|
||||
g->setProperty(widenCString("Math"), JSValue(m));
|
||||
|
||||
}
|
||||
|
||||
|
||||
} /* JSMathClass */
|
||||
} /* JavaScript */
|
||||
|
|
|
@ -41,11 +41,13 @@ namespace JSMathClass {
|
|||
|
||||
using JSTypes::JSObject;
|
||||
using JSTypes::JSString;
|
||||
using JSTypes::JSScope;
|
||||
|
||||
class JSMath : public JSObject {
|
||||
private:
|
||||
JSMath() { }
|
||||
public:
|
||||
JSMath();
|
||||
|
||||
static void initMathObject(JSScope *g);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -55,17 +55,49 @@ JSValue object_toString(Context *cx, const JSValues& argv)
|
|||
return kUndefinedValue;
|
||||
}
|
||||
|
||||
JSValue objectConstructor(Context *cx, const JSValues& argv)
|
||||
{
|
||||
ASSERT(argv.size() > 0);
|
||||
JSValue theThis = argv[0];
|
||||
|
||||
// the prototype and class have been established already
|
||||
|
||||
return theThis;
|
||||
}
|
||||
|
||||
struct ObjectFunctionEntry {
|
||||
char *name;
|
||||
JSNativeFunction::JSCode fn;
|
||||
} ObjectFunctions[] = {
|
||||
{ "toString", object_toString },
|
||||
};
|
||||
|
||||
|
||||
JSObject *JSObject::objectPrototypeObject = JSObject::initJSObject();
|
||||
JSString *JSObject::ObjectString = new JSString("Object");
|
||||
String JSObject::ObjectString = widenCString("Object");
|
||||
|
||||
// This establishes the ur-prototype, there's a timing issue
|
||||
// here - the JSObject static initializers have to run before
|
||||
// any other JSObject objects are constructed.
|
||||
JSObject *JSObject::initJSObject()
|
||||
{
|
||||
JSObject *result = new JSObject();
|
||||
result->setProperty(widenCString("toString"), JSValue(new JSNativeFunction(object_toString) ) );
|
||||
|
||||
for (int i = 0; i < sizeof(ObjectFunctions) / sizeof(ObjectFunctionEntry); i++)
|
||||
result->setProperty(widenCString(ObjectFunctions[i].name), JSValue(new JSNativeFunction(ObjectFunctions[i].fn) ) );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Install the 'Object' constructor into the scope, mostly irrelevant since making
|
||||
// a new JSObject does all the work of setting the prototype and [[class]] values.
|
||||
void JSObject::initObjectObject(JSScope *g)
|
||||
{
|
||||
JSObject* o = new JSObject();
|
||||
|
||||
g->setProperty(ObjectString, JSValue(new JSNativeFunction(objectConstructor)));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ namespace JSTypes {
|
|||
class JSObject;
|
||||
class JSArray;
|
||||
class JSFunction;
|
||||
class JSScope;
|
||||
class JSString;
|
||||
class JSType;
|
||||
class Context;
|
||||
|
@ -224,12 +225,17 @@ namespace JSTypes {
|
|||
JSType* mType;
|
||||
JSString* mClass; // this is the internal [[Class]] property
|
||||
|
||||
public:
|
||||
JSObject() : mPrototype(objectPrototypeObject), mType(&Any_Type), mClass(ObjectString) {}
|
||||
|
||||
static JSObject *objectPrototypeObject;
|
||||
static JSObject *initJSObject();
|
||||
static JSString *ObjectString;
|
||||
static String ObjectString;
|
||||
static JSObject *objectPrototypeObject;
|
||||
|
||||
void init(JSObject* prototype);
|
||||
|
||||
public:
|
||||
JSObject() { init(objectPrototypeObject); }
|
||||
JSObject(JSValue &constructor) { init(constructor.object->getProperty(widenCString("prototype")).object); }
|
||||
|
||||
static void initObjectObject(JSScope *g);
|
||||
|
||||
bool hasProperty(const String& name)
|
||||
{
|
||||
|
@ -551,6 +557,9 @@ namespace JSTypes {
|
|||
};
|
||||
|
||||
|
||||
inline void JSObject::init(JSObject* prototype) { mPrototype = prototype; mType = &Any_Type; mClass = new JSString(ObjectString); }
|
||||
|
||||
|
||||
} /* namespace JSTypes */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
|
|
|
@ -195,6 +195,10 @@ SOURCE=..\jsclasses.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jsmath.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\jstypes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -235,6 +235,7 @@ static void readEvalPrint(FILE *in, World &world)
|
|||
// list of zero or more statements
|
||||
ICodeModule* icm = cx.genCode(parsedStatements, ConsoleName);
|
||||
if (icm) {
|
||||
stdOut << *icm;
|
||||
JSValue result = cx.interpret(icm, JSValues());
|
||||
stdOut << "result = " << result << "\n";
|
||||
delete icm;
|
||||
|
|
|
@ -128,9 +128,9 @@ $ops{"SAVE_NAME"} =
|
|||
};
|
||||
$ops{"NEW_OBJECT"} =
|
||||
{
|
||||
super => "Instruction_1",
|
||||
rem => "dest",
|
||||
params => [ ("TypedRegister") ]
|
||||
super => "Instruction_2",
|
||||
rem => "dest, constructor",
|
||||
params => [ ("TypedRegister", "TypedRegister") ]
|
||||
};
|
||||
$ops{"NEW_CLASS"} =
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче